diff options
author | Tomasz Zarna | 2013-06-14 15:44:23 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2013-08-26 16:52:14 +0000 |
commit | a9e5559103c66f88e7201426ffb1fb49466d1905 (patch) | |
tree | e911da36559198b21567e0cd3154a1a00e544146 /org.eclipse.mylyn.tasks.ui | |
parent | b6df73eaa3a745d5d8eafad6461b9445274ff059 (diff) | |
download | org.eclipse.mylyn.tasks-a9e5559103c66f88e7201426ffb1fb49466d1905.tar.gz org.eclipse.mylyn.tasks-a9e5559103c66f88e7201426ffb1fb49466d1905.tar.xz org.eclipse.mylyn.tasks-a9e5559103c66f88e7201426ffb1fb49466d1905.zip |
337999: Undo mark as read command
Bug: 337999
Change-Id: I1694d6dae1a1d0808a3f7d18debd3129131580d2
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=337999
Signed-off-by: Tomasz Zarna <tomasz.zarna@tasktop.com>
Also-by: Sam Davis <sam.davis@tasktop.com>
Diffstat (limited to 'org.eclipse.mylyn.tasks.ui')
7 files changed, 176 insertions, 26 deletions
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/TaskListViewActionGroup.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/TaskListViewActionGroup.java index 9b1fd1b79..d141fa4cd 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/TaskListViewActionGroup.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/TaskListViewActionGroup.java @@ -11,6 +11,8 @@ package org.eclipse.mylyn.internal.tasks.ui.actions; +import org.eclipse.core.commands.operations.IUndoContext; +import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.IStructuredSelection; @@ -18,6 +20,9 @@ import org.eclipse.mylyn.internal.tasks.ui.views.PresentationFilter; import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.ITaskContainer; +import org.eclipse.mylyn.tasks.ui.TasksUiUtil; +import org.eclipse.ui.operations.RedoActionHandler; +import org.eclipse.ui.operations.UndoActionHandler; import org.eclipse.ui.part.DrillDownAdapter; /** @@ -37,6 +42,10 @@ public class TaskListViewActionGroup extends RepositoryElementActionGroup { private final HideQueryAction hideQueryAction; + private final IAction undoAction; + + private final IAction redoAction; + public TaskListViewActionGroup(TaskListView view, DrillDownAdapter drillDownAdapter) { this.view = view; this.drillDownAdapter = drillDownAdapter; @@ -46,6 +55,10 @@ public class TaskListViewActionGroup extends RepositoryElementActionGroup { renameAction = add(new RenameAction(view)); hideQueryAction = add(new HideQueryAction()); + IUndoContext undoContext = TasksUiUtil.getUndoContext(); + undoAction = new UndoActionHandler(view.getSite(), undoContext); + redoAction = new RedoActionHandler(view.getSite(), undoContext); + setSelectionProvider(view.getViewer()); } @@ -106,4 +119,12 @@ public class TaskListViewActionGroup extends RepositoryElementActionGroup { return renameAction; } + public IAction getUndoAction() { + return undoAction; + } + + public IAction getRedoAction() { + return redoAction; + } + } diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/AbstractTaskHandler.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/AbstractTaskHandler.java index 6a7a0468b..adff5db77 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/AbstractTaskHandler.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/AbstractTaskHandler.java @@ -11,6 +11,7 @@ package org.eclipse.mylyn.internal.tasks.ui.commands; +import java.util.HashSet; import java.util.Set; import org.eclipse.core.commands.AbstractHandler; @@ -67,36 +68,57 @@ public abstract class AbstractTaskHandler extends AbstractHandler { Object[] items = ((IStructuredSelection) selection).toArray(); if (singleTask) { if (items.length == 1 && items[0] instanceof ITask) { - processed |= process(event, items[0], false); + processed |= process(event, items, false); } } else { - for (Object item : items) { - processed |= process(event, item, recurse); - } + processed |= process(event, items, recurse); } } return processed; } - private boolean process(ExecutionEvent event, Object item, boolean recurse) throws ExecutionException { - if (!(item instanceof IRepositoryElement)) { - item = Platform.getAdapterManager().getAdapter(item, ITask.class); - } - if (item instanceof ITask) { - execute(event, (ITask) item); - return true; - } - if (item instanceof ITaskContainer && (recurse || !(item instanceof AbstractTask))) { - execute(event, (ITaskContainer) item); + private boolean process(ExecutionEvent event, Object[] items, boolean recurse) throws ExecutionException { + ITask[] tasks = collectTasks(items, recurse); + if (tasks != null) { + execute(event, tasks); return true; } return false; } - protected void execute(ExecutionEvent event, ITaskContainer item) throws ExecutionException { + private ITask[] collectTasks(Object[] items, boolean recurse) { + Set<ITask> result = new HashSet<ITask>(items.length); + for (int i = 0; i < items.length; i++) { + if (!(items[i] instanceof IRepositoryElement)) { + items[i] = Platform.getAdapterManager().getAdapter(items[i], ITask.class); + } + } + getChildren(items, recurse, result); + getTasks(items, result); + + return result.toArray(new ITask[result.size()]); + } + + private void getChildren(Object[] items, boolean recurse, Set<ITask> result) { + for (Object item : items) { + if (item instanceof ITaskContainer && (recurse || !(item instanceof AbstractTask))) { + getFilteredChildren((ITaskContainer) item, result); + } + } + } + + private void getTasks(Object[] items, Set<ITask> result) { + for (Object item : items) { + if (item instanceof ITask) { + result.add((ITask) item); + } + } + } + + protected void getFilteredChildren(ITaskContainer item, Set<ITask> result) { for (ITask task : item.getChildren()) { if (!filterBasedOnActiveTaskList || isVisibleInTaskList(item, task)) { - process(event, task, true); + result.add(task); } } } @@ -118,6 +140,12 @@ public abstract class AbstractTaskHandler extends AbstractHandler { protected void execute(ExecutionEvent event, ITask task) throws ExecutionException { } + protected void execute(ExecutionEvent event, ITask[] tasks) throws ExecutionException { + for (ITask task : tasks) { + execute(event, task); + } + } + public boolean getFilterBasedOnActiveTaskList() { return filterBasedOnActiveTaskList; } diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/MarkTaskHandler.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/MarkTaskHandler.java index 6fe921b22..24b9a9107 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/MarkTaskHandler.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/MarkTaskHandler.java @@ -11,21 +11,34 @@ package org.eclipse.mylyn.internal.tasks.ui.commands; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.List; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.operations.AbstractOperation; +import org.eclipse.core.commands.operations.IOperationHistory; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.mylyn.commons.workbench.WorkbenchUtil; import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; import org.eclipse.mylyn.internal.tasks.ui.actions.ClearOutgoingAction; -import org.eclipse.mylyn.internal.tasks.ui.editors.Messages; import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal; import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView; import org.eclipse.mylyn.monitor.ui.MonitorUi; import org.eclipse.mylyn.tasks.core.IRepositoryElement; import org.eclipse.mylyn.tasks.core.ITask; +import org.eclipse.mylyn.tasks.ui.TasksUiUtil; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; /** * @author Steffen Pingel @@ -54,9 +67,10 @@ public abstract class MarkTaskHandler extends AbstractTaskHandler { @Override protected void execute(ExecutionEvent event, ITask task) throws ExecutionException { - if (MessageDialog.openConfirm(WorkbenchUtil.getShell(), - Messages.TaskEditorPlanningPart_Confirm_Activity_Time_Deletion, - Messages.TaskEditorPlanningPart_Do_you_wish_to_reset_your_activity_time_on_this_task_)) { + if (MessageDialog.openConfirm( + WorkbenchUtil.getShell(), + org.eclipse.mylyn.internal.tasks.ui.editors.Messages.TaskEditorPlanningPart_Confirm_Activity_Time_Deletion, + org.eclipse.mylyn.internal.tasks.ui.editors.Messages.TaskEditorPlanningPart_Do_you_wish_to_reset_your_activity_time_on_this_task_)) { MonitorUi.getActivityContextManager().removeActivityTime(task.getHandleIdentifier(), 0l, System.currentTimeMillis()); } @@ -103,8 +117,8 @@ public abstract class MarkTaskHandler extends AbstractTaskHandler { } @Override - protected void execute(ExecutionEvent event, ITask task) throws ExecutionException { - TasksUiPlugin.getTaskDataManager().setTaskRead(task, true); + protected void execute(final ExecutionEvent event, final ITask[] tasks) throws ExecutionException { + markTasksRead(event, tasks, true); } } @@ -115,8 +129,67 @@ public abstract class MarkTaskHandler extends AbstractTaskHandler { } @Override - protected void execute(ExecutionEvent event, ITask task) throws ExecutionException { - TasksUiPlugin.getTaskDataManager().setTaskRead(task, false); + protected void execute(final ExecutionEvent event, final ITask[] tasks) throws ExecutionException { + markTasksRead(event, tasks, false); + } + } + + private static class MarkTaskReadOperation extends AbstractOperation { + private final IAdaptable info = new IAdaptable() { + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if (adapter == Shell.class) { + return shell; + } + return null; + } + };; + + private final boolean markRead; + + private List<ITask> tasks; + + private final Shell shell; + + public MarkTaskReadOperation(Shell shell, String label, boolean markRead, ITask[] tasks) { + super(label); + this.shell = shell; + this.markRead = markRead; + this.tasks = Arrays.asList(tasks); + addContext(TasksUiUtil.getUndoContext()); + } + + private void execute() throws ExecutionException { + IOperationHistory operationHistory = PlatformUI.getWorkbench().getOperationSupport().getOperationHistory(); + operationHistory.execute(this, new NullProgressMonitor(), info); + } + + @Override + public IStatus execute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { + List<ITask> affectedTasks = new ArrayList<ITask>(tasks.size()); + for (ITask task : tasks) { + if (TasksUiPlugin.getTaskDataManager().setTaskRead(task, markRead)) { + affectedTasks.add(task); + } + } + if (!affectedTasks.containsAll(tasks)) { + tasks = affectedTasks; + } + return Status.OK_STATUS; + } + + @Override + public IStatus undo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { + for (ITask task : tasks) { + TasksUiPlugin.getTaskDataManager().setTaskRead(task, !markRead); + } + return Status.OK_STATUS; + } + + @Override + public IStatus redo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { + return execute(monitor, info); } } @@ -126,7 +199,7 @@ public abstract class MarkTaskHandler extends AbstractTaskHandler { throws ExecutionException { if (item instanceof ITask) { ITask task = (ITask) item; - TasksUiPlugin.getTaskDataManager().setTaskRead(task, true); + markTasksRead(event, new ITask[] { task }, true); GoToUnreadTaskHandler.execute(event, org.eclipse.mylyn.internal.tasks.ui.util.TreeWalker.Direction.DOWN); } } @@ -138,10 +211,18 @@ public abstract class MarkTaskHandler extends AbstractTaskHandler { throws ExecutionException { if (item instanceof ITask) { ITask task = (ITask) item; - TasksUiPlugin.getTaskDataManager().setTaskRead(task, true); + markTasksRead(event, new ITask[] { task }, true); GoToUnreadTaskHandler.execute(event, org.eclipse.mylyn.internal.tasks.ui.util.TreeWalker.Direction.UP); } } } + private static void markTasksRead(final ExecutionEvent event, final ITask[] tasks, boolean markRead) + throws ExecutionException { + Shell shell = HandlerUtil.getActiveShell(event); + MarkTaskReadOperation operation = new MarkTaskReadOperation(shell, + Messages.MarkTaskHandler_MarkTasksUnreadOperation, markRead, tasks); + operation.execute(); + } + } diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/Messages.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/Messages.java index f46901050..2da9c4220 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/Messages.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/Messages.java @@ -50,4 +50,8 @@ public class Messages extends NLS { public static String ShowTasksConnectorDiscoveryWizardCommandHandler_Notify_when_updates_are_available_Text; public static String ShowTasksConnectorDiscoveryWizardCommandHandler_Unable_to_launch_connector_install; + + public static String MarkTaskHandler_MarkTasksReadOperation; + + public static String MarkTaskHandler_MarkTasksUnreadOperation; } diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/messages.properties b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/messages.properties index 20be4be2e..d057e5a1e 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/messages.properties +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/messages.properties @@ -24,3 +24,6 @@ RemoteTaskSelectionDialog_Select_a_task_repository=&Select a task repository\: ShowTasksConnectorDiscoveryWizardCommandHandler_Install_Connectors=Install Connectors ShowTasksConnectorDiscoveryWizardCommandHandler_Notify_when_updates_are_available_Text=Notify when updates are available ShowTasksConnectorDiscoveryWizardCommandHandler_Unable_to_launch_connector_install=Unable to launch connector install since the required platform support is not available. + +MarkTaskHandler_MarkTasksReadOperation=Mark Tasks Read +MarkTaskHandler_MarkTasksUnreadOperation=Mark Tasks Unread diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java index 1cfccc43e..0a61b33bc 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java @@ -1022,6 +1022,8 @@ public class TaskListView extends ViewPart implements IPropertyChangeListener, I IActionBars bars = getViewSite().getActionBars(); bars.setGlobalActionHandler(ActionFactory.DELETE.getId(), actionGroup.getDeleteAction()); bars.setGlobalActionHandler(ActionFactory.COPY.getId(), actionGroup.getCopyDetailsAction()); + bars.setGlobalActionHandler(ActionFactory.UNDO.getId(), actionGroup.getUndoAction()); + bars.setGlobalActionHandler(ActionFactory.REDO.getId(), actionGroup.getRedoAction()); } private void applyPresentation(String id) { diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiUtil.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiUtil.java index 1e3a0b099..3d2ffe554 100644 --- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiUtil.java +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiUtil.java @@ -11,6 +11,8 @@ package org.eclipse.mylyn.tasks.ui; +import org.eclipse.core.commands.operations.IUndoContext; +import org.eclipse.core.commands.operations.ObjectUndoContext; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; @@ -76,6 +78,8 @@ public class TasksUiUtil { @Deprecated public static final int FLAG_NO_RICH_EDITOR = 1 << 17; + private static ObjectUndoContext undoContext; + /** * @since 3.0 */ @@ -448,4 +452,11 @@ public class TasksUiUtil { .getPreferenceStore() .getBoolean(ITasksUiPreferenceConstants.EDITOR_CURRENT_LINE_HIGHLIGHT); } + + public static synchronized IUndoContext getUndoContext() { + if (undoContext == null) { + undoContext = new ObjectUndoContext(new Object(), "Tasks Context"); //$NON-NLS-1$ + } + return undoContext; + } } |