Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Zarna2013-06-14 15:44:23 +0000
committerGerrit Code Review @ Eclipse.org2013-08-26 16:52:14 +0000
commita9e5559103c66f88e7201426ffb1fb49466d1905 (patch)
treee911da36559198b21567e0cd3154a1a00e544146
parentb6df73eaa3a745d5d8eafad6461b9445274ff059 (diff)
downloadorg.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>
-rw-r--r--org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java6
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/actions/TaskListViewActionGroup.java21
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/AbstractTaskHandler.java60
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/MarkTaskHandler.java101
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/Messages.java4
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/commands/messages.properties3
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java2
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/TasksUiUtil.java11
8 files changed, 180 insertions, 28 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java
index efd35a50f..40897abf7 100644
--- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java
+++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/data/TaskDataManager.java
@@ -458,12 +458,13 @@ public class TaskDataManager implements ITaskDataManager {
}
/**
- * @param task
+ * @param itask
* repository task to mark as read or unread
* @param read
* true to mark as read, false to mark as unread
+ * @return true if synchronization state has been changed
*/
- public void setTaskRead(final ITask itask, final boolean read) {
+ public boolean setTaskRead(final ITask itask, final boolean read) {
final AbstractTask task = (AbstractTask) itask;
Assert.isNotNull(task);
final boolean changed[] = new boolean[1];
@@ -504,6 +505,7 @@ public class TaskDataManager implements ITaskDataManager {
if (changed[0]) {
taskList.notifyElementChanged(task);
}
+ return changed[0];
}
void putEdits(final ITask itask, final TaskData editsData) throws CoreException {
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;
+ }
}

Back to the top