Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspingel2008-05-02 06:47:32 +0000
committerspingel2008-05-02 06:47:32 +0000
commit7f86af1782ec463946d18ec52bbdc8a79f72af61 (patch)
treedb1a8a480829a1e1a7173f9357c607c0d555c287
parent5ae2b037869f2e1aee6691084a6baec0baf76ad0 (diff)
downloadorg.eclipse.mylyn.tasks-7f86af1782ec463946d18ec52bbdc8a79f72af61.tar.gz
org.eclipse.mylyn.tasks-7f86af1782ec463946d18ec52bbdc8a79f72af61.tar.xz
org.eclipse.mylyn.tasks-7f86af1782ec463946d18ec52bbdc8a79f72af61.zip
NEW - bug 211641: [api] supporting attaching of files for remote tasks
https://bugs.eclipse.org/bugs/show_bug.cgi?id=211641
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java11
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/FileTaskAttachmentSource.java89
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TextTaskAttachmentSource.java56
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskAttachmentJob.java102
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java7
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachment.java2
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachmentModel.java44
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJob.java19
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJobListener.java4
-rw-r--r--org.eclipse.mylyn.tasks.ui/plugin.xml21
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/AttachmentUtil.java52
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/RepositoryAwareStatusHandler.java68
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/SubmitTaskAttachmentJob.java109
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TaskJobFactory.java26
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInBrowserHandler.java4
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInDefaultEditorHandler.java73
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskAttachmentEditorInput.java161
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorAttachmentPart.java128
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java67
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage.java7
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage2.java13
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/NewAttachmentWizardDialog.java1
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/PreviewAttachmentPage2.java50
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentPage.java304
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentWizard.java242
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java4
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java4
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/wizards/TaskAttachmentPage.java (renamed from org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentPage2.java)124
28 files changed, 1076 insertions, 716 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java
index e5a472de2..cb69d1d05 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/ITaskJobFactory.java
@@ -14,6 +14,7 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.sync.SubmitJob;
@@ -33,10 +34,14 @@ public interface ITaskJobFactory {
public abstract SynchronizationJob createSynchronizeRepositoriesJob(Set<TaskRepository> repositories);
- public abstract SubmitJob createSubmitJob(AbstractRepositoryConnector connector, TaskRepository taskRepository,
+ public abstract SubmitJob createSubmitTaskJob(AbstractRepositoryConnector connector, TaskRepository taskRepository,
AbstractTask task, TaskData taskData, Set<TaskAttribute> changedAttributes);
- public abstract TaskJob createUpdateRepositoryConfigurationJob(final AbstractRepositoryConnector connector,
- final TaskRepository taskRepository);
+ public abstract TaskJob createUpdateRepositoryConfigurationJob(AbstractRepositoryConnector connector,
+ TaskRepository taskRepository);
+
+ public abstract SubmitJob createSubmitTaskAttachmentJob(AbstractRepositoryConnector connector,
+ TaskRepository taskRepository, AbstractTask task, AbstractTaskAttachmentSource source, String comment,
+ TaskAttribute attachmentAttribute);
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/FileTaskAttachmentSource.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/FileTaskAttachmentSource.java
new file mode 100644
index 000000000..a6c9dab1b
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/FileTaskAttachmentSource.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.data;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
+
+/**
+ * @author Steffen Pingel
+ */
+public class FileTaskAttachmentSource extends AbstractTaskAttachmentSource {
+
+ private static final String CONTENT_TYPE_BINARY = "application/octet-stream";
+
+ private String contentType = CONTENT_TYPE_BINARY;
+
+ private String description;
+
+ private final File file;
+
+ private String name;
+
+ public FileTaskAttachmentSource(File file) {
+ this.file = file;
+ this.name = file.getName();
+ }
+
+ @Override
+ public InputStream createInputStream(IProgressMonitor monitor) throws CoreException {
+ try {
+ return new FileInputStream(file);
+ } catch (FileNotFoundException e) {
+ throw new CoreException(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, e.getMessage(), e));
+ }
+ }
+
+ @Override
+ public String getContentType() {
+ return contentType;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public long getLength() {
+ return file.length();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean isLocal() {
+ return true;
+ }
+
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TextTaskAttachmentSource.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TextTaskAttachmentSource.java
new file mode 100644
index 000000000..d6ced41e4
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TextTaskAttachmentSource.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.data;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
+
+public class TextTaskAttachmentSource extends AbstractTaskAttachmentSource {
+
+ private final String contents;
+
+ public TextTaskAttachmentSource(String contents) {
+ this.contents = contents;
+ }
+
+ @Override
+ public InputStream createInputStream(IProgressMonitor monitor) throws CoreException {
+ return new ByteArrayInputStream(contents.getBytes());
+ }
+
+ @Override
+ public String getContentType() {
+ return "text/plain";
+ }
+
+ @Override
+ public String getDescription() {
+ return "";
+ }
+
+ @Override
+ public long getLength() {
+ return contents.getBytes().length;
+ }
+
+ @Override
+ public String getName() {
+ return "clipboard.txt";
+ }
+
+ @Override
+ public boolean isLocal() {
+ return true;
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskAttachmentJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskAttachmentJob.java
new file mode 100644
index 000000000..a1b695ebc
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskAttachmentJob.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.core.sync;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.net.Policy;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
+import org.eclipse.mylyn.tasks.core.AbstractTask;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
+import org.eclipse.mylyn.tasks.core.data.ITaskDataManager;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.sync.SubmitJob;
+
+/**
+ * @author Steffen Pingel
+ */
+public class SubmitTaskAttachmentJob extends SubmitJob {
+
+ private final TaskAttribute attachmentAttribute;
+
+ private final String comment;
+
+ private final AbstractRepositoryConnector connector;
+
+ private IStatus error;
+
+ private final AbstractTaskAttachmentSource source;
+
+ private final AbstractTask task;
+
+ private final TaskRepository taskRepository;
+
+ private final ITaskDataManager taskDataManager;
+
+ public SubmitTaskAttachmentJob(ITaskDataManager taskDataManager, AbstractRepositoryConnector connector,
+ TaskRepository taskRepository, AbstractTask task, AbstractTaskAttachmentSource source, String comment,
+ TaskAttribute attachmentAttribute) {
+ super("Submitting Attachment");
+ this.taskDataManager = taskDataManager;
+ this.connector = connector;
+ this.taskRepository = taskRepository;
+ this.task = task;
+ this.source = source;
+ this.comment = comment;
+ this.attachmentAttribute = attachmentAttribute;
+ }
+
+ @Override
+ public IStatus getError() {
+ return error;
+ }
+
+ @Override
+ public AbstractTask getTask() {
+ return task;
+ }
+
+ @Override
+ public IStatus run(IProgressMonitor monitor) {
+ final AbstractTaskAttachmentHandler attachmentHandler = connector.getTaskAttachmentHandler();
+ if (attachmentHandler == null) {
+ error = new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
+ "The task repository does not support attachments.");
+ return Status.OK_STATUS;
+ }
+ try {
+ monitor.beginTask("Submitting attachment", 2 * (1 + getSubmitJobListeners().length) * 100);
+ monitor.subTask("Sending data");
+ attachmentHandler.postContent(taskRepository, task, source, comment, attachmentAttribute,
+ Policy.subMonitorFor(monitor, 100));
+ fireTaskSubmitted(monitor);
+ monitor.subTask("Updating task");
+ TaskData taskData = connector.getTaskData2(taskRepository, task.getTaskId(), Policy.subMonitorFor(monitor,
+ 100));
+ taskDataManager.putUpdatedTaskData(task, taskData, true);
+ fireTaskSynchronized(monitor);
+ } catch (CoreException e) {
+ error = e.getStatus();
+ } catch (OperationCanceledException e) {
+ return Status.CANCEL_STATUS;
+ } finally {
+ monitor.done();
+ }
+ fireDone();
+ return Status.OK_STATUS;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java
index 33f0384a3..54b6dbe8b 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/sync/SubmitTaskJob.java
@@ -32,8 +32,6 @@ import org.eclipse.mylyn.tasks.core.sync.SubmitJob;
*/
public class SubmitTaskJob extends SubmitJob {
- private static final String LABEL_JOB_SUBMIT = "Submitting to repository";
-
private final TaskRepository taskRepository;
private final TaskData taskData;
@@ -52,7 +50,7 @@ public class SubmitTaskJob extends SubmitJob {
public SubmitTaskJob(ITaskDataManager taskDataManager, AbstractRepositoryConnector connector,
TaskRepository taskRepository, AbstractTask task, TaskData taskData, Set<TaskAttribute> changedAttributes) {
- super(LABEL_JOB_SUBMIT);
+ super("Submitting Task");
this.taskDataManager = taskDataManager;
this.connector = connector;
this.taskRepository = taskRepository;
@@ -76,7 +74,7 @@ public class SubmitTaskJob extends SubmitJob {
RepositoryStatus.ERROR_INTERNAL,
"Task could not be created. No additional information was provided by the connector."));
}
- fireTaskDataPosted(monitor);
+ fireTaskSubmitted(monitor);
// update task in task list
String taskId = response.getTaskId();
@@ -111,6 +109,7 @@ public class SubmitTaskJob extends SubmitJob {
return errorStatus;
}
+ @Override
public AbstractTask getTask() {
return task;
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachment.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachment.java
index f44d377e1..781941c49 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachment.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachment.java
@@ -151,7 +151,7 @@ public class TaskAttachment implements ITaskAttachment2 {
TaskData taskData = taskAttribute.getTaskData();
TaskAttributeMapper mapper = taskAttribute.getTaskData().getAttributeMapper();
String attachmentId = mapper.getValue(taskAttribute);
- TaskAttachment attachment = new TaskAttachment(taskData.getRepositoryUrl(), taskData.getConnectorKind(),
+ TaskAttachment attachment = new TaskAttachment(taskData.getConnectorKind(), taskData.getRepositoryUrl(),
taskData.getTaskId(), attachmentId);
TaskAttribute child = taskAttribute.getMappedAttribute(TaskAttribute.ATTACHMENT_AUTHOR);
if (child != null) {
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachmentModel.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachmentModel.java
index 644db9780..19460cd14 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachmentModel.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttachmentModel.java
@@ -17,13 +17,19 @@ import org.eclipse.mylyn.tasks.core.TaskRepository;
*/
public class TaskAttachmentModel {
+ private boolean attachContext;
+
private final TaskAttribute attribute;
+ private String comment;
+
private AbstractTaskAttachmentSource source;
+ private final AbstractTask task;
+
private final TaskRepository taskRepository;
- private final AbstractTask task;
+ private String contentType;
public TaskAttachmentModel(TaskRepository taskRepository, AbstractTask task, TaskAttribute attribute) {
this.taskRepository = taskRepository;
@@ -31,16 +37,20 @@ public class TaskAttachmentModel {
this.attribute = attribute;
}
+ public boolean getAttachContext() {
+ return attachContext;
+ }
+
public TaskAttribute getAttribute() {
return attribute;
}
- public AbstractTaskAttachmentSource getSource() {
- return source;
+ public String getComment() {
+ return comment;
}
- public void setSource(AbstractTaskAttachmentSource source) {
- this.source = source;
+ public AbstractTaskAttachmentSource getSource() {
+ return source;
}
public AbstractTask getTask() {
@@ -50,4 +60,28 @@ public class TaskAttachmentModel {
public TaskRepository getTaskRepository() {
return taskRepository;
}
+
+ public void setAttachContext(boolean attachContext) {
+ this.attachContext = attachContext;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public void setSource(AbstractTaskAttachmentSource source) {
+ this.source = source;
+ }
+
+ public String getContentType() {
+ if (contentType == null) {
+ return getSource().getContentType();
+ }
+ return contentType;
+ }
+
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
} \ No newline at end of file
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJob.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJob.java
index 460cad421..f63948e5d 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJob.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJob.java
@@ -9,6 +9,7 @@
package org.eclipse.mylyn.tasks.core.sync;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
@@ -28,7 +29,7 @@ import org.eclipse.mylyn.tasks.core.AbstractTask;
*/
public abstract class SubmitJob extends TaskJob {
- private final List<SubmitJobListener> submitJobListeners = new ArrayList<SubmitJobListener>();
+ private final List<SubmitJobListener> submitJobListeners = Collections.synchronizedList(new ArrayList<SubmitJobListener>());
public SubmitJob(String name) {
super(name);
@@ -46,30 +47,22 @@ public abstract class SubmitJob extends TaskJob {
return submitJobListeners.toArray(new SubmitJobListener[0]);
}
- protected void fireTaskDataPosted(final IProgressMonitor monitor) throws CoreException {
+ protected void fireTaskSubmitted(final IProgressMonitor monitor) throws CoreException {
SubmitJobListener[] listeners = submitJobListeners.toArray(new SubmitJobListener[0]);
if (listeners.length > 0) {
final SubmitJobEvent event = new SubmitJobEvent(this);
for (final SubmitJobListener listener : listeners) {
- listener.taskDataPosted(event, Policy.subMonitorFor(monitor, 100));
+ listener.taskSubmitted(event, Policy.subMonitorFor(monitor, 100));
}
}
}
- protected void fireTaskSynchronized(final IProgressMonitor monitor) {
+ protected void fireTaskSynchronized(final IProgressMonitor monitor) throws CoreException {
SubmitJobListener[] listeners = submitJobListeners.toArray(new SubmitJobListener[0]);
if (listeners.length > 0) {
final SubmitJobEvent event = new SubmitJobEvent(this);
for (final SubmitJobListener listener : listeners) {
- SafeRunner.run(new ISafeRunnable() {
- public void handleException(Throwable e) {
- StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Listener failed", e));
- }
-
- public void run() throws Exception {
- listener.taskSynchronized(event, Policy.subMonitorFor(monitor, 100));
- }
- });
+ listener.taskSynchronized(event, Policy.subMonitorFor(monitor, 100));
}
}
}
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJobListener.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJobListener.java
index 33c5ea669..c9d14b4c1 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJobListener.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/sync/SubmitJobListener.java
@@ -17,9 +17,9 @@ import org.eclipse.core.runtime.IProgressMonitor;
*/
public abstract class SubmitJobListener {
- public abstract void taskDataPosted(SubmitJobEvent event, IProgressMonitor monitor) throws CoreException;
+ public abstract void taskSubmitted(SubmitJobEvent event, IProgressMonitor monitor) throws CoreException;
- public abstract void taskSynchronized(SubmitJobEvent event, IProgressMonitor monitor);
+ public abstract void taskSynchronized(SubmitJobEvent event, IProgressMonitor monitor) throws CoreException;
public abstract void done(SubmitJobEvent event);
diff --git a/org.eclipse.mylyn.tasks.ui/plugin.xml b/org.eclipse.mylyn.tasks.ui/plugin.xml
index 60600cc95..146c50f32 100644
--- a/org.eclipse.mylyn.tasks.ui/plugin.xml
+++ b/org.eclipse.mylyn.tasks.ui/plugin.xml
@@ -1218,6 +1218,11 @@
id="org.eclipse.mylyn.tasks.ui.category.editor"
name="Task Editor">
</category>
+ <command
+ categoryId="org.eclipse.mylyn.tasks.ui.category.editor"
+ id="org.eclipse.mylyn.tasks.ui.command.attachment.openInDefaultEditor"
+ name="Open Attachment in Default Editor">
+ </command>
</extension>
<extension
point="org.eclipse.ui.bindings">
@@ -1346,6 +1351,10 @@
class="org.eclipse.mylyn.internal.tasks.ui.commands.OpenTaskAttachmentInBrowserHandler"
commandId="org.eclipse.mylyn.tasks.ui.command.attachment.openInBrowser">
</handler>
+ <handler
+ class="org.eclipse.mylyn.internal.tasks.ui.commands.OpenTaskAttachmentInDefaultEditorHandler"
+ commandId="org.eclipse.mylyn.tasks.ui.command.attachment.openInDefaultEditor">
+ </handler>
</extension>
<extension
point="org.eclipse.ui.menus">
@@ -1365,15 +1374,15 @@
name="group.open"
visible="false">
</separator>
+ <command
+ commandId="org.eclipse.mylyn.tasks.ui.command.attachment.openInBrowser"
+ label="Open With Browser"
+ style="push">
+ </command>
<menu
label="Open With">
<command
- commandId="org.eclipse.mylyn.tasks.ui.command.attachment.openInBrowser"
- label="Browser"
- style="push">
- </command>
- <command
- commandId="org.eclipse.mylyn.tasks.ui.command3"
+ commandId="org.eclipse.mylyn.tasks.ui.command.attachment.openInDefaultEditor"
label="Default Editor"
style="push">
</command>
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/AttachmentUtil.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/AttachmentUtil.java
index 60888044f..65a428111 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/AttachmentUtil.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/AttachmentUtil.java
@@ -12,6 +12,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;
@@ -23,7 +24,9 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.internal.tasks.core.TaskDataStorageManager;
+import org.eclipse.mylyn.internal.tasks.core.data.FileTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.AbstractAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.FileAttachment;
import org.eclipse.mylyn.tasks.core.RepositoryAttachment;
@@ -31,11 +34,12 @@ import org.eclipse.mylyn.tasks.core.RepositoryStatus;
import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.AbstractTask.SynchronizationState;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentHandler;
import org.eclipse.mylyn.tasks.core.data.ITaskAttachment2;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
/**
* @author Steffen Pingel
- * @since 3.0
*/
public class AttachmentUtil {
@@ -45,6 +49,8 @@ public class AttachmentUtil {
private static final String CONTEXT_FILENAME = "mylyn-context.zip";
+ private static final int BUFFER_SIZE = 1024;
+
/**
* Attaches the associated context to <code>task</code>.
*
@@ -79,6 +85,21 @@ public class AttachmentUtil {
return true;
}
+ public static boolean postContext(AbstractRepositoryConnector connector, TaskRepository repository,
+ AbstractTask task, String comment, IProgressMonitor monitor) throws CoreException {
+ AbstractTaskAttachmentHandler attachmentHandler = connector.getTaskAttachmentHandler();
+ ContextCore.getContextManager().saveContext(task.getHandleIdentifier());
+ File file = ContextCore.getContextManager().getFileForContext(task.getHandleIdentifier());
+ if (file != null && file.exists()) {
+ FileTaskAttachmentSource attachment = new FileTaskAttachmentSource(file);
+ attachment.setDescription(CONTEXT_DESCRIPTION);
+ attachment.setName(CONTEXT_FILENAME);
+ attachmentHandler.postContent(repository, task, attachment, comment, null, monitor);
+ return true;
+ }
+ return false;
+ }
+
/**
* Implementors of this repositoryOperations must perform it locally without going to the server since it is used
* for frequent repositoryOperations such as decoration.
@@ -112,6 +133,7 @@ public class AttachmentUtil {
}
}
+ @Deprecated
public static boolean isContext(RepositoryAttachment attachment) {
return CONTEXT_DESCRIPTION.equals(attachment.getDescription())
|| CONTEXT_DESCRIPTION_LEGACY.equals(attachment.getDescription());
@@ -127,6 +149,7 @@ public class AttachmentUtil {
*
* @return false, if operation is not supported by repository
*/
+ @Deprecated
public static boolean retrieveContext(AbstractAttachmentHandler attachmentHandler, TaskRepository repository,
AbstractTask task, RepositoryAttachment attachment, String destinationPath, IProgressMonitor monitor)
throws CoreException {
@@ -159,4 +182,31 @@ public class AttachmentUtil {
return true;
}
+ public static boolean getContext(AbstractRepositoryConnector connector, TaskRepository repository,
+ AbstractTask task, TaskAttribute attribute, IProgressMonitor monitor) throws CoreException {
+ AbstractTaskAttachmentHandler attachmentHandler = connector.getTaskAttachmentHandler();
+ File file = ContextCore.getContextManager().getFileForContext(task.getHandleIdentifier());
+ try {
+ FileOutputStream out = new FileOutputStream(file);
+ try {
+ InputStream in = attachmentHandler.getContent(repository, task, attribute, monitor);
+ try {
+ int len;
+ byte[] buffer = new byte[BUFFER_SIZE];
+ while ((len = in.read(buffer)) != -1) {
+ out.write(buffer, 0, len);
+ }
+ } finally {
+ in.close();
+ }
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ throw new CoreException(new RepositoryStatus(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
+ RepositoryStatus.ERROR_INTERNAL, "Could not create context file", e));
+ }
+ return true;
+ }
+
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/RepositoryAwareStatusHandler.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/RepositoryAwareStatusHandler.java
index b2df5b22e..a7f6ee4b8 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/RepositoryAwareStatusHandler.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/RepositoryAwareStatusHandler.java
@@ -18,6 +18,7 @@ import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.tasks.ui.util.WebBrowserDialog;
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
/**
@@ -52,51 +53,44 @@ public class RepositoryAwareStatusHandler implements IStatusHandler {
return new MessageDialog(shell, title, null, message, type, new String[] { IDialogConstants.OK_LABEL }, 0);
}
- public void displayStatus(final String title, final IStatus status) {
-
+ public void displayStatus(Shell shell, final String title, final IStatus status) {
if (status.getCode() == RepositoryStatus.ERROR_INTERNAL) {
StatusHandler.log(status);
fail(status, true);
- return;
+ } else {
+ if (status instanceof RepositoryStatus && ((RepositoryStatus) status).isHtmlMessage()) {
+ WebBrowserDialog.openAcceptAgreement(shell, title, status.getMessage(),
+ ((RepositoryStatus) status).getHtmlMessage());
+ } else {
+ switch (status.getSeverity()) {
+ case IStatus.CANCEL:
+ case IStatus.INFO:
+ createDialog(shell, title, status.getMessage(), MessageDialog.INFORMATION).open();
+ break;
+ case IStatus.WARNING:
+ createDialog(shell, title, status.getMessage(), MessageDialog.WARNING).open();
+ break;
+ case IStatus.ERROR:
+ default:
+ createDialog(shell, title, status.getMessage(), MessageDialog.ERROR).open();
+ break;
+ }
+ }
}
+ }
- if (Platform.isRunning()) {
- try {
- PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
- public void run() {
- Shell shell = null;
- if (PlatformUI.getWorkbench() != null
- && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null) {
- shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
- }
-
- if (status instanceof RepositoryStatus && ((RepositoryStatus) status).isHtmlMessage()) {
- WebBrowserDialog.openAcceptAgreement(shell, title, status.getMessage(),
- ((RepositoryStatus) status).getHtmlMessage());
- return;
- }
-
- switch (status.getSeverity()) {
- case IStatus.CANCEL:
- case IStatus.INFO:
- createDialog(shell, title, status.getMessage(), MessageDialog.INFORMATION).open();
- break;
- case IStatus.WARNING:
- createDialog(shell, title, status.getMessage(), MessageDialog.WARNING).open();
- break;
- case IStatus.ERROR:
- default:
- createDialog(shell, title, status.getMessage(), MessageDialog.ERROR).open();
- break;
- }
- }
- });
- } catch (Throwable t) {
- status.getException().printStackTrace();
- }
+ public void displayStatus(final String title, final IStatus status) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench != null && !workbench.getDisplay().isDisposed()
+ && workbench.getDisplay().getActiveShell() != null) {
+ Shell shell = workbench.getDisplay().getActiveShell();
+ displayStatus(shell, title, status);
+ } else {
+ StatusHandler.log(status);
}
}
+ @Deprecated
public void fail(final IStatus status, boolean informUser) {
if (informUser && Platform.isRunning()) {
try {
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/SubmitTaskAttachmentJob.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/SubmitTaskAttachmentJob.java
deleted file mode 100644
index b4a4b335d..000000000
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/SubmitTaskAttachmentJob.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2007 Mylyn project committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.AbstractTask;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.core.data.ITaskAttachment2;
-
-/**
- * @author Steffen Pingel
- */
-public class SubmitTaskAttachmentJob extends Job {
-
- private static final String LABEL_JOB_SUBMIT = "Submitting to repository";
-
- private final ITaskAttachment2 taskAttachment;
-
- private final AbstractRepositoryConnector connector;
-
- private final TaskRepository taskRepository;
-
- private AbstractTask task;
-
- public SubmitTaskAttachmentJob(AbstractRepositoryConnector connector, TaskRepository taskRepository,
- ITaskAttachment2 taskAttachment) {
- super(LABEL_JOB_SUBMIT);
- this.connector = connector;
- this.taskRepository = taskRepository;
- this.taskAttachment = taskAttachment;
- }
-
- @Override
- public IStatus run(IProgressMonitor monitor) {
- return null;
-// try {
-// if (monitor == null) {
-// monitor = new NullProgressMonitor();
-// }
-// monitor.beginTask("Attaching file...", 2);
-// task.setSubmitting(true);
-// task.setSynchronizationState(SynchronizationState.OUTGOING);
-//
-// if (screenshotMode || InputAttachmentSourcePage.SCREENSHOT_LABEL.equals(path)) {
-// ((ImageAttachment) taskAttachment).ensureImageFileWasCreated();
-// } else if (InputAttachmentSourcePage.CLIPBOARD_LABEL.equals(path)) {
-// String contents = inputPage.getClipboardContents();
-// if (contents == null) {
-// throw new InvocationTargetException(new CoreException(new RepositoryStatus(IStatus.ERROR,
-// TasksUiPlugin.ID_PLUGIN, RepositoryStatus.ERROR_INTERNAL, "Clipboard is empty", null)));
-// }
-// taskAttachment.setContent(contents.getBytes());
-// taskAttachment.setFilename(CLIPBOARD_FILENAME);
-// } else {
-// File file = new File(path);
-// taskAttachment.setFile(file);
-// taskAttachment.setFilename(file.getName());
-// }
-//
-// attachmentHandler.uploadAttachment(taskRepository, task, taskAttachment, taskAttachment.getComment(),
-// new SubProgressMonitor(monitor, 1));
-//
-// if (monitor.isCanceled()) {
-// throw new OperationCanceledException();
-// }
-//
-// if (attachContext && connector.getAttachmentHandler() != null) {
-// connector.getAttachmentHandler().attachContext(taskRepository, task, "",
-// new SubProgressMonitor(monitor, 1));
-// }
-// } catch (CoreException e) {
-// return e.getStatus();
-// } finally {
-// task.setSubmitting(false);
-// task.setSynchronizationState(SynchronizationState.SYNCHRONIZED);
-//
-// monitor.done();
-// }
- }
-
-// private void synchronizeTask() {
-// TasksUiPlugin.getSynchronizationManager().synchronize(connector, task, false, new JobChangeAdapter() {
-// @Override
-// public void done(final IJobChangeEvent event) {
-// PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-// public void run() {
-// if (event.getResult().getException() != null) {
-//
-// MessageDialog.openError(Display.getDefault().getActiveShell(),
-// ITasksUiConstants.TITLE_DIALOG, event.getResult().getMessage());
-//
-// }
-// forceRefreshInplace(task);
-// }
-// });
-// }
-// });
-// }
-
-}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TaskJobFactory.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TaskJobFactory.java
index 695cdfe2b..b875db0a1 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TaskJobFactory.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/TaskJobFactory.java
@@ -19,6 +19,7 @@ import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.tasks.core.ITaskJobFactory;
import org.eclipse.mylyn.internal.tasks.core.ITaskListRunnable;
import org.eclipse.mylyn.internal.tasks.core.TaskList;
+import org.eclipse.mylyn.internal.tasks.core.sync.SubmitTaskAttachmentJob;
import org.eclipse.mylyn.internal.tasks.core.sync.SubmitTaskJob;
import org.eclipse.mylyn.internal.tasks.core.sync.SynchronizeAllTasksJob;
import org.eclipse.mylyn.internal.tasks.core.sync.SynchronizeQueriesJob;
@@ -29,6 +30,7 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.ITaskRepositoryManager;
import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.ITaskDataManager;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
@@ -86,10 +88,9 @@ public class TaskJobFactory implements ITaskJobFactory {
return job;
}
- public SubmitJob createSubmitJob(AbstractRepositoryConnector connector, TaskRepository taskRepository,
+ public SubmitJob createSubmitTaskJob(AbstractRepositoryConnector connector, TaskRepository taskRepository,
final AbstractTask task, TaskData taskData, Set<TaskAttribute> changedAttributes) {
- SubmitTaskJob job = new SubmitTaskJob(taskDataManager, connector, taskRepository, task, taskData,
- changedAttributes);
+ SubmitJob job = new SubmitTaskJob(taskDataManager, connector, taskRepository, task, taskData, changedAttributes);
job.setPriority(Job.INTERACTIVE);
try {
taskList.run(new ITaskListRunnable() {
@@ -138,4 +139,23 @@ public class TaskJobFactory implements ITaskJobFactory {
return updateJob;
}
+ public SubmitJob createSubmitTaskAttachmentJob(AbstractRepositoryConnector connector,
+ TaskRepository taskRepository, final AbstractTask task, AbstractTaskAttachmentSource source,
+ String comment, TaskAttribute attachmentAttribute) {
+ SubmitJob job = new SubmitTaskAttachmentJob(taskDataManager, connector, taskRepository, task, source, comment,
+ attachmentAttribute);
+ job.setPriority(Job.INTERACTIVE);
+ try {
+ taskList.run(new ITaskListRunnable() {
+ public void execute(IProgressMonitor monitor) throws CoreException {
+ task.setSubmitting(true);
+ }
+ });
+ } catch (CoreException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Unexpected error", e));
+ }
+ taskList.notifyTaskChanged(task, false);
+ job.setUser(true);
+ return job;
+ }
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInBrowserHandler.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInBrowserHandler.java
index 093bdceee..3d607f6a6 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInBrowserHandler.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInBrowserHandler.java
@@ -19,10 +19,12 @@ import org.eclipse.mylyn.tasks.core.data.ITaskAttachment2;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.ui.handlers.HandlerUtil;
+/**
+ * @author Steffen Pingel
+ */
public class OpenTaskAttachmentInBrowserHandler extends AbstractHandler {
public Object execute(ExecutionEvent event) throws ExecutionException {
- //ISelection selection = HandlerUtil.getActiveMenuSelection(event);
ISelection selection = HandlerUtil.getCurrentSelection(event);
if (selection instanceof IStructuredSelection) {
List<?> items = ((IStructuredSelection) selection).toList();
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInDefaultEditorHandler.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInDefaultEditorHandler.java
new file mode 100644
index 000000000..a9a3d628a
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/OpenTaskAttachmentInDefaultEditorHandler.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.commands;
+
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylyn.internal.tasks.ui.editors.TaskAttachmentEditorInput;
+import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
+import org.eclipse.mylyn.tasks.core.data.ITaskAttachment2;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * @author Steffen Pingel
+ */
+public class OpenTaskAttachmentInDefaultEditorHandler extends AbstractHandler {
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IWorkbenchPage page = null;
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection) {
+ List<?> items = ((IStructuredSelection) selection).toList();
+ for (Object item : items) {
+ if (item instanceof ITaskAttachment2) {
+ if (page == null) {
+ IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
+ page = window.getActivePage();
+ if (page == null) {
+ throw new ExecutionException("No active workbench page");
+ }
+ }
+ openAttachment(page, (ITaskAttachment2) item);
+ }
+ }
+ }
+ return null;
+ }
+
+ private void openAttachment(IWorkbenchPage page, ITaskAttachment2 attachment) throws ExecutionException {
+ TaskAttachmentEditorInput input = new TaskAttachmentEditorInput(attachment);
+ IEditorDescriptor description = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(input.getName());
+ if (description == null) {
+ TasksUiInternal.displayStatus("Open Attachment Failed", new Status(IStatus.WARNING,
+ TasksUiPlugin.ID_PLUGIN, "No default editor for \"" + input.getName() + "\" found"));
+ } else {
+ try {
+ page.openEditor(input, description.getId());
+ } catch (PartInitException e) {
+ throw new ExecutionException("Failed to open editor", e);
+ }
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskAttachmentEditorInput.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskAttachmentEditorInput.java
new file mode 100644
index 000000000..511f6c473
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskAttachmentEditorInput.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Mylyn project committers and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.editors;
+
+import java.io.InputStream;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
+import org.eclipse.mylyn.tasks.core.AbstractTask;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.data.ITaskAttachment2;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.IStorageEditorInput;
+
+/**
+ * @author Jeff Pound
+ * @author Steffen Pingel
+ */
+public class TaskAttachmentEditorInput extends PlatformObject implements IStorageEditorInput {
+
+ private static final String ATTACHMENT_DEFAULT_NAME = "attachment";
+
+ private static final String CTYPE_ZIP = "zip";
+
+ private static final String CTYPE_OCTET_STREAM = "octet-stream";
+
+ private static final String CTYPE_TEXT = "text";
+
+ private static final String CTYPE_HTML = "html";
+
+ private final ITaskAttachment2 attachment;
+
+ private final String name;
+
+ public TaskAttachmentEditorInput(ITaskAttachment2 attachment) {
+ this.attachment = attachment;
+ this.name = getName(attachment);
+ }
+
+ private String getName(ITaskAttachment2 attachment) {
+ String name = attachment.getFileName();
+ // if no filename is set, make one up with the proper extension so
+ // we can support opening in that filetype's default editor
+ if (name == null || "".equals(name)) {
+ String ctype = attachment.getContentType();
+ if (ctype.endsWith(CTYPE_HTML)) {
+ name = ATTACHMENT_DEFAULT_NAME + ".html";
+ } else if (ctype.startsWith(CTYPE_TEXT)) {
+ name = ATTACHMENT_DEFAULT_NAME + ".txt";
+ } else if (ctype.endsWith(CTYPE_OCTET_STREAM)) {
+ name = ATTACHMENT_DEFAULT_NAME;
+ } else if (ctype.endsWith(CTYPE_ZIP)) {
+ name = ATTACHMENT_DEFAULT_NAME + "." + CTYPE_ZIP;
+ } else {
+ name = ATTACHMENT_DEFAULT_NAME + "." + ctype.substring(ctype.indexOf("/") + 1);
+ }
+ }
+ // treat .patch files as text files
+ if (name.endsWith(".patch")) {
+ name += ".txt";
+ }
+ return name;
+ }
+
+ public IStorage getStorage() throws CoreException {
+ TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(attachment.getConnectorKind(),
+ attachment.getRepositoryUrl());
+ AbstractTask task = TasksUi.getTaskListManager().getTaskList().getTask(attachment.getRepositoryUrl(),
+ attachment.getTaskId());
+ TaskData taskData = TasksUi.getTaskDataManager().getTaskData(task, taskRepository.getConnectorKind());
+ TaskAttribute[] attachments = taskData.getAttributeMapper().getAttributesByType(taskData,
+ TaskAttribute.TYPE_ATTACHMENT);
+ for (TaskAttribute taskAttribute : attachments) {
+ ITaskAttachment2 existingAttachment = taskData.getAttributeMapper().getTaskAttachment(taskAttribute);
+ if (existingAttachment.getAttachmentId().equals(attachment.getAttachmentId())) {
+ return new TaskAttachmentStorage(taskRepository, task, taskAttribute, name);
+ }
+ }
+ throw new CoreException(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Failed to find attachment: "
+ + attachment.getUrl()));
+ }
+
+ public boolean exists() {
+ return true;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ // ignore
+ return null;
+ }
+
+ public String getName() {
+ return attachment.getFileName();
+ }
+
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+ public String getToolTipText() {
+ return "Attachment: " + attachment.getAttachmentId() + " [" + attachment.getUrl() + "]";
+ }
+
+ private static class TaskAttachmentStorage extends PlatformObject implements IStorage {
+
+ private final TaskRepository taskRepository;
+
+ private final AbstractTask task;
+
+ private final TaskAttribute attachmentAttribute;
+
+ private final String name;
+
+ public TaskAttachmentStorage(TaskRepository taskRepository, AbstractTask task,
+ TaskAttribute attachmentAttribute, String name) {
+ this.taskRepository = taskRepository;
+ this.task = task;
+ this.attachmentAttribute = attachmentAttribute;
+ this.name = name;
+ }
+
+ public InputStream getContents() throws CoreException {
+ AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
+ taskRepository.getConnectorKind());
+ AbstractTaskAttachmentHandler handler = connector.getTaskAttachmentHandler();
+ return handler.getContent(taskRepository, task, attachmentAttribute, new NullProgressMonitor());
+ }
+
+ public IPath getFullPath() {
+ // ignore
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorAttachmentPart.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorAttachmentPart.java
index e8ad3c0e1..fe659f4d6 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorAttachmentPart.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorAttachmentPart.java
@@ -8,11 +8,13 @@
package org.eclipse.mylyn.internal.tasks.ui.editors;
+import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.OpenEvent;
@@ -22,22 +24,35 @@ import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
+import org.eclipse.mylyn.internal.tasks.core.data.FileTaskAttachmentSource;
+import org.eclipse.mylyn.internal.tasks.core.data.TextTaskAttachmentSource;
import org.eclipse.mylyn.internal.tasks.ui.actions.AttachAction;
import org.eclipse.mylyn.internal.tasks.ui.actions.AttachScreenshotAction;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
+import org.eclipse.mylyn.internal.tasks.ui.wizards.NewAttachmentWizardDialog;
import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskAttachmentWizard.Mode;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.ITaskAttachment2;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
@@ -92,6 +107,8 @@ public class TaskEditorAttachmentPart extends AbstractTaskEditorPart {
private MenuManager menuManager;
+ private TaskAttachmentDropListener dropListener;
+
public TaskEditorAttachmentPart() {
setPartName("Attachments");
}
@@ -161,8 +178,8 @@ public class TaskEditorAttachmentPart extends AbstractTaskEditorPart {
attachmentsTable.setMenu(menu);
}
- private void createAttachmentTableMenu() {
- // FIXME EDITOR
+// private void createAttachmentTableMenu() {
+ // FIXME EDITOR
// final Action openWithBrowserAction = new Action(LABEL_BROWSER) {
// @Override
// public void run() {
@@ -320,7 +337,7 @@ public class TaskEditorAttachmentPart extends AbstractTaskEditorPart {
// attachmentsTableViewer);
// }
// });
- }
+// }
private void createButtons(Composite attachmentsComposite, FormToolkit toolkit) {
final Composite attachmentControlsComposite = toolkit.createComposite(attachmentsComposite);
@@ -332,9 +349,10 @@ public class TaskEditorAttachmentPart extends AbstractTaskEditorPart {
attachFileButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- openNewAttachmentWizard(Mode.DEFAULT);
+ openNewAttachmentWizard(Mode.DEFAULT, null);
}
});
+ registerDropListener(attachFileButton, dropListener);
Button attachScreenshotButton = toolkit.createButton(attachmentControlsComposite, AttachScreenshotAction.LABEL,
SWT.PUSH);
@@ -342,9 +360,10 @@ public class TaskEditorAttachmentPart extends AbstractTaskEditorPart {
attachScreenshotButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- openNewAttachmentWizard(Mode.SCREENSHOT);
+ openNewAttachmentWizard(Mode.SCREENSHOT, null);
}
});
+ registerDropListener(attachScreenshotButton, dropListener);
}
@Override
@@ -358,6 +377,9 @@ public class TaskEditorAttachmentPart extends AbstractTaskEditorPart {
attachmentsComposite.setLayout(new GridLayout(1, false));
attachmentsComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ dropListener = new TaskAttachmentDropListener();
+ registerDropListener(section, dropListener);
+
if (attachments.length > 0) {
createAttachmentTable(toolkit, attachmentsComposite);
} else {
@@ -367,18 +389,19 @@ public class TaskEditorAttachmentPart extends AbstractTaskEditorPart {
createButtons(attachmentsComposite, toolkit);
- // TODO EDITOR fix drop listener
-// registerDropListener(section);
-// registerDropListener(attachmentsComposite);
-// registerDropListener(attachFileButton);
-// if (supportsAttachmentDelete()) {
-// registerDropListener(deleteAttachmentButton);
-// }
-
section.setClient(attachmentsComposite);
setSection(toolkit, section);
}
+ private void registerDropListener(Control control, TaskAttachmentDropListener dropListener) {
+ DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_DEFAULT);
+ final TextTransfer textTransfer = TextTransfer.getInstance();
+ final FileTransfer fileTransfer = FileTransfer.getInstance();
+ Transfer[] types = new Transfer[] { textTransfer, fileTransfer };
+ target.setTransfer(types);
+ target.addDropListener(dropListener);
+ }
+
@Override
public void dispose() {
if (menuManager != null) {
@@ -392,11 +415,84 @@ public class TaskEditorAttachmentPart extends AbstractTaskEditorPart {
TaskAttribute.TYPE_ATTACHMENT);
}
- private void openNewAttachmentWizard(Mode mode) {
+ private NewAttachmentWizardDialog openNewAttachmentWizard(Mode mode, AbstractTaskAttachmentSource source) {
TaskAttributeMapper mapper = getModel().getTaskData().getAttributeMapper();
TaskAttribute attribute = mapper.createTaskAttachment(getModel().getTaskData());
- TasksUiInternal.openNewAttachmentWizard(getTaskEditorPage().getSite().getShell(),
- getTaskEditorPage().getTaskRepository(), getTaskEditorPage().getTask(), attribute, mode);
+ return TasksUiInternal.openNewAttachmentWizard(getTaskEditorPage().getSite().getShell(),
+ getTaskEditorPage().getTaskRepository(), getTaskEditorPage().getTask(), attribute, mode, source);
}
+ /**
+ * @author Mik Kersten
+ * @author Maarten Meijer
+ * @author Steffen Pingel
+ */
+ public class TaskAttachmentDropListener implements DropTargetListener {
+
+ public TaskAttachmentDropListener() {
+ }
+
+ public void dragEnter(DropTargetEvent event) {
+ if (event.detail == DND.DROP_DEFAULT) {
+ if ((event.operations & DND.DROP_COPY) != 0) {
+ event.detail = DND.DROP_COPY;
+ } else {
+ event.detail = DND.DROP_NONE;
+ }
+ }
+ // will accept text but prefer to have files dropped
+ for (TransferData dataType : event.dataTypes) {
+ if (FileTransfer.getInstance().isSupportedType(dataType)) {
+ event.currentDataType = dataType;
+ // files should only be copied
+ if (event.detail != DND.DROP_COPY) {
+ event.detail = DND.DROP_NONE;
+ }
+ break;
+ }
+ }
+ }
+
+ public void dragOver(DropTargetEvent event) {
+ event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
+ }
+
+ public void dragOperationChanged(DropTargetEvent event) {
+ if ((event.detail == DND.DROP_DEFAULT) || (event.operations & DND.DROP_COPY) != 0) {
+ event.detail = DND.DROP_COPY;
+ } else {
+ event.detail = DND.DROP_NONE;
+ }
+ // allow text to be moved but files should only be copied
+ if (FileTransfer.getInstance().isSupportedType(event.currentDataType)) {
+ if (event.detail != DND.DROP_COPY) {
+ event.detail = DND.DROP_NONE;
+ }
+ }
+ }
+
+ public void dragLeave(DropTargetEvent event) {
+ }
+
+ public void dropAccept(DropTargetEvent event) {
+ }
+
+ public void drop(DropTargetEvent event) {
+ if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
+ String text = (String) event.data;
+ openNewAttachmentWizard(null, new TextTaskAttachmentSource(text));
+ }
+ if (FileTransfer.getInstance().isSupportedType(event.currentDataType)) {
+ String[] files = (String[]) event.data;
+ if (files.length > 0) {
+ File file = new File(files[0]);
+ NewAttachmentWizardDialog dialog = openNewAttachmentWizard(null, new FileTaskAttachmentSource(file));
+ if (files.length > 1) {
+ dialog.setMessage("Note that only the first file dragged will be attached.",
+ IMessageProvider.WARNING);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java
index 9fcc47a42..5036c6ec0 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiInternal.java
@@ -23,6 +23,8 @@ import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.mylyn.commons.core.CoreUtil;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.tasks.core.ITaskJobFactory;
@@ -30,7 +32,6 @@ import org.eclipse.mylyn.internal.tasks.core.LocalTask;
import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskDelegate;
import org.eclipse.mylyn.internal.tasks.core.TaskCategory;
import org.eclipse.mylyn.internal.tasks.core.TaskList;
-import org.eclipse.mylyn.internal.tasks.ui.RepositoryAwareStatusHandler;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.editors.CategoryEditor;
import org.eclipse.mylyn.internal.tasks.ui.editors.CategoryEditorInput;
@@ -43,9 +44,11 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.AbstractTaskContainer;
import org.eclipse.mylyn.tasks.core.ITaskList;
+import org.eclipse.mylyn.tasks.core.RepositoryStatus;
import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.TaskSelection;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.sync.SynchronizationJob;
import org.eclipse.mylyn.tasks.core.sync.TaskJob;
@@ -59,6 +62,7 @@ import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
@@ -147,7 +151,6 @@ public class TasksUiInternal {
});
}
- // API 3.0 move to internal class?
public static void refreshAndOpenTaskListElement(AbstractTaskContainer element) {
if (element instanceof AbstractTask || element instanceof ScheduledTaskDelegate) {
final AbstractTask task;
@@ -362,26 +365,56 @@ public class TasksUiInternal {
return TasksUiPlugin.getTasksJobFactory();
}
- /**
- * Display error to user
- *
- * @param title
- * dialog title
- * @param status
- * IStatus to reveal in dialog FIXME deprecated use
- * <code>org.eclipse.ui.statushandlers.StatusMananger#getManager().handle()</code> instead.
- */
- public static void displayStatus(String title, IStatus status) {
- RepositoryAwareStatusHandler.getInstance().displayStatus(title, status);
- }
-
- public static void openNewAttachmentWizard(Shell shell, TaskRepository taskRepository, AbstractTask task,
- TaskAttribute taskAttribute, TaskAttachmentWizard.Mode mode) {
+ public static NewAttachmentWizardDialog openNewAttachmentWizard(Shell shell, TaskRepository taskRepository,
+ AbstractTask task, TaskAttribute taskAttribute, TaskAttachmentWizard.Mode mode,
+ AbstractTaskAttachmentSource source) {
TaskAttachmentWizard attachmentWizard = new TaskAttachmentWizard(taskRepository, task, taskAttribute);
+ attachmentWizard.setSource(source);
attachmentWizard.setMode(mode);
NewAttachmentWizardDialog dialog = new NewAttachmentWizardDialog(shell, attachmentWizard, false);
+ dialog.setBlockOnOpen(false);
dialog.create();
dialog.open();
+ return dialog;
+ }
+
+ private static MessageDialog createDialog(Shell shell, String title, String message, int type) {
+ return new MessageDialog(shell, title, null, message, type, new String[] { IDialogConstants.OK_LABEL }, 0);
}
+ public static void displayStatus(Shell shell, final String title, final IStatus status) {
+ if (status.getCode() == RepositoryStatus.ERROR_INTERNAL) {
+ StatusHandler.fail(status);
+ } else {
+ if (status instanceof RepositoryStatus && ((RepositoryStatus) status).isHtmlMessage()) {
+ WebBrowserDialog.openAcceptAgreement(shell, title, status.getMessage(),
+ ((RepositoryStatus) status).getHtmlMessage());
+ } else {
+ switch (status.getSeverity()) {
+ case IStatus.CANCEL:
+ case IStatus.INFO:
+ createDialog(shell, title, status.getMessage(), MessageDialog.INFORMATION).open();
+ break;
+ case IStatus.WARNING:
+ createDialog(shell, title, status.getMessage(), MessageDialog.WARNING).open();
+ break;
+ case IStatus.ERROR:
+ default:
+ createDialog(shell, title, status.getMessage(), MessageDialog.ERROR).open();
+ break;
+ }
+ }
+ }
+ }
+
+ public static void displayStatus(final String title, final IStatus status) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench != null && !workbench.getDisplay().isDisposed()
+ && workbench.getDisplay().getActiveShell() != null) {
+ Shell shell = workbench.getDisplay().getActiveShell();
+ displayStatus(shell, title, status);
+ } else {
+ StatusHandler.log(status);
+ }
+ }
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage.java
index 714734db0..c0c10d764 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage.java
@@ -35,6 +35,7 @@ import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.mylyn.internal.tasks.core.data.FileTaskAttachmentSource;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.ITaskAttachment2;
@@ -687,16 +688,16 @@ public class InputAttachmentSourcePage extends WizardPage {
public AbstractTaskAttachmentSource getSource() {
switch (getInputMethod()) {
case CLIPBOARD:
- return new TaskAttachmentWizard.ClipboardSource();
+ return new TaskAttachmentWizard.ClipboardTaskAttachmentSource();
case WORKSPACE:
IResource[] resources = getResources(treeViewer.getSelection());
if (resources.length > 0) {
- return new TaskAttachmentWizard.FileSource(resources[0].getLocation().toFile());
+ return new FileTaskAttachmentSource(resources[0].getLocation().toFile());
} else {
return null;
}
default: // FILE
- return new TaskAttachmentWizard.FileSource(new File(getAttachmentFilePath()));
+ return new FileTaskAttachmentSource(new File(getAttachmentFilePath()));
}
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage2.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage2.java
index 75a981129..319d1f4b3 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage2.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/InputAttachmentSourcePage2.java
@@ -35,8 +35,9 @@ import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.mylyn.internal.tasks.core.data.FileTaskAttachmentSource;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskAttachmentWizard.ClipboardSource;
+import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskAttachmentWizard.ClipboardTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel;
import org.eclipse.swt.SWT;
@@ -125,7 +126,7 @@ public class InputAttachmentSourcePage2 extends WizardPage {
super("InputAttachmentPage");
this.model = model;
setTitle("Select attachment source");
- setDescription("Clipboard contents are for text attachments only.");
+ setDescription("Clipboard supports text and image attachments only.");
// setMessage("Please select the source for the attachment");
}
@@ -381,7 +382,7 @@ public class InputAttachmentSourcePage2 extends WizardPage {
boolean attachmentFound = false;
int inputMethod = getInputMethod();
if (inputMethod == CLIPBOARD) {
- if (ClipboardSource.isSupportedType(getControl().getDisplay())) {
+ if (ClipboardTaskAttachmentSource.isSupportedType(getControl().getDisplay())) {
attachmentFound = true;
} else {
error = "Clipboard contains an unsupported data";
@@ -631,16 +632,16 @@ public class InputAttachmentSourcePage2 extends WizardPage {
public AbstractTaskAttachmentSource getSource() {
switch (getInputMethod()) {
case CLIPBOARD:
- return new TaskAttachmentWizard.ClipboardSource();
+ return new TaskAttachmentWizard.ClipboardTaskAttachmentSource();
case WORKSPACE:
IResource[] resources = getResources(treeViewer.getSelection());
if (resources.length > 0) {
- return new TaskAttachmentWizard.FileSource(resources[0].getLocation().toFile());
+ return new FileTaskAttachmentSource(resources[0].getLocation().toFile());
} else {
return null;
}
default: // FILE
- return new TaskAttachmentWizard.FileSource(new File(getAttachmentFilePath()));
+ return new FileTaskAttachmentSource(new File(getAttachmentFilePath()));
}
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/NewAttachmentWizardDialog.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/NewAttachmentWizardDialog.java
index d8d40cea2..7ede8ef39 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/NewAttachmentWizardDialog.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/NewAttachmentWizardDialog.java
@@ -44,4 +44,5 @@ public class NewAttachmentWizardDialog extends WizardDialog {
}
return section;
}
+
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/PreviewAttachmentPage2.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/PreviewAttachmentPage2.java
index 92f4bb435..bd0f257cb 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/PreviewAttachmentPage2.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/PreviewAttachmentPage2.java
@@ -40,8 +40,10 @@ import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ScrollBar;
@@ -67,10 +69,14 @@ public class PreviewAttachmentPage2 extends WizardPage {
private final TaskAttachmentModel model;
+ private Button runInBackgroundButton;
+
private ScrolledComposite scrolledComposite;
private final Set<String> textTypes;
+ private Composite contentComposite;
+
public PreviewAttachmentPage2(TaskAttachmentModel model) {
super(PAGE_NAME);
this.model = model;
@@ -110,16 +116,34 @@ public class PreviewAttachmentPage2 extends WizardPage {
composite.setLayout(new GridLayout());
setControl(composite);
- if (isTextAttachment() || isImageAttachment()) {
- Object content = getContent(composite);
- if (content instanceof String) {
- createTextPreview(composite, (String) content);
- } else if (content instanceof Image) {
- createImagePreview(composite, (Image) content);
+ contentComposite = new Composite(composite, SWT.NONE);
+ contentComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+ contentComposite.setLayout(new GridLayout());
+
+ runInBackgroundButton = new Button(composite, SWT.CHECK);
+ runInBackgroundButton.setText("Run in background");
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ if (visible) {
+ Control[] children = contentComposite.getChildren();
+ for (Control control : children) {
+ control.dispose();
}
- } else {
- createGenericPreview(composite);
+ if (isTextAttachment() || isImageAttachment()) {
+ Object content = getContent(contentComposite);
+ if (content instanceof String) {
+ createTextPreview(contentComposite, (String) content);
+ } else if (content instanceof Image) {
+ createImagePreview(contentComposite, (Image) content);
+ }
+ } else {
+ createGenericPreview(contentComposite);
+ }
+ contentComposite.layout(true, true);
}
+ super.setVisible(visible);
}
private void createErrorPreview(Composite composite, String message) {
@@ -132,7 +156,7 @@ public class PreviewAttachmentPage2 extends WizardPage {
Label label = new Label(composite, SWT.NONE);
label.setLayoutData(new GridData(GridData.FILL_BOTH));
label.setText("Attaching File '" + model.getSource().getName() + "'\nA preview the type '"
- + model.getSource().getContentType() + "' is currently not available");
+ + model.getContentType() + "' is currently not available");
}
private void createImagePreview(Composite composite, final Image bufferedImage) {
@@ -244,11 +268,15 @@ public class PreviewAttachmentPage2 extends WizardPage {
}
private boolean isImageAttachment() {
- return imageTypes.contains(model.getSource().getContentType());
+ return imageTypes.contains(model.getContentType());
}
private boolean isTextAttachment() {
- return textTypes.contains(model.getSource().getContentType());
+ return textTypes.contains(model.getContentType());
+ }
+
+ public boolean runInBackground() {
+ return runInBackgroundButton.getSelection();
}
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentPage.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentPage.java
deleted file mode 100644
index 5f3b99040..000000000
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentPage.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2007 Mylyn project committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.wizards;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
-import org.eclipse.mylyn.tasks.core.data.ITaskAttachment2;
-import org.eclipse.mylyn.tasks.core.data.TaskAttachment;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * A wizard page to enter details of a new attachment.
- *
- * @author Jeff Pound
- * @author Mik Kersten
- */
-public class TaskAttachmentPage extends WizardPage {
-
- private final TaskAttachment attachment;
-
- private Text filePath;
-
- private Text attachmentDesc;
-
- private Text attachmentComment;
-
- private Button isPatchButton;
-
- private Button attachContextButton;
-
- private Combo contentTypeList;
-
- private boolean supportsDescription = true;
-
- private static List<String> contentTypes;
-
- private static Map<String, String> extensions2Types;
-
- static {
- /* For UI */
- contentTypes = new LinkedList<String>();
- contentTypes.add("text/plain");
- contentTypes.add("text/html");
- contentTypes.add("application/xml");
- contentTypes.add("image/gif");
- contentTypes.add("image/jpeg");
- contentTypes.add("image/png");
- contentTypes.add("application/octet-stream");
-
- /* For auto-detect */
- extensions2Types = new HashMap<String, String>();
- extensions2Types.put("txt", "text/plain");
- extensions2Types.put("html", "text/html");
- extensions2Types.put("htm", "text/html");
- extensions2Types.put("jpg", "image/jpeg");
- extensions2Types.put("jpeg", "image/jpeg");
- extensions2Types.put("gif", "image/gif");
- extensions2Types.put("png", "image/png");
- extensions2Types.put("xml", "application/xml");
- extensions2Types.put("zip", "application/octet-stream");
- extensions2Types.put("tar", "application/octet-stream");
- extensions2Types.put("gz", "application/octet-stream");
- }
-
- protected TaskAttachmentPage(TaskAttachment attachment) {
- super("AttachmentDetails");
- setTitle("Attachment Details");
- setMessage("Enter a description and verify the content type of the attachment");
- this.attachment = attachment;
- }
-
- public void createControl(Composite parent) {
- Composite composite = new Composite(parent, SWT.NONE);
- GridLayout gridLayout = new GridLayout();
- gridLayout.numColumns = 3;
- composite.setLayout(gridLayout);
- setControl(composite);
-
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- composite.setLayout(new GridLayout(3, false));
-
- final TaskAttachmentPage thisPage = this;
-
- new Label(composite, SWT.NONE).setText("File");
- filePath = new Text(composite, SWT.BORDER);
- filePath.setEditable(false);
- filePath.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
-
- if (supportsDescription) {
- new Label(composite, SWT.NONE).setText("Description");
- attachmentDesc = new Text(composite, SWT.BORDER);
- attachmentDesc.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
-
- attachmentDesc.addModifyListener(new ModifyListener() {
- public void modifyText(ModifyEvent e) {
- if ("".equals(attachmentDesc.getText().trim())) {
- thisPage.setErrorMessage("Description required");
- } else {
- if (!"".equals(filePath.getText())) {
- thisPage.setPageComplete(true);
- thisPage.setErrorMessage(null);
- }
- }
- }
-
- });
- }
-
- Label label = new Label(composite, SWT.NONE);
- label.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false));
- label.setText("Comment");
- attachmentComment = new Text(composite, SWT.V_SCROLL | SWT.BORDER | SWT.WRAP);
- attachmentComment.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
-
- new Label(composite, SWT.NONE).setText("Content Type");// .setBackground(parent.getBackground());
-
- contentTypeList = new Combo(composite, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
- contentTypeList.setLayoutData(new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false, 2, 1));
- final HashMap<String, Integer> contentTypeIndices = new HashMap<String, Integer>();
- Iterator<String> iter = contentTypes.iterator();
- int i = 0;
- while (iter.hasNext()) {
- String next = iter.next();
- contentTypeList.add(next);
- contentTypeIndices.put(next, new Integer(i));
- i++;
- }
-
- /* Update attachment on select content type */
- contentTypeList.addSelectionListener(new SelectionListener() {
- public void widgetDefaultSelected(SelectionEvent e) {
- // ignore
- }
-
- public void widgetSelected(SelectionEvent e) {
- attachment.setContentType(contentTypeList.getItem(contentTypeList.getSelectionIndex()));
- }
- });
- contentTypeList.select(0);
- attachment.setContentType(contentTypeList.getItem(0));
-
- // TODO: is there a better way to pad?
- new Label(composite, SWT.NONE);
-
- isPatchButton = new Button(composite, SWT.CHECK);
- isPatchButton.setLayoutData(new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false, 2, 1));
- isPatchButton.setText("Patch");
-
- // TODO: is there a better way to pad?
- new Label(composite, SWT.NONE);
-
- attachContextButton = new Button(composite, SWT.CHECK);
- attachContextButton.setLayoutData(new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false, 2, 1));
- attachContextButton.setText("Attach Context");
- attachContextButton.setImage(CommonImages.getImage(TasksUiImages.CONTEXT_ATTACH));
- attachContextButton.setEnabled((((NewAttachmentWizard) getWizard()).hasContext()));
-
- /*
- * Attachment file name listener, update the local attachment
- * accordingly
- */
- filePath.addModifyListener(new ModifyListener() {
- public void modifyText(ModifyEvent e) {
- // Determine type by extension
- int index = filePath.getText().lastIndexOf(".");
- if (index > 0 && index < filePath.getText().length()) {
- String ext = filePath.getText().substring(index + 1);
- String type = extensions2Types.get(ext.toLowerCase(Locale.ENGLISH));
- if (type != null) {
- contentTypeList.select(contentTypeIndices.get(type));
- attachment.setContentType(type);
- }
- }
-
- // check page completenes
- if (attachmentDesc != null && "".equals(attachmentDesc.getText())) {
- thisPage.setErrorMessage("Description required");
- } else {
- if (!"".equals(filePath.getText())) {
- thisPage.setPageComplete(true);
- thisPage.setErrorMessage(null);
- }
- }
- }
- });
-
- filePath.setText(attachment.getFileName() == null ? "" : attachment.getFileName()); //$NON-NLS-1$
-
- /* Listener for isPatch */
- isPatchButton.addSelectionListener(new SelectionListener() {
- private int lastSelected;
-
- public void widgetDefaultSelected(SelectionEvent e) {
- // ignore
- }
-
- public void widgetSelected(SelectionEvent e) {
- attachment.setPatch(isPatchButton.getSelection());
- if (isPatchButton.getSelection()) {
- lastSelected = contentTypeList.getSelectionIndex();
- contentTypeList.select(0);
- contentTypeList.setEnabled(false);
- if (attachContextButton.isEnabled()) {
- attachContextButton.setSelection(true);
- }
- } else {
- contentTypeList.setEnabled(true);
- contentTypeList.select(lastSelected);
- }
- }
- });
-
- thisPage.setErrorMessage(null);
- }
-
- @Override
- public boolean isPageComplete() {
- return !"".equals(filePath.getText().trim())
- && (attachmentDesc == null || !"".equals(attachmentDesc.getText().trim()));
- }
-
- public void populateAttachment() {
- if (attachmentDesc != null) {
- attachment.setDescription(attachmentDesc.getText());
- }
- attachment.setComment(attachmentComment.getText());
- }
-
- public ITaskAttachment2 getAttachment() {
- return attachment;
- }
-
- public void setFilePath(String path) {
- filePath.setText(path);
- if (path.endsWith(".patch")) {
- isPatchButton.setSelection(true);
- if (attachContextButton.isEnabled()) {
- attachContextButton.setSelection(true);
- }
- }
- }
-
- @Override
- public IWizardPage getNextPage() {
- populateAttachment();
- // TODO implement preview
-// PreviewAttachmentPage page = new PreviewAttachmentPage(getAttachment());
-// page.setWizard(getWizard());
-// return page;
- return null;
- }
-
- public boolean getAttachContext() {
- return attachContextButton.getSelection();
- }
-
- public void setContentType() {
- String type = attachment.getContentType();
- String[] typeList = contentTypeList.getItems();
- for (int i = 0; i < typeList.length; i++) {
- if (typeList[i].equals(type)) {
- contentTypeList.select(i);
- contentTypeList.setEnabled(false);
- isPatchButton.setEnabled(false);
- return;
- }
- }
- }
-
- public boolean supportsDescription() {
- return supportsDescription;
- }
-
- public void setSupportsDescription(boolean supportsDescription) {
- this.supportsDescription = supportsDescription;
- }
-
-}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentWizard.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentWizard.java
index 0b900fbaa..d1e6de01b 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentWizard.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentWizard.java
@@ -12,29 +12,41 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
import org.eclipse.mylyn.internal.provisional.commons.ui.ScreenshotCreationPage;
+import org.eclipse.mylyn.internal.tasks.core.sync.SubmitTaskAttachmentJob;
+import org.eclipse.mylyn.internal.tasks.ui.AttachmentUtil;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractTask;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.sync.SubmitJob;
+import org.eclipse.mylyn.tasks.core.sync.SubmitJobEvent;
+import org.eclipse.mylyn.tasks.core.sync.SubmitJobListener;
import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.ImageTransfer;
import org.eclipse.swt.dnd.TextTransfer;
@@ -49,22 +61,37 @@ import org.eclipse.ui.PlatformUI;
* A wizard to add a new attachment to a task report.
*
* @since 3.0
- * @author Jeff Pound
* @author Steffen Pingel
*/
public class TaskAttachmentWizard extends Wizard {
- static class ClipboardSource extends AbstractTaskAttachmentSource {
+ static class ClipboardTaskAttachmentSource extends AbstractTaskAttachmentSource {
+
+ public static boolean isSupportedType(Display display) {
+ Clipboard clipboard = new Clipboard(display);
+ TransferData[] types = clipboard.getAvailableTypes();
+ for (TransferData transferData : types) {
+ if (ImageTransfer.getInstance().isSupportedType(transferData)
+ || TextTransfer.getInstance().isSupportedType(transferData)) {
+ return true;
+ }
+ }
+ return false;
+ }
private Object contents;
- public ClipboardSource() {
- Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());
- contents = clipboard.getContents(ImageTransfer.getInstance());
- if (contents == null) {
- contents = clipboard.getContents(TextTransfer.getInstance());
- }
- clipboard.dispose();
+ public ClipboardTaskAttachmentSource() {
+ BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() {
+ public void run() {
+ Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());
+ contents = clipboard.getContents(ImageTransfer.getInstance());
+ if (contents == null) {
+ contents = clipboard.getContents(TextTransfer.getInstance());
+ }
+ clipboard.dispose();
+ }
+ });
}
@Override
@@ -89,12 +116,12 @@ public class TaskAttachmentWizard extends Wizard {
} else if (contents instanceof ImageData) {
return "image/png";
}
- return "";
+ return "application/octet-stream";
}
@Override
public String getDescription() {
- return "Clipboard";
+ return null;
}
@Override
@@ -120,64 +147,8 @@ public class TaskAttachmentWizard extends Wizard {
return true;
}
- public static boolean isSupportedType(Display display) {
- Clipboard clipboard = new Clipboard(display);
- TransferData[] types = clipboard.getAvailableTypes();
- for (TransferData transferData : types) {
- if (ImageTransfer.getInstance().isSupportedType(transferData)
- || TextTransfer.getInstance().isSupportedType(transferData)) {
- return true;
- }
- }
- return false;
- }
-
};
- static class FileSource extends AbstractTaskAttachmentSource {
-
- private final File file;
-
- public FileSource(File file) {
- this.file = file;
- }
-
- @Override
- public InputStream createInputStream(IProgressMonitor monitor) throws CoreException {
- try {
- return new FileInputStream(file);
- } catch (FileNotFoundException e) {
- throw new CoreException(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, e.getMessage(), e));
- }
- }
-
- @Override
- public String getContentType() {
- return null;
- }
-
- @Override
- public String getDescription() {
- return getName();
- }
-
- @Override
- public long getLength() {
- return file.length();
- }
-
- @Override
- public String getName() {
- return file.getName();
- }
-
- @Override
- public boolean isLocal() {
- return true;
- }
-
- }
-
static class ImageSource extends AbstractTaskAttachmentSource {
private File file;
@@ -249,16 +220,21 @@ public class TaskAttachmentWizard extends Wizard {
private static final String DIALOG_SETTINGS_KEY = "AttachmentWizard";
+ private final AbstractRepositoryConnector connector;
+
+ private IWizardPage editPage;
+
private Mode mode = Mode.DEFAULT;
private final TaskAttachmentModel model;
- private IWizardPage editPage;
+ private PreviewAttachmentPage2 previewPage;
public TaskAttachmentWizard(TaskRepository taskRepository, AbstractTask task, TaskAttribute taskAttachment) {
Assert.isNotNull(taskRepository);
Assert.isNotNull(taskAttachment);
this.model = new TaskAttachmentModel(taskRepository, task, taskAttachment);
+ this.connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(taskRepository.getConnectorKind());
setMode(Mode.DEFAULT);
setNeedsProgressMonitor(true);
setDialogSettings(TasksUiPlugin.getDefault().getDialogSettings().getSection(DIALOG_SETTINGS_KEY));
@@ -279,74 +255,98 @@ public class TaskAttachmentWizard extends Wizard {
.getConnectorKind());
editPage = connectorUi.getAttachmentPage(model);
addPage(editPage);
- }
- public TaskAttachmentModel getModel() {
- return model;
+ previewPage = new PreviewAttachmentPage2(model);
+ addPage(previewPage);
}
public Mode getMode() {
return mode;
}
- @Override
- public IWizardPage getNextPage(IWizardPage page) {
- if (page == editPage) {
- PreviewAttachmentPage2 previewPage = new PreviewAttachmentPage2(model);
- previewPage.setWizard(this);
- return previewPage;
- }
- return super.getNextPage(page);
+ public TaskAttachmentModel getModel() {
+ return model;
}
public AbstractTaskAttachmentSource getSource() {
return model.getSource();
}
-// private void handleSubmitError(final CoreException exception) {
-// if (exception.getStatus().getCode() == RepositoryStatus.ERROR_REPOSITORY_LOGIN) {
-// if (TasksUiUtil.openEditRepositoryWizard(taskRepository) == Window.OK) {
-// // performFinish();
-// }
-// } else {
-// TasksUiInternal.displayStatus("Attachment failed", exception.getStatus());
-// }
-// }
+ private void handleDone(SubmitJob job) {
+ if (job.getError() != null) {
+ TasksUiInternal.displayStatus(getShell(), "Attachment Failed", job.getError());
+ }
+ }
@Override
public boolean performFinish() {
-// attachPage.populateAttachment();
-// final String path = inputPage.getAbsoluteAttachmentPath();
- // upload the attachment
-// final AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
-// taskRepository.getConnectorKind());
-// final AbstractAttachmentHandler attachmentHandler = connector.getAttachmentHandler();
-// if (attachmentHandler == null) {
-// return false;
-// }
-//
-//// final boolean attachContext = attachPage.getAttachContext();
-//
-// final SubmitTaskAttachmentJob job = new SubmitTaskAttachmentJob(connector, taskRepository, taskAttachment);
-// try {
-// getContainer().run(true, true, new IRunnableWithProgress() {
-// public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-// job.run(monitor);
-// }
-// });
-// } catch (InvocationTargetException e) {
-// if (e.getCause() instanceof CoreException) {
-// handleSubmitError((CoreException) e.getCause());
-// } else {
-// StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Attachment failure", e));
-// }
-// return false;
-// } catch (InterruptedException e) {
-// // cancelled
-// return false;
-// }
-
- return true;
+ SubmitJob job = TasksUiInternal.getJobFactory()
+ .createSubmitTaskAttachmentJob(connector, model.getTaskRepository(), model.getTask(),
+ model.getSource(), model.getComment(), model.getAttribute());
+ final boolean attachContext = model.getAttachContext();
+ job.addSubmitJobListener(new SubmitJobListener() {
+ @Override
+ public void done(SubmitJobEvent event) {
+ // ignore
+ }
+
+ @Override
+ public void taskSubmitted(SubmitJobEvent event, IProgressMonitor monitor) throws CoreException {
+ if (attachContext) {
+ monitor.subTask("Attaching context");
+ AttachmentUtil.postContext(connector, model.getTaskRepository(), model.getTask(), null, monitor);
+ }
+ }
+
+ @Override
+ public void taskSynchronized(SubmitJobEvent event, IProgressMonitor monitor) throws CoreException {
+ // ignore
+ }
+ });
+ if (previewPage.runInBackground()) {
+ runInBackground(job);
+ return false;
+ } else {
+ return runInWizard(job);
+ }
+ }
+
+ private void runInBackground(final SubmitJob job) {
+ getContainer().getShell().setVisible(false);
+ job.addJobChangeListener(new JobChangeAdapter() {
+ @Override
+ public void done(IJobChangeEvent event) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ if (job.getError() != null) {
+ getContainer().getShell().setVisible(true);
+ }
+ handleDone(job);
+ }
+ });
+ }
+ });
+ job.schedule();
+ }
+
+ private boolean runInWizard(final SubmitJob job) {
+ try {
+ getContainer().run(true, true, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ if (((SubmitTaskAttachmentJob) job).run(monitor) == Status.CANCEL_STATUS) {
+ throw new InterruptedException();
+ }
+ }
+ });
+ handleDone(job);
+ return job.getError() == null;
+ } catch (InvocationTargetException e) {
+ StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Unexpected error", e));
+ return false;
+ } catch (InterruptedException e) {
+ // canceled
+ return false;
+ }
}
public void setMode(Mode mode) {
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java
index 42bcdc056..a3a283939 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/AbstractRepositoryConnectorUi.java
@@ -26,7 +26,6 @@ import org.eclipse.mylyn.internal.tasks.ui.OpenRepositoryTaskJob;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.wizards.CommonAddExistingTaskWizard;
-import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskAttachmentPage2;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
import org.eclipse.mylyn.tasks.core.AbstractTask;
@@ -40,6 +39,7 @@ import org.eclipse.mylyn.tasks.core.data.ITaskComment;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositorySettingsPage;
+import org.eclipse.mylyn.tasks.ui.wizards.TaskAttachmentPage;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
@@ -293,6 +293,6 @@ public abstract class AbstractRepositoryConnectorUi {
* @since 3.0
*/
public IWizardPage getAttachmentPage(TaskAttachmentModel model) {
- return new TaskAttachmentPage2(model);
+ return new TaskAttachmentPage(model);
}
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java
index 7fdc9a110..33bfc2746 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java
@@ -172,7 +172,7 @@ public abstract class AbstractTaskEditorPage extends FormPage implements ISelect
}
@Override
- public void taskDataPosted(SubmitJobEvent event, IProgressMonitor monitor) throws CoreException {
+ public void taskSubmitted(SubmitJobEvent event, IProgressMonitor monitor) throws CoreException {
// attach context if required
if (attachContext && connector.getAttachmentHandler() != null) {
AttachmentUtil.attachContext(connector.getAttachmentHandler(), taskRepository, task, "", monitor);
@@ -534,7 +534,7 @@ public abstract class AbstractTaskEditorPage extends FormPage implements ISelect
doSave(new NullProgressMonitor());
- SubmitJob submitJob = TasksUiInternal.getJobFactory().createSubmitJob(connector, taskRepository, task,
+ SubmitJob submitJob = TasksUiInternal.getJobFactory().createSubmitTaskJob(connector, taskRepository, task,
getModel().getTaskData(), getModel().getChangedAttributes());
submitJob.addSubmitJobListener(new SubmitTaskJobListener(actionPart.getAttachContext()));
submitJob.schedule();
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentPage2.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/wizards/TaskAttachmentPage.java
index 1aa79380e..3af30e956 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/wizards/TaskAttachmentPage2.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/wizards/TaskAttachmentPage.java
@@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
-package org.eclipse.mylyn.internal.tasks.ui.wizards;
+package org.eclipse.mylyn.tasks.ui.wizards;
import java.util.HashMap;
import java.util.Iterator;
@@ -41,8 +41,9 @@ import org.eclipse.swt.widgets.Text;
* @author Jeff Pound
* @author Mik Kersten
* @author Steffen Pingel
+ * @since 3.0
*/
-public class TaskAttachmentPage2 extends WizardPage {
+public class TaskAttachmentPage extends WizardPage {
private static List<String> contentTypes;
@@ -76,28 +77,30 @@ public class TaskAttachmentPage2 extends WizardPage {
private Button attachContextButton;
- private Text attachmentComment;
+ private Text commentText;
- private Text attachmentDesc;
+ private Text descriptionText;
private Combo contentTypeList;
- private Text filePath;
+ private Text fileNameText;
private Button isPatchButton;
private final TaskAttachmentModel model;
- private boolean supportsDescription = true;
+ private boolean needsDescription;
private final TaskAttachment taskAttachment;
- public TaskAttachmentPage2(TaskAttachmentModel model) {
+ private boolean first = true;
+
+ public TaskAttachmentPage(TaskAttachmentModel model) {
super("AttachmentDetails");
- setTitle("Attachment Details");
- setMessage("Enter a description and verify the content type of the attachment");
this.model = model;
this.taskAttachment = TaskAttachment.createFrom(model.getAttribute());
+ setTitle("Attachment Details");
+ setNeedsDescription(true);
}
public void createControl(Composite parent) {
@@ -111,20 +114,20 @@ public class TaskAttachmentPage2 extends WizardPage {
composite.setLayout(new GridLayout(3, false));
new Label(composite, SWT.NONE).setText("File");
- filePath = new Text(composite, SWT.BORDER);
- filePath.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
+ fileNameText = new Text(composite, SWT.BORDER);
+ fileNameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
- if (supportsDescription) {
+ if (needsDescription) {
new Label(composite, SWT.NONE).setText("Description");
- attachmentDesc = new Text(composite, SWT.BORDER);
- attachmentDesc.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
+ descriptionText = new Text(composite, SWT.BORDER);
+ descriptionText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
- attachmentDesc.addModifyListener(new ModifyListener() {
+ descriptionText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
- if ("".equals(attachmentDesc.getText().trim())) {
+ if ("".equals(descriptionText.getText().trim())) {
setErrorMessage("Description required");
} else {
- if (!"".equals(filePath.getText())) {
+ if (!"".equals(fileNameText.getText())) {
setPageComplete(true);
setErrorMessage(null);
}
@@ -137,8 +140,8 @@ public class TaskAttachmentPage2 extends WizardPage {
Label label = new Label(composite, SWT.NONE);
label.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false));
label.setText("Comment");
- attachmentComment = new Text(composite, SWT.V_SCROLL | SWT.BORDER | SWT.WRAP);
- attachmentComment.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+ commentText = new Text(composite, SWT.V_SCROLL | SWT.BORDER | SWT.WRAP);
+ commentText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
new Label(composite, SWT.NONE).setText("Content Type");// .setBackground(parent.getBackground());
@@ -188,12 +191,12 @@ public class TaskAttachmentPage2 extends WizardPage {
* Attachment file name listener, update the local attachment
* accordingly
*/
- filePath.addModifyListener(new ModifyListener() {
+ fileNameText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
// Determine type by extension
- int index = filePath.getText().lastIndexOf(".");
- if (index > 0 && index < filePath.getText().length()) {
- String ext = filePath.getText().substring(index + 1);
+ int index = fileNameText.getText().lastIndexOf(".");
+ if (index > 0 && index < fileNameText.getText().length()) {
+ String ext = fileNameText.getText().substring(index + 1);
String type = extensions2Types.get(ext.toLowerCase(Locale.ENGLISH));
if (type != null) {
contentTypeList.select(contentTypeIndices.get(type));
@@ -202,10 +205,10 @@ public class TaskAttachmentPage2 extends WizardPage {
}
// check page completenes
- if (attachmentDesc != null && "".equals(attachmentDesc.getText())) {
+ if (descriptionText != null && "".equals(descriptionText.getText())) {
setErrorMessage("Description required");
} else {
- if (!"".equals(filePath.getText())) {
+ if (!"".equals(fileNameText.getText())) {
setPageComplete(true);
setErrorMessage(null);
}
@@ -213,7 +216,7 @@ public class TaskAttachmentPage2 extends WizardPage {
}
});
- filePath.setText(taskAttachment.getFileName() == null ? "" : taskAttachment.getFileName()); //$NON-NLS-1$
+ fileNameText.setText(taskAttachment.getFileName() == null ? "" : taskAttachment.getFileName()); //$NON-NLS-1$
/* Listener for isPatch */
isPatchButton.addSelectionListener(new SelectionListener() {
@@ -240,10 +243,12 @@ public class TaskAttachmentPage2 extends WizardPage {
});
setErrorMessage(null);
- }
- public boolean getAttachContext() {
- return attachContextButton.getSelection();
+ if (descriptionText != null) {
+ descriptionText.setFocus();
+ } else {
+ commentText.setFocus();
+ }
}
public TaskAttachmentModel getModel() {
@@ -253,37 +258,30 @@ public class TaskAttachmentPage2 extends WizardPage {
@Override
public IWizardPage getNextPage() {
taskAttachment.applyTo(model.getAttribute());
+ model.setComment(commentText.getText());
+ model.setAttachContext(attachContextButton.getSelection());
+ model.setContentType(taskAttachment.getContentType());
return super.getNextPage();
}
@Override
public boolean isPageComplete() {
- return !"".equals(filePath.getText().trim())
- && (attachmentDesc == null || !"".equals(attachmentDesc.getText().trim()));
+ return !"".equals(fileNameText.getText().trim())
+ && (descriptionText == null || !"".equals(descriptionText.getText().trim()));
}
- public void populateAttachment() {
- if (attachmentDesc != null) {
- taskAttachment.setDescription(attachmentDesc.getText());
- }
- taskAttachment.setComment(attachmentComment.getText());
- }
-
- public void setContentType() {
- String type = taskAttachment.getContentType();
+ private void setContentType(String contentType) {
String[] typeList = contentTypeList.getItems();
for (int i = 0; i < typeList.length; i++) {
- if (typeList[i].equals(type)) {
+ if (typeList[i].equals(contentType)) {
contentTypeList.select(i);
- contentTypeList.setEnabled(false);
- isPatchButton.setEnabled(false);
- return;
+ break;
}
}
}
- public void setFilePath(String path) {
- filePath.setText(path);
+ private void setFilePath(String path) {
+ fileNameText.setText(path);
if (path.endsWith(".patch")) {
isPatchButton.setSelection(true);
if (attachContextButton.isEnabled()) {
@@ -292,12 +290,40 @@ public class TaskAttachmentPage2 extends WizardPage {
}
}
- public void setSupportsDescription(boolean supportsDescription) {
- this.supportsDescription = supportsDescription;
+ public void setNeedsDescription(boolean supportsDescription) {
+ this.needsDescription = supportsDescription;
+ if (supportsDescription) {
+ setMessage("Enter a description and verify the content type of the attachment");
+ } else {
+ setMessage("Verify the content type of the attachment");
+ }
}
public boolean supportsDescription() {
- return supportsDescription;
+ return needsDescription;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ if (visible) {
+ if (fileNameText.getText().length() == 0) {
+ setFilePath(getModel().getSource().getName());
+ }
+ setContentType(getModel().getSource().getContentType());
+ }
+ super.setVisible(visible);
+ if (first) {
+ if (descriptionText != null) {
+ descriptionText.setFocus();
+ getShell().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ }
+ });
+ } else {
+ commentText.setFocus();
+ }
+ first = false;
+ }
}
}

Back to the top