diff options
author | spingel | 2008-06-13 04:21:27 +0000 |
---|---|---|
committer | spingel | 2008-06-13 04:21:27 +0000 |
commit | 407094c32e6025e5af1a8406f0de41ee0f895fb3 (patch) | |
tree | 0522fa247ac248846beaa5e39958c71b0811b874 /org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/util | |
parent | 5b13fbea75db0057aee1fdffd76c50e7cdb46969 (diff) | |
download | org.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')
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; + } + } |