Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspingel2010-05-24 21:30:25 +0000
committerspingel2010-05-24 21:30:25 +0000
commit070a4ea489907f716460e182d3ec9230322dd936 (patch)
tree969e27a3a0ad53fe635ba0629cdf2d3ba20f39de /org.eclipse.mylyn.tasks.ui/src
parent218c0ef5843c22522d06ca96db7c4ac37e15fb68 (diff)
downloadorg.eclipse.mylyn.tasks-070a4ea489907f716460e182d3ec9230322dd936.tar.gz
org.eclipse.mylyn.tasks-070a4ea489907f716460e182d3ec9230322dd936.tar.xz
org.eclipse.mylyn.tasks-070a4ea489907f716460e182d3ec9230322dd936.zip
ASSIGNED - bug 278102: [patch] add quick outline to task editor and provide quick access to related tasks
https://bugs.eclipse.org/bugs/show_bug.cgi?id=278102
Diffstat (limited to 'org.eclipse.mylyn.tasks.ui/src')
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/EditorUtil.java16
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/Messages.java10
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineContentProvider.java56
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineModel.java26
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNode.java123
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNodeLabelProvider.java113
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlinePage.java99
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/messages.properties5
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/Messages.java27
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/QuickOutlineDialog.java532
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/QuickOutlineLabelProvider.java66
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/ShowQuickOutlineHandler.java33
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/messages.properties1
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java141
14 files changed, 1109 insertions, 139 deletions
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/EditorUtil.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/EditorUtil.java
index 72f8bdc40..3c9d61175 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/EditorUtil.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/EditorUtil.java
@@ -153,7 +153,7 @@ public class EditorUtil {
* @param control
* The StyledText to scroll to
*/
- private static void focusOn(ScrolledForm form, Control control) {
+ public static void focusOn(ScrolledForm form, Control control) {
int pos = 0;
control.setEnabled(true);
control.setFocus();
@@ -405,8 +405,11 @@ public class EditorUtil {
} else {
roundedBorder.setLayout(GridLayoutFactory.fillDefaults().margins(0, 6).create());
}
- GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).hint(EditorUtil.MAXIMUM_WIDTH, SWT.DEFAULT).grab(
- true, false).applyTo(roundedBorder);
+ GridDataFactory.fillDefaults()
+ .align(SWT.FILL, SWT.BEGINNING)
+ .hint(EditorUtil.MAXIMUM_WIDTH, SWT.DEFAULT)
+ .grab(true, false)
+ .applyTo(roundedBorder);
return roundedBorder;
}
@@ -432,8 +435,11 @@ public class EditorUtil {
textFont.dispose();
}
});
- Color color = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get(
- CommonThemes.COLOR_COMPLETED);
+ Color color = PlatformUI.getWorkbench()
+ .getThemeManager()
+ .getCurrentTheme()
+ .getColorRegistry()
+ .get(CommonThemes.COLOR_COMPLETED);
text.setForeground(color);
return textFont;
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/Messages.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/Messages.java
index f769d28bd..86eb5e371 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/Messages.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/Messages.java
@@ -151,14 +151,24 @@ public class Messages extends NLS {
public static String TaskEditorNewCommentPart_New_Comment;
+ public static String TaskEditorOutlineNode_Attachments;
+
+ public static String TaskEditorOutlineNode_Attributes;
+
public static String TaskEditorOutlineNode_Comments;
public static String TaskEditorOutlineNode_Description;
public static String TaskEditorOutlineNode_New_Comment;
+ public static String TaskEditorOutlineNode_Related_Tasks;
+
public static String TaskEditorOutlineNode_Task_;
+ public static String TaskEditorOutlineNode_TaskRelation_Label;
+
+ public static String TaskEditorOutlineNode_unknown_Label;
+
public static String TaskEditorPeoplePart_People;
public static String TaskEditorPlanningPart_0_SECOUNDS;
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineContentProvider.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineContentProvider.java
new file mode 100644
index 000000000..07545d2d7
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineContentProvider.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.editors;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+public class TaskEditorOutlineContentProvider implements ITreeContentProvider {
+
+ public void dispose() {
+ // ignore
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof TaskEditorOutlineNode) {
+ Object[] children = ((TaskEditorOutlineNode) parentElement).getChildren();
+ return children;
+ }
+ return new Object[0];
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof TaskEditorOutlineModel) {
+ return new Object[] { ((TaskEditorOutlineModel) inputElement).getRoot() };
+ }
+ return new Object[0];
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof TaskEditorOutlineNode) {
+ return ((TaskEditorOutlineNode) element).getParent();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof TaskEditorOutlineNode) {
+ return ((TaskEditorOutlineNode) element).getChildren().length > 0;
+ }
+ return false;
+ }
+
+ public void inputChanged(Viewer viewerChanged, Object oldInput, Object newInput) {
+ // ignore
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineModel.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineModel.java
new file mode 100644
index 000000000..28478dc37
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineModel.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.editors;
+
+public class TaskEditorOutlineModel {
+
+ private final TaskEditorOutlineNode root;
+
+ public TaskEditorOutlineModel(TaskEditorOutlineNode root) {
+ this.root = root;
+ }
+
+ public TaskEditorOutlineNode getRoot() {
+ return root;
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNode.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNode.java
index a3ada9523..44489a945 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNode.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNode.java
@@ -12,15 +12,27 @@
package org.eclipse.mylyn.internal.tasks.ui.editors;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.mylyn.internal.tasks.core.TaskList;
+import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylyn.internal.tasks.ui.util.AttachmentUtil;
+import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.IRepositoryPerson;
+import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.mylyn.tasks.core.ITaskAttachment;
import org.eclipse.mylyn.tasks.core.ITaskComment;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.mylyn.tasks.core.data.TaskRelation;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.eclipse.osgi.util.NLS;
/**
* A node for the tree in {@link TaskEditorOutlinePage}.
@@ -35,6 +47,12 @@ public class TaskEditorOutlineNode {
public static final String LABEL_NEW_COMMENT = Messages.TaskEditorOutlineNode_New_Comment;
+ public static final String LABEL_ATTACHMENTS = Messages.TaskEditorOutlineNode_Attachments;
+
+ public static final String LABEL_ATTRIBUTES = Messages.TaskEditorOutlineNode_Attributes;
+
+ public static final String LABEL_RELATED_TASKS = Messages.TaskEditorOutlineNode_Related_Tasks;
+
private static TaskEditorOutlineNode createNode(TaskData taskData, String attributeId, String label) {
TaskAttribute taskAttribute = taskData.getRoot().getMappedAttribute(attributeId);
if (taskAttribute != null) {
@@ -69,19 +87,90 @@ public class TaskEditorOutlineNode {
node.setTaskComment(taskComment);
return node;
}
+ } else if (TaskAttribute.TYPE_ATTACHMENT.equals(type)) {
+ ITaskAttachment taskAttachment = TasksUiPlugin.getRepositoryModel().createTaskAttachment(taskAttribute);
+ if (taskAttachment != null) {
+ taskAttribute.getTaskData().getAttributeMapper().updateTaskAttachment(taskAttachment, taskAttribute);
+ StringBuilder sb = new StringBuilder();
+ sb.append(taskAttribute.getTaskData().getAttributeMapper().getValueLabel(taskAttribute));
+ sb.append(": "); //$NON-NLS-1$
+ if (AttachmentUtil.isContext(taskAttachment)) {
+ sb.append(Messages.AttachmentTableLabelProvider_Task_Context);
+ } else if (taskAttachment.isPatch()) {
+ sb.append(Messages.AttachmentTableLabelProvider_Patch);
+ } else {
+ sb.append(taskAttachment.getFileName());
+ }
+ TaskEditorOutlineNode node = new TaskEditorOutlineNode(sb.toString(), taskAttribute);
+ node.setTaskAttachment(taskAttachment);
+ return node;
+ }
} else {
- String label = taskAttribute.getTaskData().getAttributeMapper().getValueLabel(taskAttribute);
+ String label = taskAttribute.getTaskData().getAttributeMapper().getLabel(taskAttribute);
+ if (label.endsWith(":")) { //$NON-NLS-1$
+ label = label.substring(0, label.length() - 1);
+ }
return new TaskEditorOutlineNode(label, taskAttribute);
}
return null;
}
- public static TaskEditorOutlineNode parse(TaskData taskData) {
+ public static TaskEditorOutlineNode parse(TaskData taskData, boolean includeAttributes) {
TaskEditorOutlineNode rootNode = createNode(taskData, TaskAttribute.SUMMARY, null);
if (rootNode == null) {
rootNode = new TaskEditorOutlineNode(Messages.TaskEditorOutlineNode_Task_ + taskData.getTaskId());
}
+ if (includeAttributes) {
+ final TaskList taskList = TasksUiPlugin.getTaskList();
+ TaskEditorOutlineNode relatedTasksNode = new TaskEditorOutlineNode(LABEL_RELATED_TASKS);
+ rootNode.addChild(relatedTasksNode);
+ AbstractRepositoryConnector connector = TasksUi.getRepositoryConnector(taskData.getConnectorKind());
+ Collection<TaskRelation> relations = connector.getTaskRelations(taskData);
+ TaskRepositoryManager manager = TasksUiPlugin.getRepositoryManager();
+ TaskRepository taskRepository = manager.getRepository(taskData.getConnectorKind(),
+ taskData.getRepositoryUrl());
+ for (TaskRelation taskRelation : relations) {
+ ITask task = taskList.getTask(taskData.getRepositoryUrl(), taskRelation.getTaskId());
+ String label;
+ if (task != null) {
+ label = NLS.bind(Messages.TaskEditorOutlineNode_TaskRelation_Label,
+ new Object[] { taskRelation.getTaskId(), task.getSummary() });
+ } else {
+ label = NLS.bind(Messages.TaskEditorOutlineNode_TaskRelation_Label,
+ new Object[] { taskRelation.getTaskId(), Messages.TaskEditorOutlineNode_unknown_Label });
+ }
+ TaskEditorOutlineNode childNode = new TaskEditorOutlineNode(label);
+
+ childNode.setTaskRelation(taskRelation);
+ childNode.setTaskRepository(taskRepository);
+ relatedTasksNode.addChild(childNode);
+ }
+
+ TaskEditorOutlineNode attributesNode = new TaskEditorOutlineNode(LABEL_ATTRIBUTES);
+ rootNode.addChild(attributesNode);
+ Map<String, TaskAttribute> attributes = taskData.getRoot().getAttributes();
+ for (TaskAttribute attribute : attributes.values()) {
+ if (TaskAttribute.KIND_DEFAULT.equals(attribute.getMetaData().getKind())) {
+ TaskEditorOutlineNode node = createNode(attribute);
+ if (node != null) {
+ attributesNode.addChild(node);
+ }
+ }
+ }
+ }
addNode(rootNode, taskData, TaskAttribute.DESCRIPTION, LABEL_DESCRIPTION);
+ List<TaskAttribute> attachments = taskData.getAttributeMapper().getAttributesByType(taskData,
+ TaskAttribute.TYPE_ATTACHMENT);
+ if (attachments.size() > 0) {
+ TaskEditorOutlineNode attachmentNode = new TaskEditorOutlineNode(LABEL_ATTACHMENTS);
+ rootNode.addChild(attachmentNode);
+ for (TaskAttribute attachmentAttribute : attachments) {
+ TaskEditorOutlineNode node = createNode(attachmentAttribute);
+ if (node != null) {
+ attachmentNode.addChild(node);
+ }
+ }
+ }
List<TaskAttribute> comments = taskData.getAttributeMapper().getAttributesByType(taskData,
TaskAttribute.TYPE_COMMENT);
if (comments.size() > 0) {
@@ -118,6 +207,12 @@ public class TaskEditorOutlineNode {
private ITaskComment taskComment;
+ private ITaskAttachment taskAttachment;
+
+ private TaskRelation taskRelation;
+
+ private TaskRepository taskRepository;
+
public TaskEditorOutlineNode(String label) {
this(label, null);
}
@@ -183,4 +278,28 @@ public class TaskEditorOutlineNode {
return getLabel();
}
+ public ITaskAttachment getTaskAttachment() {
+ return taskAttachment;
+ }
+
+ public void setTaskAttachment(ITaskAttachment taskAttachment) {
+ this.taskAttachment = taskAttachment;
+ }
+
+ public TaskRelation getTaskRelation() {
+ return taskRelation;
+ }
+
+ public void setTaskRelation(TaskRelation taskRelation) {
+ this.taskRelation = taskRelation;
+ }
+
+ public TaskRepository getTaskRepository() {
+ return taskRepository;
+ }
+
+ public void setTaskRepository(TaskRepository taskRepository) {
+ this.taskRepository = taskRepository;
+ }
+
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNodeLabelProvider.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNodeLabelProvider.java
new file mode 100644
index 000000000..379ded4c4
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlineNodeLabelProvider.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Frank Becker 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
+ *
+ * Contributors:
+ * Frank Becker - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.editors;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
+import org.eclipse.mylyn.internal.tasks.ui.util.AttachmentUtil;
+import org.eclipse.mylyn.tasks.core.IRepositoryPerson;
+import org.eclipse.mylyn.tasks.core.ITaskAttachment;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.eclipse.mylyn.tasks.ui.TasksUiImages;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.internal.WorkbenchImages;
+
+/**
+ * @author Frank Becker
+ */
+public class TaskEditorOutlineNodeLabelProvider extends LabelProvider {
+
+ private static final String[] IMAGE_EXTENSIONS = { "jpg", "gif", "png", "tiff", "tif", "bmp" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ @Override
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof TaskEditorOutlineNode) {
+ TaskEditorOutlineNode node = (TaskEditorOutlineNode) element;
+ if (TaskEditorOutlineNode.LABEL_COMMENTS.equals(node.getLabel())
+ || TaskEditorOutlineNode.LABEL_NEW_COMMENT.equals(node.getLabel())) {
+ return CommonImages.getImage(TasksUiImages.COMMENT);
+ }
+ if (TaskEditorOutlineNode.LABEL_DESCRIPTION.equals(node.getLabel())) {
+ return CommonImages.getImage(TasksUiImages.TASK_NOTES);
+ } else if (node.getTaskComment() != null) {
+ IRepositoryPerson author = node.getTaskComment().getAuthor();
+ TaskAttribute taskAttribute = node.getData();
+ String repositoryUrl = taskAttribute.getTaskData().getRepositoryUrl();
+ String connectorKind = null;
+ TaskRepository taskRepository = null;
+ if (repositoryUrl != null) {
+ connectorKind = taskAttribute.getTaskData().getConnectorKind();
+ if (connectorKind != null) {
+ taskRepository = TasksUi.getRepositoryManager().getRepository(connectorKind, repositoryUrl);
+ }
+ }
+ if (taskRepository != null && author != null
+ && author.getPersonId().equals(taskRepository.getUserName())) {
+ return CommonImages.getImage(CommonImages.PERSON_ME);
+ } else {
+ return CommonImages.getImage(CommonImages.PERSON);
+ }
+ } else if (node.getTaskAttachment() != null) {
+ ITaskAttachment attachment = node.getTaskAttachment();
+ if (AttachmentUtil.isContext(attachment)) {
+ return CommonImages.getImage(TasksUiImages.CONTEXT_TRANSFER);
+ } else if (attachment.isPatch()) {
+ return CommonImages.getImage(TasksUiImages.TASK_ATTACHMENT_PATCH);
+ } else {
+ String filename = attachment.getFileName();
+ if (filename != null) {
+ int dotIndex = filename.lastIndexOf('.');
+ if (dotIndex != -1) {
+ String fileType = filename.substring(dotIndex + 1);
+ for (String element2 : IMAGE_EXTENSIONS) {
+ if (element2.equalsIgnoreCase(fileType)) {
+ return CommonImages.getImage(CommonImages.IMAGE_FILE);
+ }
+ }
+ }
+ }
+ return WorkbenchImages.getImage(ISharedImages.IMG_OBJ_FILE);
+ }
+ } else if (node.getParent() == null) {
+ return CommonImages.getImage(TasksUiImages.TASK);
+ }
+ }
+ return super.getImage(element);
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof TaskEditorOutlineNode) {
+ TaskEditorOutlineNode node = (TaskEditorOutlineNode) element;
+ if (TaskEditorOutlineNode.LABEL_COMMENTS.equals(node.getLabel())
+ || TaskEditorOutlineNode.LABEL_NEW_COMMENT.equals(node.getLabel())
+ || TaskEditorOutlineNode.LABEL_DESCRIPTION.equals(node.getLabel())) {
+ return node.getLabel();
+ }
+ if (node.getData() != null && node.getTaskAttachment() == null && node.getTaskComment() == null) {
+ // regular attribute
+ TaskAttribute taskAttribute = node.getData();
+ String label = taskAttribute.getTaskData().getAttributeMapper().getLabel(taskAttribute);
+ if (!label.endsWith(":")) { //$NON-NLS-1$
+ label += ":"; //$NON-NLS-1$
+ }
+ return label + " " + taskAttribute.getTaskData().getAttributeMapper().getValueLabel(taskAttribute); //$NON-NLS-1$
+ }
+ return node.getLabel();
+ }
+ return super.getText(element);
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlinePage.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlinePage.java
index 52a3046b7..085c09915 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlinePage.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskEditorOutlinePage.java
@@ -11,16 +11,9 @@
package org.eclipse.mylyn.internal.tasks.ui.editors;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
-import org.eclipse.mylyn.tasks.core.IRepositoryPerson;
import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUiImages;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
-import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
@@ -31,61 +24,6 @@ import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
*/
public class TaskEditorOutlinePage extends ContentOutlinePage {
- private static class TaskEditorOutlineContentProvider implements ITreeContentProvider {
-
- public void dispose() {
- // ignore
- }
-
- public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof TaskEditorOutlineNode) {
- Object[] children = ((TaskEditorOutlineNode) parentElement).getChildren();
- return children;
- }
- return new Object[0];
- }
-
- public Object[] getElements(Object inputElement) {
- if (inputElement instanceof TaskEditorOutlineModel) {
- return new Object[] { ((TaskEditorOutlineModel) inputElement).getRoot() };
- }
- return new Object[0];
- }
-
- public Object getParent(Object element) {
- if (element instanceof TaskEditorOutlineNode) {
- return ((TaskEditorOutlineNode) element).getParent();
- }
- return null;
- }
-
- public boolean hasChildren(Object element) {
- if (element instanceof TaskEditorOutlineNode) {
- return ((TaskEditorOutlineNode) element).getChildren().length > 0;
- }
- return false;
- }
-
- public void inputChanged(Viewer viewerChanged, Object oldInput, Object newInput) {
- // ignore
- }
-
- }
-
- private static class TaskEditorOutlineModel {
-
- private final TaskEditorOutlineNode root;
-
- public TaskEditorOutlineModel(TaskEditorOutlineNode root) {
- this.root = root;
- }
-
- public TaskEditorOutlineNode getRoot() {
- return root;
- }
-
- }
-
private TaskEditorOutlineModel model;
private TaskRepository taskRepository;
@@ -113,42 +51,7 @@ public class TaskEditorOutlinePage extends ContentOutlinePage {
super.createControl(parent);
viewer = getTreeViewer();
viewer.setContentProvider(new TaskEditorOutlineContentProvider());
- viewer.setLabelProvider(new LabelProvider() {
- @Override
- public Image getImage(Object element) {
- if (element instanceof TaskEditorOutlineNode) {
- TaskEditorOutlineNode node = (TaskEditorOutlineNode) element;
- if (TaskEditorOutlineNode.LABEL_COMMENTS.equals(node.getLabel())
- || TaskEditorOutlineNode.LABEL_NEW_COMMENT.equals(node.getLabel())) {
- return CommonImages.getImage(TasksUiImages.COMMENT);
- }
- if (TaskEditorOutlineNode.LABEL_DESCRIPTION.equals(node.getLabel())) {
- return CommonImages.getImage(TasksUiImages.TASK_NOTES);
- } else if (node.getTaskComment() != null) {
- IRepositoryPerson author = node.getTaskComment().getAuthor();
- if (taskRepository != null && author != null
- && author.getPersonId().equals(taskRepository.getUserName())) {
- return CommonImages.getImage(CommonImages.PERSON_ME);
- } else {
- return CommonImages.getImage(CommonImages.PERSON);
- }
- } else {
- return CommonImages.getImage(TasksUiImages.TASK);
- }
- } else {
- return super.getImage(element);
- }
- }
-
- @Override
- public String getText(Object element) {
- if (element instanceof TaskEditorOutlineNode) {
- TaskEditorOutlineNode node = (TaskEditorOutlineNode) element;
- return node.getLabel();
- }
- return super.getText(element);
- }
- });
+ viewer.setLabelProvider(new TaskEditorOutlineNodeLabelProvider());
viewer.setInput(model);
viewer.expandAll();
}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/messages.properties b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/messages.properties
index a137f85c1..0f27c0c02 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/messages.properties
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/messages.properties
@@ -83,10 +83,15 @@ TaskEditorDescriptionPart_The_duplicate_detector_did_not_return_a_valid_query=Th
TaskEditorDescriptionPart_Search=Search
TaskEditorNewCommentPart_New_Comment=New Comment
+TaskEditorOutlineNode_Attachments=Attachments
+TaskEditorOutlineNode_Attributes=Attributes
TaskEditorOutlineNode_Comments=Comments
TaskEditorOutlineNode_Description=Description
TaskEditorOutlineNode_New_Comment=New Comment
+TaskEditorOutlineNode_Related_Tasks=Related Tasks
TaskEditorOutlineNode_Task_=Task
+TaskEditorOutlineNode_TaskRelation_Label={0}: {1}
+TaskEditorOutlineNode_unknown_Label=<unknown>
TaskEditorPeoplePart_People=People
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/Messages.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/Messages.java
new file mode 100644
index 000000000..a427243a6
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/Messages.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.editors.outline;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.tasks.ui.editors.outline.messages"; //$NON-NLS-1$
+
+ public static String QuickOutlineDialog_Press_Esc_Info_Text;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/QuickOutlineDialog.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/QuickOutlineDialog.java
new file mode 100644
index 000000000..2c98c864f
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/QuickOutlineDialog.java
@@ -0,0 +1,532 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation 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
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Tasktop Technologies - adapted for Mylyn
+ * Frank Becker - adapted for Mylyn Task Editor
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.editors.outline;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.PopupDialog;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlExtension;
+import org.eclipse.jface.text.IInformationControlExtension2;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IOpenListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorOutlineContentProvider;
+import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorOutlineModel;
+import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorOutlineNode;
+import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
+import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.dialogs.PatternFilter;
+import org.eclipse.ui.forms.editor.IFormPage;
+
+/**
+ * @author Mik Kersten
+ * @author Frank Becker
+ * @author Steffen Pingel
+ */
+public class QuickOutlineDialog extends PopupDialog implements IInformationControl, IInformationControlExtension,
+ IInformationControlExtension2, DisposeListener {
+
+ private class OpenListener implements IOpenListener, IDoubleClickListener, MouseListener {
+
+ private final Viewer viewer;
+
+ public OpenListener(Viewer viewer) {
+ this.viewer = viewer;
+ }
+
+ public void mouseDoubleClick(MouseEvent e) {
+ setSelection(e);
+ }
+
+ public void mouseDown(MouseEvent e) {
+ setSelection(e);
+ }
+
+ public void mouseUp(MouseEvent e) {
+ // ignore
+
+ }
+
+ public void doubleClick(DoubleClickEvent event) {
+ open(null);
+ }
+
+ public void open(OpenEvent event) {
+ AbstractTaskEditorPage taskEditorPage = getTaskEditorPage();
+ if (taskEditorPage == null) {
+ return;
+ }
+
+ StructuredSelection selection = (StructuredSelection) viewer.getSelection();
+ Object select = (selection).getFirstElement();
+ taskEditorPage.selectReveal(select);
+ }
+
+ private void setSelection(MouseEvent event) {
+ try {
+ Object selection = ((Tree) event.getSource()).getSelection()[0].getData();
+ viewer.setSelection(new StructuredSelection(selection));
+ open(null);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ }
+
+ public static final String ID_VIEWER = "org.eclipse.mylyn.internal.tasks.ui.taskdata.quick"; //$NON-NLS-1$
+
+ private TreeViewer viewer;
+
+ private Text filterText;
+
+ private PatternFilter namePatternFilter;
+
+ private OpenListener openListener;
+
+ private final IWorkbenchWindow window;
+
+ public QuickOutlineDialog(IWorkbenchWindow window) {
+ super(window.getShell(), SWT.RESIZE, true, true, true, true, true, null, null);
+ this.window = window;
+ setInfoText(Messages.QuickOutlineDialog_Press_Esc_Info_Text);
+ create();
+ }
+
+ @Override
+ public boolean close() {
+ // nothing additional to dispose
+ return super.close();
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ createViewer(parent);
+ createUIListenersTreeViewer();
+ addDisposeListener(this);
+
+ return viewer.getControl();
+ }
+
+ private void createViewer(Composite parent) {
+ Control composite = super.createDialogArea(parent);
+ viewer = createCommonViewer((Composite) composite);
+ openListener = new OpenListener(viewer);
+
+ viewer.addOpenListener(openListener);
+ viewer.getTree().addMouseListener(openListener);
+
+ namePatternFilter = new PatternFilter();
+ namePatternFilter.setIncludeLeadingWildcard(true);
+ viewer.addFilter(namePatternFilter);
+
+ AbstractTaskEditorPage taskEditorPage = getTaskEditorPage();
+ if (taskEditorPage != null) {
+ try {
+ viewer.getControl().setRedraw(false);
+ TaskEditorOutlineNode root = TaskEditorOutlineNode.parse(taskEditorPage.getModel().getTaskData(), true);
+ viewer.setInput(new TaskEditorOutlineModel(root));
+ viewer.expandAll();
+ } finally {
+ viewer.getControl().setRedraw(true);
+ }
+ }
+ }
+
+ protected TreeViewer createCommonViewer(Composite parent) {
+ TreeViewer viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
+ viewer.setUseHashlookup(true);
+ viewer.getControl().setLayoutData(new GridData(500, 400));
+ viewer.setContentProvider(new TaskEditorOutlineContentProvider());
+ viewer.setLabelProvider(new QuickOutlineLabelProvider());
+ return viewer;
+ }
+
+ @Override
+ protected void fillDialogMenu(IMenuManager dialogMenu) {
+ dialogMenu.add(new Separator());
+ super.fillDialogMenu(dialogMenu);
+ }
+
+ private void createUIListenersTreeViewer() {
+ final Tree tree = viewer.getTree();
+ tree.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ if (e.character == 0x1B) {
+ // Dispose on ESC key press
+ dispose();
+ }
+ }
+
+ public void keyReleased(KeyEvent e) {
+ // ignore
+ }
+ });
+
+ tree.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseUp(MouseEvent e) {
+ handleTreeViewerMouseUp(tree, e);
+ }
+ });
+
+ tree.addSelectionListener(new SelectionListener() {
+ public void widgetSelected(SelectionEvent e) {
+ // ignore
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ gotoSelectedElement();
+ }
+ });
+ }
+
+ private void handleTreeViewerMouseUp(final Tree tree, MouseEvent e) {
+ if ((tree.getSelectionCount() < 1) || (e.button != 1) || (tree.equals(e.getSource()) == false)) {
+ return;
+ }
+ // Selection is made in the selection changed listener
+ Object object = tree.getItem(new Point(e.x, e.y));
+ TreeItem selection = tree.getSelection()[0];
+ if (selection.equals(object)) {
+ gotoSelectedElement();
+ }
+ }
+
+ private Object getSelectedElement() {
+ if (viewer == null) {
+ return null;
+ }
+ return ((IStructuredSelection) viewer.getSelection()).getFirstElement();
+ }
+
+ public void addDisposeListener(DisposeListener listener) {
+ getShell().addDisposeListener(listener);
+ }
+
+ public void addFocusListener(FocusListener listener) {
+ getShell().addFocusListener(listener);
+ }
+
+ public Point computeSizeHint() {
+ // Note that it already has the persisted size if persisting is enabled.
+ return getShell().getSize();
+ }
+
+ public void dispose() {
+ close();
+ }
+
+ public boolean isFocusControl() {
+ if (viewer.getControl().isFocusControl() || filterText.isFocusControl()) {
+ return true;
+ }
+ return false;
+ }
+
+ public void removeDisposeListener(DisposeListener listener) {
+ getShell().removeDisposeListener(listener);
+ }
+
+ public void removeFocusListener(FocusListener listener) {
+ getShell().removeFocusListener(listener);
+ }
+
+ public void setBackgroundColor(Color background) {
+ applyBackgroundColor(background, getContents());
+ }
+
+ public void setFocus() {
+ getShell().forceFocus();
+ filterText.setFocus();
+ }
+
+ public void setForegroundColor(Color foreground) {
+ applyForegroundColor(foreground, getContents());
+ }
+
+ public void setInformation(String information) {
+ // See IInformationControlExtension2
+ }
+
+ public void setLocation(Point location) {
+ /*
+ * If the location is persisted, it gets managed by PopupDialog - fine. Otherwise, the location is
+ * computed in Window#getInitialLocation, which will center it in the parent shell / main
+ * monitor, which is wrong for two reasons:
+ * - we want to center over the editor / subject control, not the parent shell
+ * - the center is computed via the initalSize, which may be also wrong since the size may
+ * have been updated since via min/max sizing of AbstractInformationControlManager.
+ * In that case, override the location with the one computed by the manager. Note that
+ * the call to constrainShellSize in PopupDialog.open will still ensure that the shell is
+ * entirely visible.
+ */
+ if (getPersistLocation() == false || getDialogSettings() == null) {
+ getShell().setLocation(location);
+ }
+ }
+
+ public void setSize(int width, int height) {
+ getShell().setSize(width, height);
+ }
+
+ public void setSizeConstraints(int maxWidth, int maxHeight) {
+ // Ignore
+ }
+
+ public void setVisible(boolean visible) {
+ if (visible) {
+ open();
+ } else {
+ saveDialogBounds(getShell());
+ getShell().setVisible(false);
+ }
+ }
+
+ public boolean hasContents() {
+ if ((viewer == null) || (viewer.getInput() == null)) {
+ return false;
+ }
+ return true;
+ }
+
+ public void setInput(Object input) {
+ if (input != null) {
+ viewer.setSelection(new StructuredSelection(input));
+ }
+ }
+
+ public void widgetDisposed(DisposeEvent e) {
+ // Note: We do not reuse the dialog
+ viewer = null;
+ filterText = null;
+ }
+
+ @Override
+ protected Control createTitleControl(Composite parent) {
+ Composite control = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginHeight = 0;
+ control.setLayout(layout);
+ control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ // Applies only to dialog title - not body. See createDialogArea
+ // Create the text widget
+ createUIWidgetFilterText(control);
+ // Add listeners to the text widget
+ createUIListenersFilterText();
+ // Return the text widget
+ return control;
+ }
+
+ private void createUIWidgetFilterText(Composite parent) {
+ // Create the widget
+ filterText = new Text(parent, SWT.NONE);
+ // Set the font
+ GC gc = new GC(parent);
+ gc.setFont(parent.getFont());
+ FontMetrics fontMetrics = gc.getFontMetrics();
+ gc.dispose();
+ // Create the layout
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ data.heightHint = Dialog.convertHeightInCharsToPixels(fontMetrics, 1);
+ data.horizontalAlignment = GridData.FILL;
+ data.verticalAlignment = GridData.CENTER;
+ filterText.setLayoutData(data);
+ }
+
+ /**
+ *
+ */
+ private void gotoSelectedElement() {
+ Object selectedElement = getSelectedElement();
+ if (selectedElement == null) {
+ return;
+ }
+ dispose();
+ }
+
+ private void createUIListenersFilterText() {
+ filterText.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ if (e.keyCode == 0x0D) {
+ // Return key was pressed
+ gotoSelectedElement();
+ } else if (e.keyCode == SWT.ARROW_DOWN) {
+ // Down key was pressed
+ viewer.getTree().setFocus();
+ } else if (e.keyCode == SWT.ARROW_UP) {
+ // Up key was pressed
+ viewer.getTree().setFocus();
+ } else if (e.character == 0x1B) {
+ // Escape key was pressed
+ dispose();
+ }
+ }
+
+ public void keyReleased(KeyEvent e) {
+ // NO-OP
+ }
+ });
+ // Handle text modify events
+ filterText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String text = ((Text) e.widget).getText();
+ int length = text.length();
+ if (length > 0) {
+ // Append a '*' pattern to the end of the text value if it
+ // does not have one already
+ if (text.charAt(length - 1) != '*') {
+ text = text + '*';
+ }
+ // Prepend a '*' pattern to the beginning of the text value
+ // if it does not have one already
+ if (text.charAt(0) != '*') {
+ text = '*' + text;
+ }
+ }
+ // Set and update the pattern
+ setMatcherString(text, true);
+ }
+ });
+ }
+
+ /**
+ * Sets the patterns to filter out for the receiver.
+ * <p>
+ * The following characters have special meaning: ? => any character * => any string
+ * </p>
+ *
+ * @param pattern
+ * the pattern
+ * @param update
+ * <code>true</code> if the viewer should be updated
+ */
+ private void setMatcherString(String pattern, boolean update) {
+ namePatternFilter.setPattern(pattern);
+ if (update) {
+ stringMatcherUpdated();
+ }
+ }
+
+ /**
+ * The string matcher has been modified. The default implementation refreshes the view and selects the first matched
+ * element
+ */
+ private void stringMatcherUpdated() {
+ // Refresh the tree viewer to re-filter
+ viewer.getControl().setRedraw(false);
+ viewer.refresh();
+ viewer.expandAll();
+// selectFirstMatch();
+ viewer.getControl().setRedraw(true);
+ }
+
+ protected AbstractTaskEditorPage getTaskEditorPage() {
+ IWorkbenchPage activePage = window.getActivePage();
+ if (activePage == null) {
+ return null;
+ }
+ IEditorPart editorPart = activePage.getActiveEditor();
+ AbstractTaskEditorPage taskEditorPage = null;
+ if (editorPart instanceof TaskEditor) {
+ TaskEditor taskEditor = (TaskEditor) editorPart;
+ IFormPage formPage = taskEditor.getActivePageInstance();
+ if (formPage instanceof AbstractTaskEditorPage) {
+ taskEditorPage = (AbstractTaskEditorPage) formPage;
+ }
+ }
+ return taskEditorPage;
+ }
+
+// /**
+// * Selects the first element in the tree which matches the current filter pattern.
+// */
+// private void selectFirstMatch() {
+// Tree tree = viewer.getTree();
+// Object element = findFirstMatchToPattern(tree.getItems());
+// if (element != null) {
+// viewer.setSelection(new StructuredSelection(element), true);
+// } else {
+// viewer.setSelection(StructuredSelection.EMPTY);
+// }
+// }
+//
+// /**
+// * @param items
+// * @return
+// */
+// private Object findFirstMatchToPattern(TreeItem[] items) {
+// // Match the string pattern against labels
+// ILabelProvider labelProvider = (ILabelProvider) viewer.getLabelProvider();
+// // Process each item in the tree
+// for (TreeItem item : items) {
+// Object element = item.getData();
+// // Return the first element if no pattern is set
+// if (fStringMatcher == null) {
+// return element;
+// }
+// // Return the element if it matches the pattern
+// if (element != null) {
+// String label = labelProvider.getText(element);
+// if (fStringMatcher.match(label)) {
+// return element;
+// }
+// }
+// // Recursively check the elements children for a match
+// element = findFirstMatchToPattern(item.getItems());
+// // Return the child element match if found
+// if (element != null) {
+// return element;
+// }
+// }
+// // No match found
+// return null;
+// }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/QuickOutlineLabelProvider.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/QuickOutlineLabelProvider.java
new file mode 100644
index 000000000..de2d8cdb1
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/QuickOutlineLabelProvider.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Frank Becker 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
+ *
+ * Contributors:
+ * Frank Becker - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.editors.outline;
+
+import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorOutlineNode;
+import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorOutlineNodeLabelProvider;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskAttributeMetaData;
+import org.eclipse.mylyn.tasks.core.data.TaskData;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author Frank Becker
+ */
+public class QuickOutlineLabelProvider extends TaskEditorOutlineNodeLabelProvider {
+
+ @Override
+ public String getText(Object element) {
+ String result = ""; //$NON-NLS-1$
+ if (element instanceof TaskData) {
+ TaskData node = (TaskData) element;
+ result = node.getTaskId();
+ } else if (element instanceof TaskAttribute) {
+ TaskAttribute node = (TaskAttribute) element;
+ TaskAttributeMetaData meta = node.getMetaData();
+ if (meta != null) {
+ String lable = meta.getLabel();
+ if (lable != null) {
+ result = lable + " (" + node.getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ if (TaskAttribute.TYPE_ATTACHMENT.equals(meta.getType())) {
+ result = "Attachment: " + node.getValue(); //$NON-NLS-1$
+ } else if (TaskAttribute.TYPE_COMMENT.equals(meta.getType())) {
+ result = "Comment: " + node.getValue(); //$NON-NLS-1$
+ } else {
+ result = "<" + node.getId() + ">"; //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+ }
+ } else if (element instanceof TaskEditorOutlineNode) {
+ result = super.getText(element);
+ } else if (element instanceof String) {
+ result = (String) element;
+ }
+ return result;
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof TaskEditorOutlineNode) {
+ return super.getImage(element);
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/ShowQuickOutlineHandler.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/ShowQuickOutlineHandler.java
new file mode 100644
index 000000000..c54ea2546
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/ShowQuickOutlineHandler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.tasks.ui.editors.outline;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * @author Steffen Pingel
+ */
+public class ShowQuickOutlineHandler extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
+ QuickOutlineDialog dialog = new QuickOutlineDialog(window);
+ dialog.open();
+ dialog.setFocus();
+ return null;
+ }
+
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/messages.properties b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/messages.properties
new file mode 100644
index 000000000..c6a363b66
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/outline/messages.properties
@@ -0,0 +1 @@
+QuickOutlineDialog_Press_Esc_Info_Text=Press 'Esc' to exit the dialog.
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java
index f08315bab..fffa47edf 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractTaskEditorPage.java
@@ -89,6 +89,7 @@ import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.IRepositoryElement;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState;
+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.data.ITaskDataWorkingCopy;
@@ -97,6 +98,7 @@ import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
import org.eclipse.mylyn.tasks.core.data.TaskDataModelEvent;
import org.eclipse.mylyn.tasks.core.data.TaskDataModelListener;
+import org.eclipse.mylyn.tasks.core.data.TaskRelation;
import org.eclipse.mylyn.tasks.core.sync.SubmitJob;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobEvent;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobListener;
@@ -123,6 +125,7 @@ import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PlatformUI;
@@ -1033,39 +1036,14 @@ public abstract class AbstractTaskEditorPage extends TaskFormPage implements ISe
ISelection selection = event.getSelection();
if (selection instanceof StructuredSelection) {
Object select = ((StructuredSelection) selection).getFirstElement();
- if (select instanceof TaskEditorOutlineNode) {
- TaskEditorOutlineNode node = (TaskEditorOutlineNode) select;
- TaskAttribute attribute = node.getData();
- if (attribute != null) {
- if (TaskAttribute.TYPE_COMMENT.equals(attribute.getMetaData().getType())) {
- AbstractTaskEditorPart actionPart = getPart(ID_PART_COMMENTS);
- if (actionPart != null && actionPart.getControl() instanceof ExpandableComposite) {
- CommonFormUtil.setExpanded((ExpandableComposite) actionPart.getControl(), true);
- if (actionPart.getControl() instanceof Section) {
- Control client = ((Section) actionPart.getControl()).getClient();
- if (client instanceof Composite) {
- for (Control control : ((Composite) client).getChildren()) {
- // toggle subsections
- if (control instanceof Section) {
- CommonFormUtil.setExpanded((Section) control, true);
- }
- }
- }
- }
- }
- }
- EditorUtil.reveal(form, attribute.getId());
- } else {
- EditorUtil.reveal(form, node.getLabel());
- }
- getEditor().setActivePage(getId());
- }
+ selectReveal(select);
+ getEditor().setActivePage(getId());
}
}
});
}
if (getModel() != null) {
- TaskEditorOutlineNode node = TaskEditorOutlineNode.parse(getModel().getTaskData());
+ TaskEditorOutlineNode node = TaskEditorOutlineNode.parse(getModel().getTaskData(), false);
outlinePage.setInput(getTaskRepository(), node);
} else {
outlinePage.setInput(null, null);
@@ -1239,15 +1217,21 @@ public abstract class AbstractTaskEditorPage extends TaskFormPage implements ISe
if (part.getControl() != null) {
if (ID_PART_ACTIONS.equals(part.getPartId())) {
// do not expand horizontally
- GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(false, false).applyTo(
- part.getControl());
+ GridDataFactory.fillDefaults()
+ .align(SWT.FILL, SWT.FILL)
+ .grab(false, false)
+ .applyTo(part.getControl());
} else {
if (part.getExpandVertically()) {
- GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(
- part.getControl());
+ GridDataFactory.fillDefaults()
+ .align(SWT.FILL, SWT.FILL)
+ .grab(true, true)
+ .applyTo(part.getControl());
} else {
- GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).applyTo(
- part.getControl());
+ GridDataFactory.fillDefaults()
+ .align(SWT.FILL, SWT.TOP)
+ .grab(true, false)
+ .applyTo(part.getControl());
}
}
// for outline
@@ -1670,4 +1654,93 @@ public abstract class AbstractTaskEditorPage extends TaskFormPage implements ISe
// }
// }
+ @Override
+ public boolean selectReveal(Object object) {
+ if (object instanceof TaskEditorOutlineNode) {
+ TaskEditorOutlineNode node = (TaskEditorOutlineNode) object;
+ TaskAttribute attribute = node.getData();
+ if (attribute != null) {
+ if (TaskAttribute.TYPE_COMMENT.equals(attribute.getMetaData().getType())) {
+ AbstractTaskEditorPart actionPart = this.getPart(AbstractTaskEditorPage.ID_PART_COMMENTS);
+ if (actionPart != null && actionPart.getControl() instanceof ExpandableComposite) {
+ CommonFormUtil.setExpanded((ExpandableComposite) actionPart.getControl(), true);
+ if (actionPart.getControl() instanceof Section) {
+ Control client = ((Section) actionPart.getControl()).getClient();
+ if (client instanceof Composite) {
+ for (Control control : ((Composite) client).getChildren()) {
+ // toggle subsections
+ if (control instanceof Section) {
+ CommonFormUtil.setExpanded((Section) control, true);
+ }
+ }
+ }
+ }
+ }
+ EditorUtil.reveal(this.getManagedForm().getForm(), attribute.getId());
+ return true;
+ } else if (TaskAttribute.TYPE_ATTACHMENT.equals(attribute.getMetaData().getType())) {
+ AbstractTaskEditorPart actionPart = this.getPart(AbstractTaskEditorPage.ID_PART_ATTACHMENTS);
+ if (actionPart != null && actionPart.getControl() instanceof ExpandableComposite) {
+ CommonFormUtil.setExpanded((ExpandableComposite) actionPart.getControl(), true);
+ if (actionPart.getControl() instanceof Section) {
+ Control client = actionPart.getControl();
+ if (client instanceof Composite) {
+ for (Control control : ((Composite) client).getChildren()) {
+ if (control instanceof Composite) {
+ for (Control control1 : ((Composite) control).getChildren()) {
+ if (control1 instanceof org.eclipse.swt.widgets.Table) {
+ org.eclipse.swt.widgets.Table attachmentTable = ((org.eclipse.swt.widgets.Table) control1);
+ TableItem[] attachments = attachmentTable.getItems();
+ int index = 0;
+ for (TableItem attachment : attachments) {
+ Object data = attachment.getData();
+ if (data instanceof ITaskAttachment) {
+ ITaskAttachment attachmentData = ((ITaskAttachment) data);
+ if (attachmentData.getTaskAttribute() == attribute) {
+ attachmentTable.deselectAll();
+ attachmentTable.select(index);
+ IManagedForm mform = actionPart.getManagedForm();
+ ScrolledForm form = mform.getForm();
+ EditorUtil.focusOn(form, attachmentTable);
+ return true;
+ }
+ }
+ index++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ TaskEditorAttributePart actionPart = (TaskEditorAttributePart) this.getPart(AbstractTaskEditorPage.ID_PART_ATTRIBUTES);
+ Section section = actionPart.getSection();
+ boolean expanded = section.isExpanded();
+ if (!expanded && actionPart != null && actionPart.getControl() instanceof ExpandableComposite) {
+ CommonFormUtil.setExpanded((ExpandableComposite) actionPart.getControl(), true);
+ if (!expanded) {
+ CommonFormUtil.setExpanded((ExpandableComposite) actionPart.getControl(), false);
+ }
+ }
+
+ EditorUtil.reveal(this.getManagedForm().getForm(), attribute.getId());
+ return true;
+ }
+ } else {
+ TaskRelation taskRelation = node.getTaskRelation();
+ TaskRepository taskRepository = node.getTaskRepository();
+ if (taskRelation != null && taskRepository != null) {
+ String taskID = taskRelation.getTaskId();
+ TasksUiUtil.openTask(taskRepository, taskID);
+ } else {
+ EditorUtil.reveal(this.getManagedForm().getForm(), node.getLabel());
+ }
+ return true;
+ }
+ }
+ return super.selectReveal(object);
+ }
+
}

Back to the top