Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspingel2008-06-13 04:21:27 +0000
committerspingel2008-06-13 04:21:27 +0000
commit407094c32e6025e5af1a8406f0de41ee0f895fb3 (patch)
tree0522fa247ac248846beaa5e39958c71b0811b874 /org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util
parent5b13fbea75db0057aee1fdffd76c50e7cdb46969 (diff)
downloadorg.eclipse.mylyn.tasks-407094c32e6025e5af1a8406f0de41ee0f895fb3.tar.gz
org.eclipse.mylyn.tasks-407094c32e6025e5af1a8406f0de41ee0f895fb3.tar.xz
org.eclipse.mylyn.tasks-407094c32e6025e5af1a8406f0de41ee0f895fb3.zip
NEW - bug 236563: items are missing from attachment table context menu
https://bugs.eclipse.org/bugs/show_bug.cgi?id=236563
Diffstat (limited to 'org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util')
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/AttachmentUtil.java441
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/CopyAttachmentToClipboardJob.java63
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/DownloadAttachmentJob.java64
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskAttachmentPropertyTester.java1
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskPropertyTester.java1
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiMenus.java302
6 files changed, 688 insertions, 184 deletions
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/AttachmentUtil.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/AttachmentUtil.java
new file mode 100644
index 000000000..ce8d573f8
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/AttachmentUtil.java
@@ -0,0 +1,441 @@
+/*******************************************************************************
+ * 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.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+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.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.mylyn.commons.core.StatusHandler;
+import org.eclipse.mylyn.commons.net.Policy;
+import org.eclipse.mylyn.context.core.ContextCore;
+import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
+import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
+import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
+import org.eclipse.mylyn.internal.tasks.core.TaskAttachment;
+import org.eclipse.mylyn.internal.tasks.core.TaskDataStorageManager;
+import org.eclipse.mylyn.internal.tasks.core.data.FileTaskAttachmentSource;
+import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractAttachmentHandler;
+import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractLegacyRepositoryConnector;
+import org.eclipse.mylyn.internal.tasks.core.deprecated.FileAttachment;
+import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryAttachment;
+import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
+import org.eclipse.mylyn.internal.tasks.core.sync.SubmitTaskAttachmentJob;
+import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylyn.internal.tasks.ui.deprecated.DownloadAttachmentJob;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.ITaskAttachment;
+import org.eclipse.mylyn.tasks.core.RepositoryStatus;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentHandler;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.sync.SubmitJob;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author Steffen Pingel
+ */
+public class AttachmentUtil {
+
+ protected static final int BUFFER_SIZE = 1024;
+
+ private static final String CONTEXT_DESCRIPTION = "mylyn/context/zip";
+
+ private static final String CONTEXT_DESCRIPTION_LEGACY = "mylar/context/zip";
+
+ private static final String CONTEXT_FILENAME = "mylyn-context.zip";
+
+ private static final String CONTEXT_CONTENT_TYPE = "application/octet-stream";
+
+ /**
+ * Attaches the associated context to <code>task</code>.
+ *
+ * @return false, if operation is not supported by repository
+ */
+ @SuppressWarnings("restriction")
+ @Deprecated
+ public static boolean attachContext(AbstractAttachmentHandler attachmentHandler, TaskRepository repository,
+ ITask task, String longComment, IProgressMonitor monitor) throws CoreException {
+ ContextCorePlugin.getContextStore().saveActiveContext();
+ final File sourceContextFile = ContextCorePlugin.getContextStore()
+ .getFileForContext(task.getHandleIdentifier());
+
+ SynchronizationState previousState = task.getSynchronizationState();
+
+ if (sourceContextFile != null && sourceContextFile.exists()) {
+ try {
+ ((AbstractTask) task).setSubmitting(true);
+ ((AbstractTask) task).setSynchronizationState(SynchronizationState.OUTGOING);
+ FileAttachment attachment = new FileAttachment(sourceContextFile);
+ attachment.setDescription(CONTEXT_DESCRIPTION);
+ attachment.setFilename(CONTEXT_FILENAME);
+ attachmentHandler.uploadAttachment(repository, task, attachment, longComment, monitor);
+ } catch (CoreException e) {
+ // TODO: Calling method should be responsible for returning
+ // state of task. Wizard will have different behaviour than
+ // editor.
+ ((AbstractTask) task).setSynchronizationState(previousState);
+ throw e;
+ } catch (OperationCanceledException e) {
+ return true;
+ }
+ }
+ return true;
+ }
+
+ public static boolean postContext(AbstractRepositoryConnector connector, TaskRepository repository, ITask task,
+ String comment, TaskAttribute attribute, IProgressMonitor monitor) throws CoreException {
+ AbstractTaskAttachmentHandler attachmentHandler = connector.getTaskAttachmentHandler();
+ ContextCorePlugin.getContextStore().saveActiveContext();
+
+ File file = ContextCorePlugin.getContextStore().getFileForContext(task.getHandleIdentifier());
+ if (attachmentHandler != null && file != null && file.exists()) {
+ FileTaskAttachmentSource attachment = new FileTaskAttachmentSource(file);
+ attachment.setDescription(CONTEXT_DESCRIPTION);
+ attachment.setName(CONTEXT_FILENAME);
+ attachmentHandler.postContent(repository, task, attachment, comment, attribute, 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.
+ *
+ * @return an empty set if no contexts
+ */
+ public static Set<RepositoryAttachment> getLegacyContextAttachments(TaskRepository repository, ITask task) {
+ TaskDataStorageManager taskDataManager = TasksUiPlugin.getTaskDataStorageManager();
+ Set<RepositoryAttachment> contextAttachments = new HashSet<RepositoryAttachment>();
+ if (taskDataManager != null) {
+ RepositoryTaskData newData = taskDataManager.getNewTaskData(task.getRepositoryUrl(), task.getTaskId());
+ if (newData != null) {
+ for (RepositoryAttachment attachment : newData.getAttachments()) {
+ if (attachment.getDescription().equals(CONTEXT_DESCRIPTION)) {
+ contextAttachments.add(attachment);
+ } else if (attachment.getDescription().equals(CONTEXT_DESCRIPTION_LEGACY)) {
+ contextAttachments.add(attachment);
+ }
+ }
+ }
+ }
+ return contextAttachments;
+ }
+
+ public static List<ITaskAttachment> getContextAttachments(TaskRepository repository, ITask task) {
+ List<ITaskAttachment> contextAttachments = new ArrayList<ITaskAttachment>();
+ TaskData taskData;
+ try {
+ taskData = TasksUi.getTaskDataManager().getTaskData(task);
+ } catch (CoreException e) {
+ // ignore
+ return contextAttachments;
+ }
+ if (taskData != null) {
+ List<TaskAttribute> taskAttachments = taskData.getAttributeMapper().getAttributesByType(taskData,
+ TaskAttribute.TYPE_ATTACHMENT);
+ for (TaskAttribute attribute : taskAttachments) {
+ TaskAttachment taskAttachment = new TaskAttachment(repository, task, attribute);
+ taskData.getAttributeMapper().updateTaskAttachment(taskAttachment, attribute);
+ if (isContext(taskAttachment)) {
+ contextAttachments.add(taskAttachment);
+ }
+ }
+ }
+ return contextAttachments;
+ }
+
+ public static boolean hasContext(TaskRepository repository, ITask task) {
+ if (repository == null || task == null) {
+ return false;
+ } else {
+ Set<RepositoryAttachment> remoteContextAttachments = getLegacyContextAttachments(repository, task);
+ return (remoteContextAttachments != null && remoteContextAttachments.size() > 0);
+ }
+ }
+
+ public static boolean hasContextAttachment(ITask task) {
+ Assert.isNotNull(task);
+ TaskRepository repository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(),
+ task.getRepositoryUrl());
+ AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
+ repository.getConnectorKind());
+ if (connector instanceof AbstractLegacyRepositoryConnector) {
+ Set<RepositoryAttachment> remoteContextAttachments = getLegacyContextAttachments(repository, task);
+ return (remoteContextAttachments != null && remoteContextAttachments.size() > 0);
+ } else {
+ List<ITaskAttachment> contextAttachments = getContextAttachments(repository, task);
+ return contextAttachments.size() > 0;
+ }
+ }
+
+ private static final String MESSAGE_ATTACHMENTS_NOT_SUPPORTED = "Attachments not supported by connector: ";
+
+ private static final String TITLE_DIALOG = "Mylyn Information";
+
+ public static boolean downloadContext(final ITask task, final ITaskAttachment attachment,
+ final IRunnableContext context) {
+ final AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
+ task.getConnectorKind());
+ final TaskRepository repository = TasksUi.getRepositoryManager().getRepository(attachment.getConnectorKind(),
+ attachment.getRepositoryUrl());
+ final String directory = TasksUiPlugin.getDefault().getDataDirectory();
+ if (task.isActive()) {
+ TasksUi.getTaskActivityManager().deactivateTask(task);
+ }
+ boolean result = false;
+
+ if (connector instanceof AbstractRepositoryConnector) {
+ if (connector.getTaskAttachmentHandler() != null) {
+ result = AttachmentUtil.retrieveContext(connector.getTaskAttachmentHandler(), repository, task,
+ attachment, directory, context);
+ }
+ }
+
+ if (!result) {
+ MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ TITLE_DIALOG, MESSAGE_ATTACHMENTS_NOT_SUPPORTED + connector.getLabel());
+ } else {
+ TasksUiInternal.getTaskList().notifyElementChanged(task);
+ TasksUi.getTaskActivityManager().activateTask(task);
+ }
+ return true;
+ }
+
+ public static boolean uploadContext(final TaskRepository repository, final ITask task, final String comment,
+ final IRunnableContext context) {
+
+ final AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
+ repository.getConnectorKind());
+
+ ContextCorePlugin.getContextStore().saveActiveContext();
+ final File sourceContextFile = ContextCorePlugin.getContextStore()
+ .getFileForContext(task.getHandleIdentifier());
+
+ if (!sourceContextFile.exists()) {
+ return false;
+ }
+
+ FileTaskAttachmentSource source = new FileTaskAttachmentSource(sourceContextFile);
+ source.setDescription(CONTEXT_DESCRIPTION);
+ source.setContentType(CONTEXT_CONTENT_TYPE);
+ final SubmitJob submitJob = TasksUiInternal.getJobFactory().createSubmitTaskAttachmentJob(connector,
+ repository, task, source, comment, null);
+ try {
+ context.run(true, true, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ if (((SubmitTaskAttachmentJob) submitJob).run(monitor) == Status.CANCEL_STATUS) {
+ throw new InterruptedException();
+ }
+ }
+ });
+
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof CoreException) {
+ TasksUiInternal.displayStatus(TITLE_DIALOG, ((CoreException) e.getCause()).getStatus());
+ } else {
+ StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
+ "Unexpected error while attaching context", e));
+ }
+ return false;
+ } catch (InterruptedException ignored) {
+ // canceled
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean hasLocalContext(ITask task) {
+ Assert.isNotNull(task);
+ return ContextCore.getContextManager().hasContext(task.getHandleIdentifier());
+ }
+
+ @SuppressWarnings("restriction")
+ @Deprecated
+ public static boolean isContext(RepositoryAttachment attachment) {
+ return CONTEXT_DESCRIPTION.equals(attachment.getDescription())
+ || CONTEXT_DESCRIPTION_LEGACY.equals(attachment.getDescription());
+ }
+
+ public static boolean isContext(ITaskAttachment attachment) {
+ return CONTEXT_DESCRIPTION.equals(attachment.getDescription())
+ || CONTEXT_DESCRIPTION_LEGACY.equals(attachment.getDescription());
+ }
+
+ /**
+ * Retrieves a context stored in <code>attachment</code> from <code>task</code>.
+ *
+ * @return false, if operation is not supported by repository
+ */
+ public static boolean retrieveContext(AbstractTaskAttachmentHandler attachmentHandler, TaskRepository repository,
+ ITask task, ITaskAttachment attachment, String destinationPath, IRunnableContext context) {
+
+ File destinationContextFile = ContextCorePlugin.getContextStore().getFileForContext(task.getHandleIdentifier());
+ // TODO: add functionality for not overwriting previous context
+ if (destinationContextFile.exists()) {
+ if (!destinationContextFile.delete()) {
+ return false;
+ }
+ }
+
+ final DownloadAttachmentJob downloadJob = new DownloadAttachmentJob(attachment, destinationContextFile);
+
+ try {
+ context.run(true, true, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ if ((downloadJob).run(monitor) == Status.CANCEL_STATUS) {
+ throw new InterruptedException();
+ }
+ }
+ });
+
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof CoreException) {
+ TasksUiInternal.displayStatus(TITLE_DIALOG, ((CoreException) e.getCause()).getStatus());
+ } else {
+ StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
+ "Unexpected error while retrieving context", e));
+ }
+ return false;
+ } catch (InterruptedException ignored) {
+ // canceled
+ return false;
+ }
+
+ return true;
+ }
+
+// public static boolean getContext(AbstractRepositoryConnector connector, TaskRepository repository, ITask task,
+// TaskAttribute attribute, IProgressMonitor monitor) throws CoreException {
+// AbstractTaskAttachmentHandler attachmentHandler = connector.getTaskAttachmentHandler();
+// File file = ContextCorePlugin.getContextStore().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;
+// }
+
+ public static boolean canUploadAttachment(ITask task) {
+ TaskRepository repository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(),
+ task.getRepositoryUrl());
+ AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
+ repository.getConnectorKind());
+ if (connector instanceof AbstractLegacyRepositoryConnector) {
+ AbstractAttachmentHandler attachmentHandler = ((AbstractLegacyRepositoryConnector) connector).getAttachmentHandler();
+ if (attachmentHandler != null) {
+ return attachmentHandler.canUploadAttachment(repository, task);
+ }
+ } else {
+ AbstractTaskAttachmentHandler attachmentHandler = connector.getTaskAttachmentHandler();
+ if (attachmentHandler != null) {
+ return attachmentHandler.canPostContent(repository, task);
+ }
+ }
+ return false;
+ }
+
+ public static boolean canDownloadAttachment(ITask task) {
+ TaskRepository repository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(),
+ task.getRepositoryUrl());
+ AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
+ repository.getConnectorKind());
+ if (connector instanceof AbstractLegacyRepositoryConnector) {
+ AbstractAttachmentHandler attachmentHandler = ((AbstractLegacyRepositoryConnector) connector).getAttachmentHandler();
+ if (attachmentHandler != null) {
+ return attachmentHandler.canDownloadAttachment(repository, task);
+ }
+ } else {
+ AbstractTaskAttachmentHandler attachmentHandler = connector.getTaskAttachmentHandler();
+ if (attachmentHandler != null) {
+ return attachmentHandler.canGetContent(repository, task);
+ }
+ }
+ return false;
+ }
+
+ public static void downloadAttachment(ITaskAttachment attachment, OutputStream out, IProgressMonitor monitor)
+ throws CoreException {
+ try {
+ monitor.beginTask("Downloading attachment", IProgressMonitor.UNKNOWN);
+
+ AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
+ attachment.getConnectorKind());
+ AbstractTaskAttachmentHandler handler = connector.getTaskAttachmentHandler();
+ if (handler == null) {
+ throw new CoreException(new RepositoryStatus(IStatus.INFO, TasksUiPlugin.ID_PLUGIN,
+ RepositoryStatus.ERROR_INTERNAL, "The repository does not support attachments."));
+ }
+
+ InputStream in = handler.getContent(attachment.getTaskRepository(), attachment.getTask(),
+ attachment.getTaskAttribute(), monitor);
+ try {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ while (true) {
+ Policy.checkCanceled(monitor);
+ int count = in.read(buffer);
+ if (count == -1) {
+ return;
+ }
+ out.write(buffer, 0, count);
+ }
+ } catch (IOException e) {
+ throw new CoreException(new RepositoryStatus(attachment.getTaskRepository(), IStatus.ERROR,
+ TasksUiPlugin.ID_PLUGIN, RepositoryStatus.ERROR_IO, "IO error reading attachment: "
+ + e.getMessage(), e));
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
+ "Error closing attachment stream", e));
+ }
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/CopyAttachmentToClipboardJob.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/CopyAttachmentToClipboardJob.java
new file mode 100644
index 000000000..71d835f91
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/CopyAttachmentToClipboardJob.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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.util;
+
+import java.io.ByteArrayOutputStream;
+
+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.Job;
+import org.eclipse.mylyn.tasks.core.ITaskAttachment;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author Steffen Pingel
+ */
+public class CopyAttachmentToClipboardJob extends Job {
+
+ private final ITaskAttachment attachment;
+
+ public CopyAttachmentToClipboardJob(ITaskAttachment attachment) {
+ super("Copying Attachment to Clipboard");
+ this.attachment = attachment;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ AttachmentUtil.downloadAttachment(attachment, out, monitor);
+ } catch (final CoreException e) {
+ TasksUiInternal.asyncDisplayStatus("Copy Attachment to Clipboard", e.getStatus());
+ return Status.OK_STATUS;
+ }
+
+ String contents = new String(out.toByteArray());
+ contents = contents.replaceAll("\r\n|\n", System.getProperty("line.separator"));
+ copyToClipboard(contents);
+
+ return Status.OK_STATUS;
+ }
+
+ private void copyToClipboard(final String contents) {
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+ public void run() {
+ Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());
+ clipboard.setContents(new Object[] { contents }, new Transfer[] { TextTransfer.getInstance() });
+ clipboard.dispose();
+ }
+ });
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/DownloadAttachmentJob.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/DownloadAttachmentJob.java
new file mode 100644
index 000000000..2d6e10cb3
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/DownloadAttachmentJob.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.util;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+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.Job;
+import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylyn.tasks.core.ITaskAttachment;
+import org.eclipse.mylyn.tasks.core.RepositoryStatus;
+
+/**
+ * @author Steffen Pingel
+ */
+public class DownloadAttachmentJob extends Job {
+
+ private final ITaskAttachment attachment;
+
+ private final File targetFile;
+
+ public DownloadAttachmentJob(ITaskAttachment attachment, File targetFile) {
+ super("Downloading Attachment");
+ this.attachment = attachment;
+ this.targetFile = targetFile;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ try {
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(targetFile));
+ try {
+ AttachmentUtil.downloadAttachment(attachment, out, monitor);
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ throw new CoreException(new RepositoryStatus(attachment.getTaskRepository(), IStatus.ERROR,
+ TasksUiPlugin.ID_PLUGIN, RepositoryStatus.ERROR_IO, "IO error writing attachment: "
+ + e.getMessage(), e));
+ }
+ } catch (final CoreException e) {
+ TasksUiInternal.asyncDisplayStatus("Copy Attachment to Clipboard", e.getStatus());
+ return Status.OK_STATUS;
+ }
+
+ return Status.OK_STATUS;
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskAttachmentPropertyTester.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskAttachmentPropertyTester.java
index c5ab1ac71..c0919c795 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskAttachmentPropertyTester.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskAttachmentPropertyTester.java
@@ -9,7 +9,6 @@
package org.eclipse.mylyn.internal.tasks.ui.util;
import org.eclipse.core.expressions.PropertyTester;
-import org.eclipse.mylyn.internal.tasks.ui.AttachmentUtil;
import org.eclipse.mylyn.tasks.core.ITaskAttachment;
/**
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskPropertyTester.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskPropertyTester.java
index a3674c56c..ec388610b 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskPropertyTester.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TaskPropertyTester.java
@@ -10,7 +10,6 @@ package org.eclipse.mylyn.internal.tasks.ui.util;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.ui.AttachmentUtil;
import org.eclipse.mylyn.internal.tasks.ui.actions.ClearOutgoingAction;
import org.eclipse.mylyn.tasks.core.ITask;
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiMenus.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiMenus.java
index d18d54b25..82b5fd58b 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiMenus.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util/TasksUiMenus.java
@@ -8,202 +8,140 @@
package org.eclipse.mylyn.internal.tasks.ui.util;
+import java.io.File;
+
+import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.mylyn.tasks.core.ITaskAttachment;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
/**
* @author Steffen Pingel
*/
public class TasksUiMenus {
-// 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 static final String LABEL_TEXT_EDITOR = "Text Editor";
- //
-// private static final String LABEL_COPY_URL_TO_CLIPBOARD = "Copy &URL";
- //
-// private static final String LABEL_COPY_TO_CLIPBOARD = "Copy Contents";
- //
-// private static final String LABEL_SAVE = "Save...";
- //
-// private static final String LABEL_BROWSER = "Browser";
- //
-// private static final String LABEL_DEFAULT_EDITOR = "Default Editor";
-
-// private void createAttachmentTableMenu() {
- // FIXME EDITOR
-// final Action openWithBrowserAction = new Action(LABEL_BROWSER) {
-// @Override
-// public void run() {
-// TaskAttachment attachment = (TaskAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-// if (attachment != null) {
-// TasksUiUtil.openUrl(attachment.getUrl());
-// }
-// }
-// };
-//
-// final Action openWithDefaultAction = new Action(LABEL_DEFAULT_EDITOR) {
-// @Override
-// public void run() {
-// // browser shortcut
-// TaskAttachment attachment = (TaskAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-// if (attachment == null) {
-// return;
-// }
-//
-// if (attachment.getContentType().endsWith(CTYPE_HTML)) {
-// TasksUiUtil.openUrl(attachment.getUrl());
-// return;
-// }
-//
-// IStorageEditorInput input = new RepositoryAttachmentEditorInput(getTaskRepository(), attachment);
-// IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-// if (page == null) {
-// return;
-// }
-// IEditorDescriptor desc = PlatformUI.getWorkbench()
-// .getEditorRegistry()
-// .getDefaultEditor(input.getName());
-// try {
-// page.openEditor(input, desc.getId());
-// } catch (PartInitException e) {
-// StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Unable to open editor for: "
-// + attachment.getDescription(), e));
-// }
-// }
-// };
-//
-// final Action openWithTextEditorAction = new Action(LABEL_TEXT_EDITOR) {
-// @Override
-// public void run() {
-// TaskAttachment attachment = (TaskAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-// IStorageEditorInput input = new RepositoryAttachmentEditorInput(getTaskRepository(), attachment);
-// IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-// if (page == null) {
-// return;
-// }
-//
-// try {
-// page.openEditor(input, "org.eclipse.ui.DefaultTextEditor");
-// } catch (PartInitException e) {
-// StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Unable to open editor for: "
-// + attachment.getDescription(), e));
-// }
-// }
-// };
-//
-// final Action saveAction = new Action(LABEL_SAVE) {
-// @Override
-// public void run() {
-// TaskAttachment attachment = (TaskAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-// /* Launch Browser */
-// FileDialog fileChooser = new FileDialog(attachmentsTable.getShell(), SWT.SAVE);
-// String fname = attachment.getAttributeValue(RepositoryTaskAttribute.ATTACHMENT_FILENAME);
-// // Default name if none is found
-// if (fname.equals("")) {
-// String ctype = attachment.getContentType();
-// if (ctype.endsWith(CTYPE_HTML)) {
-// fname = ATTACHMENT_DEFAULT_NAME + ".html";
-// } else if (ctype.startsWith(CTYPE_TEXT)) {
-// fname = ATTACHMENT_DEFAULT_NAME + ".txt";
-// } else if (ctype.endsWith(CTYPE_OCTET_STREAM)) {
-// fname = ATTACHMENT_DEFAULT_NAME;
-// } else if (ctype.endsWith(CTYPE_ZIP)) {
-// fname = ATTACHMENT_DEFAULT_NAME + "." + CTYPE_ZIP;
-// } else {
-// fname = ATTACHMENT_DEFAULT_NAME + "." + ctype.substring(ctype.indexOf("/") + 1);
-// }
-// }
-// fileChooser.setFileName(fname);
-// String filePath = fileChooser.open();
-// // Check if the dialog was canceled or an error occurred
-// if (filePath == null) {
-// return;
-// }
-//
-// DownloadAttachmentJob job = new DownloadAttachmentJob(attachment, new File(filePath));
-// job.setUser(true);
-// job.schedule();
-// }
-// };
-//
-// final Action copyURLToClipAction = new Action(LABEL_COPY_URL_TO_CLIPBOARD) {
-// @Override
-// public void run() {
-// TaskAttachment attachment = (TaskAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-// Clipboard clip = new Clipboard(PlatformUI.getWorkbench().getDisplay());
-// clip.setContents(new Object[] { attachment.getUrl() }, new Transfer[] { TextTransfer.getInstance() });
-// clip.dispose();
-// }
-// };
-//
-// final Action copyToClipAction = new Action(LABEL_COPY_TO_CLIPBOARD) {
-// @Override
-// public void run() {
-// TaskAttachment attachment = (TaskAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-// CopyAttachmentToClipboardJob job = new CopyAttachmentToClipboardJob(attachment);
-// job.setUser(true);
-// job.schedule();
-// }
-// };
-//
-// final MenuManager popupMenu = new MenuManager();
-// final Menu menu = popupMenu.createContextMenu(attachmentsTable);
-// attachmentsTable.setMenu(menu);
-// final MenuManager openMenu = new MenuManager("Open With");
-// popupMenu.addMenuListener(new IMenuListener() {
-// public void menuAboutToShow(IMenuManager manager) {
-// popupMenu.removeAll();
-//
-// ISelection selection = attachmentsTableViewer.getSelection();
-// if (selection.isEmpty()) {
-// return;
-// }
-//
-// TaskAttachment att = (TaskAttachment) ((StructuredSelection) selection).getFirstElement();
-//
-// // reinitialize menu
-// popupMenu.add(openMenu);
-// openMenu.removeAll();
-// IStorageEditorInput input = new RepositoryAttachmentEditorInput(getTaskRepository(), att);
-// IEditorDescriptor desc = PlatformUI.getWorkbench()
-// .getEditorRegistry()
-// .getDefaultEditor(input.getName());
-// if (desc != null) {
-// openMenu.add(openWithDefaultAction);
-// }
-// openMenu.add(openWithBrowserAction);
-// openMenu.add(openWithTextEditorAction);
-//
-// popupMenu.add(new Separator());
-// popupMenu.add(saveAction);
-//
-// popupMenu.add(copyURLToClipAction);
-// if (att.getContentType().startsWith(CTYPE_TEXT) || att.getContentType().endsWith("xml")) {
-// popupMenu.add(copyToClipAction);
-// }
-// popupMenu.add(new Separator("actions"));
-//
-// // TODO: use workbench mechanism for this?
-// ObjectActionContributorManager.getManager().contributeObjectActions(getTaskEditorPage(), popupMenu,
-// attachmentsTableViewer);
-// }
-// });
-// }
+ 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 static final String LABEL_COPY_URL_TO_CLIPBOARD = "Copy &URL";
+
+ private static final String LABEL_COPY_TO_CLIPBOARD = "Copy Contents";
+
+ private static final String LABEL_SAVE = "Save...";
public static void fillTaskAttachmentMenu(IMenuManager manager) {
+ final Action saveAction = new Action(LABEL_SAVE) {
+ @Override
+ public void run() {
+ ITaskAttachment attachment = getSelectedAttachment();
+ if (attachment == null) {
+ return;
+ }
+
+ /* Launch Browser */
+ FileDialog fileChooser = new FileDialog(TasksUiInternal.getShell(), SWT.SAVE);
+ String fname = attachment.getFileName();
+ // default name if none is found
+ if (fname.equals("")) {
+ String ctype = attachment.getContentType();
+ if (ctype.endsWith(CTYPE_HTML)) {
+ fname = ATTACHMENT_DEFAULT_NAME + ".html";
+ } else if (ctype.startsWith(CTYPE_TEXT)) {
+ fname = ATTACHMENT_DEFAULT_NAME + ".txt";
+ } else if (ctype.endsWith(CTYPE_OCTET_STREAM)) {
+ fname = ATTACHMENT_DEFAULT_NAME;
+ } else if (ctype.endsWith(CTYPE_ZIP)) {
+ fname = ATTACHMENT_DEFAULT_NAME + "." + CTYPE_ZIP;
+ } else {
+ fname = ATTACHMENT_DEFAULT_NAME + "." + ctype.substring(ctype.indexOf("/") + 1);
+ }
+ }
+ fileChooser.setFileName(fname);
+ String filePath = fileChooser.open();
+ // check if the dialog was canceled or an error occurred
+ if (filePath == null) {
+ return;
+ }
+
+ File file = new File(filePath);
+ if (file.exists()) {
+ if (!MessageDialog.openConfirm(TasksUiInternal.getShell(), "File exists!",
+ "Overwrite existing file?\n" + file.getName())) {
+ return;
+ }
+ }
+
+ DownloadAttachmentJob job = new DownloadAttachmentJob(attachment, file);
+ job.setUser(true);
+ job.schedule();
+ }
+ };
+
+ final Action copyURLToClipAction = new Action(LABEL_COPY_URL_TO_CLIPBOARD) {
+ @Override
+ public void run() {
+ ITaskAttachment attachment = getSelectedAttachment();
+ if (attachment != null) {
+ Clipboard clip = new Clipboard(PlatformUI.getWorkbench().getDisplay());
+ clip.setContents(new Object[] { attachment.getUrl() },
+ new Transfer[] { TextTransfer.getInstance() });
+ clip.dispose();
+ }
+ }
+ };
+
+ final Action copyToClipAction = new Action(LABEL_COPY_TO_CLIPBOARD) {
+ @Override
+ public void run() {
+ ITaskAttachment attachment = getSelectedAttachment();
+ if (attachment != null) {
+ CopyAttachmentToClipboardJob job = new CopyAttachmentToClipboardJob(attachment);
+ job.setUser(true);
+ job.schedule();
+ }
+ }
+ };
+
manager.add(new Separator("group.open"));
manager.add(new Separator("group.save"));
+ manager.add(saveAction);
+ manager.add(copyURLToClipAction);
+ manager.add(copyToClipAction);
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
+ private static ITaskAttachment getSelectedAttachment() {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ ISelection windowSelection = window.getSelectionService().getSelection();
+ IStructuredSelection selection = null;
+ if (windowSelection instanceof IStructuredSelection) {
+ selection = (IStructuredSelection) windowSelection;
+ }
+ if (selection == null || selection.isEmpty()) {
+ return null;
+ }
+ if (selection.getFirstElement() instanceof ITaskAttachment) {
+ return (ITaskAttachment) selection.getFirstElement();
+ }
+ return null;
+ }
+
}

Back to the top