Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.mylyn.tasks.index.ui/src/org')
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/AbstractIndexReference.java22
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java4
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposalProvider.java221
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java3
-rw-r--r--org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java158
5 files changed, 250 insertions, 158 deletions
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/AbstractIndexReference.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/AbstractIndexReference.java
new file mode 100644
index 000000000..6e3fc8062
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/AbstractIndexReference.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.index.ui;
+
+import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
+
+/**
+ * @author David Green
+ */
+public abstract class AbstractIndexReference {
+
+ public abstract TaskListIndex index();
+}
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java
index b84387678..daed4fd54 100644
--- a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposal.java
@@ -30,6 +30,10 @@ class ContentProposal implements IContentProposal {
this(content, label, description, content.length());
}
+ public ContentProposal(String content, String contentSuffix, String label, String description) {
+ this(content + contentSuffix, label, description, content.length());
+ }
+
public ContentProposal(String content, String label, String description, int cursorPosition) {
this.content = content;
this.cursorPosition = cursorPosition;
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposalProvider.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposalProvider.java
new file mode 100644
index 000000000..19d004098
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/ContentProposalProvider.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.index.ui;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
+import org.eclipse.mylyn.internal.tasks.core.TaskList;
+import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema;
+import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema.Field;
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A content proposal provider for proposals on a task list index and task list.
+ *
+ * @author David Green
+ */
+public class ContentProposalProvider implements IContentProposalProvider {
+
+ private static final Pattern PATTERN_WHITESPACE = Pattern.compile("\\s"); //$NON-NLS-1$
+
+ private static final Pattern PATTERN_SPECIAL_CHARACTERS = Pattern.compile("([+&\\|!\\(\\)\\{\\}\\[\\]^\"~\\*\\?:\\\\-])"); //$NON-NLS-1$
+
+ private final AbstractIndexReference reference;
+
+ private final TaskList taskList;
+
+ public ContentProposalProvider(TaskList taskList, AbstractIndexReference reference) {
+ this.taskList = taskList;
+ this.reference = reference;
+ }
+
+ public static class ProposalContentState {
+
+ public String beforePrefixContent;
+
+ public String fieldPrefix = ""; //$NON-NLS-1$
+
+ public String prefix = ""; //$NON-NLS-1$
+
+ public String suffix = ""; //$NON-NLS-1$
+
+ public ProposalContentState(String contents) {
+ beforePrefixContent = contents;
+ }
+
+ }
+
+ public IContentProposal[] getProposals(String contents, int position) {
+ List<IContentProposal> proposals = new ArrayList<IContentProposal>(10);
+
+ ProposalContentState contentState = computeProposalContentState(contents, position);
+
+ // if we have a field prefix
+ if (contentState.fieldPrefix.length() > 0) {
+ AbstractTaskSchema.Field indexField = computeIndexField(contentState.fieldPrefix);
+
+ // if it's a person field then suggest
+ // people from the task list
+ if (indexField != null && TaskAttribute.TYPE_PERSON.equals(indexField.getType())) {
+ computePersonProposals(proposals, contentState);
+ }
+
+ } else {
+
+ // suggest field name prefixes
+ for (Field field : reference.index().getIndexedFields()) {
+
+ // searching on URL is not useful
+ if (field.equals(TaskListIndex.FIELD_IDENTIFIER)) {
+ continue;
+ }
+
+ String indexKey = field.getIndexKey();
+ if (indexKey.startsWith(contentState.prefix)) {
+ String description;
+ if (TaskListIndex.FIELD_CONTENT.equals(field)) {
+ description = Messages.IndexSearchHandler_hint_content;
+ } else if (TaskListIndex.FIELD_PERSON.equals(field)) {
+ description = Messages.IndexSearchHandler_hint_person;
+ } else {
+ description = NLS.bind(Messages.IndexSearchHandler_hint_generic, field.getLabel());
+ }
+ proposals.add(new ContentProposal(contentState.beforePrefixContent + indexKey + ":", //$NON-NLS-1$
+ contentState.suffix, indexKey, description));
+
+ if (TaskAttribute.TYPE_DATE.equals(field.getType())
+ || TaskAttribute.TYPE_DATETIME.equals(field.getType())) {
+ computeDateRangeProposals(proposals, contentState, field);
+ }
+ }
+ }
+ }
+
+ return proposals.toArray(new IContentProposal[proposals.size()]);
+ }
+
+ public ProposalContentState computeProposalContentState(String contents, int position) {
+ ProposalContentState contentState = new ProposalContentState(contents);
+
+ if (position >= 0 && position <= contents.length()) {
+ int i = position;
+ while (i > 0 && !Character.isWhitespace(contents.charAt(i - 1)) && contents.charAt(i - 1) != ':') {
+ --i;
+ }
+ if (i > 0 && contents.charAt(i - 1) == ':') {
+ int fieldEnd = i - 1;
+ int fieldStart = i - 1;
+ while (fieldStart > 0 && Character.isLetter(contents.charAt(fieldStart - 1))) {
+ --fieldStart;
+ }
+ contentState.fieldPrefix = contents.substring(fieldStart, fieldEnd);
+ }
+
+ contentState.prefix = contents.substring(i, position);
+ contentState.beforePrefixContent = contents.substring(0, i);
+
+ if (position < contents.length()) {
+ i = position;
+ while (i < contents.length()) {
+ if (Character.isWhitespace(contents.charAt(i))) {
+ break;
+ }
+ ++i;
+ }
+ contentState.suffix = contents.substring(i);
+ }
+ }
+ return contentState;
+ }
+
+ public Field computeIndexField(String fieldPrefix) {
+ for (Field field : reference.index().getIndexedFields()) {
+ if (field.getIndexKey().equals(fieldPrefix)) {
+ return field;
+ }
+ }
+ return null;
+ }
+
+ public void computeDateRangeProposals(List<IContentProposal> proposals, ProposalContentState contentState,
+ Field field) {
+ // for date fields give suggestion of date range search
+ String description;
+ final Date now = new Date();
+ final Date dateSearchUpperBound;
+ final Date dateSearchOneWeekLowerBound;
+ {
+ GregorianCalendar calendar = new GregorianCalendar();
+
+ calendar.setTime(now);
+ calendar.add(Calendar.DAY_OF_WEEK, 1); // one day in future due to GMT conversion in index
+ dateSearchUpperBound = calendar.getTime();
+
+ calendar.setTime(now);
+ calendar.add(Calendar.DAY_OF_WEEK, -7);
+ dateSearchOneWeekLowerBound = calendar.getTime();
+ }
+
+ description = NLS.bind(Messages.IndexSearchHandler_Generic_date_range_search_1_week, field.getLabel());
+
+ String label = NLS.bind(Messages.IndexSearchHandler_Past_week_date_range_label, field.getIndexKey());
+
+ String queryText = reference.index().computeQueryFieldDateRange(field, dateSearchOneWeekLowerBound,
+ dateSearchUpperBound);
+
+ if (queryText.startsWith(contentState.prefix)) {
+ proposals.add(new ContentProposal(contentState.beforePrefixContent + queryText, contentState.suffix, label,
+ description));
+ }
+ }
+
+ public void computePersonProposals(List<IContentProposal> proposals, ProposalContentState contentState) {
+ Set<String> addresses = new TreeSet<String>();
+
+ Collection<AbstractTask> allTasks = taskList.getAllTasks();
+ for (AbstractTask task : allTasks) {
+ addAddresses(addresses, task);
+ }
+
+ for (String address : addresses) {
+ if (address.startsWith(contentState.prefix)) {
+ String proposalContent = address;
+ proposalContent = PATTERN_SPECIAL_CHARACTERS.matcher(proposalContent).replaceAll("\\\\$1"); //$NON-NLS-1$
+ if (PATTERN_WHITESPACE.matcher(proposalContent).find()) {
+ proposalContent = "\"" + proposalContent + "\""; //$NON-NLS-1$//$NON-NLS-2$
+ }
+ proposals.add(new ContentProposal(contentState.beforePrefixContent + proposalContent,
+ contentState.suffix, address, null));
+ }
+ }
+ }
+
+ private void addAddresses(Set<String> addresses, AbstractTask task) {
+ String name = task.getOwner();
+ if (name != null && name.trim().length() > 0) {
+ addresses.add(name.trim());
+ }
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java
index 5181cbf43..bfdc8001e 100644
--- a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexReference.java
@@ -23,7 +23,7 @@ import org.eclipse.mylyn.tasks.core.IRepositoryManager;
* @author David Green
* @author Steffen Pingel
*/
-public class IndexReference {
+public class IndexReference extends AbstractIndexReference {
private static TaskListIndex theIndex;
@@ -49,6 +49,7 @@ public class IndexReference {
*/
private TaskListIndex index;
+ @Override
public TaskListIndex index() {
synchronized (IndexReference.class) {
if (index == null) {
diff --git a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java
index 61beb9d35..0a2dce97c 100644
--- a/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java
+++ b/org.eclipse.mylyn.tasks.index.ui/src/org/eclipse/mylyn/internal/tasks/index/ui/IndexSearchHandler.java
@@ -11,29 +11,15 @@
package org.eclipse.mylyn.internal.tasks.index.ui;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.regex.Pattern;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
-import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.layout.GridLayoutFactory;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.index.core.TaskListIndex;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.search.AbstractSearchHandler;
-import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema.Field;
-import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
-import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
@@ -52,154 +38,12 @@ import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
*/
public class IndexSearchHandler extends AbstractSearchHandler {
- private static final Pattern PATTERN_WHITESPACE = Pattern.compile("\\s"); //$NON-NLS-1$
-
- private static final Pattern PATTERN_SPECIAL_CHARACTERS = Pattern.compile("([+&\\|!\\(\\)\\{\\}\\[\\]^\"~\\*\\?:\\\\-])"); //$NON-NLS-1$
-
- private class ContentProposalProvider implements IContentProposalProvider {
-
- public IContentProposal[] getProposals(String contents, int position) {
- List<IContentProposal> proposals = new ArrayList<IContentProposal>(10);
-
- String beforePrefixContent = contents;
- String fieldPrefix = ""; //$NON-NLS-1$
- String prefix = ""; //$NON-NLS-1$
- if (position >= 0 && position <= contents.length()) {
- int i = position;
- while (i > 0 && !Character.isWhitespace(contents.charAt(i - 1)) && contents.charAt(i - 1) != ':') {
- --i;
- }
- if (i > 0 && contents.charAt(i - 1) == ':') {
- int fieldEnd = i - 1;
- int fieldStart = i - 1;
- while (fieldStart > 0 && Character.isLetter(contents.charAt(fieldStart - 1))) {
- --fieldStart;
- }
- fieldPrefix = contents.substring(fieldStart, fieldEnd);
- }
-
- prefix = contents.substring(i, position);
- beforePrefixContent = contents.substring(0, i);
- }
-
- // if we have a field prefix
- if (fieldPrefix.length() > 0) {
- AbstractTaskSchema.Field indexField = computeIndexField(fieldPrefix);
-
- // if it's a person field then suggest
- // people from the task list
- if (indexField != null && TaskAttribute.TYPE_PERSON.equals(indexField.getType())) {
- computePersonProposals(proposals, beforePrefixContent, prefix);
- }
-
- } else {
-
- // suggest field name prefixes
- for (Field field : reference.index().getIndexedFields()) {
-
- // searching on URL is not useful
- if (field.equals(TaskListIndex.FIELD_IDENTIFIER)) {
- continue;
- }
-
- String indexKey = field.getIndexKey();
- if (indexKey.startsWith(prefix)) {
- String description;
- if (TaskListIndex.FIELD_CONTENT.equals(field)) {
- description = Messages.IndexSearchHandler_hint_content;
- } else if (TaskListIndex.FIELD_PERSON.equals(field)) {
- description = Messages.IndexSearchHandler_hint_person;
- } else {
- description = NLS.bind(Messages.IndexSearchHandler_hint_generic, field.getLabel());
- }
- proposals.add(new ContentProposal(beforePrefixContent + indexKey + ":", //$NON-NLS-1$
- indexKey, description));
-
- if (TaskAttribute.TYPE_DATE.equals(field.getType())
- || TaskAttribute.TYPE_DATETIME.equals(field.getType())) {
- computeDateRangeProposals(proposals, beforePrefixContent, prefix, field);
- }
- }
- }
- }
-
- return proposals.toArray(new IContentProposal[proposals.size()]);
- }
-
- public void computeDateRangeProposals(List<IContentProposal> proposals, String beforePrefixContent,
- String prefix, Field field) {
- // for date fields give suggestion of date range search
- String description;
- final Date now = new Date();
- final Date dateSearchUpperBound;
- final Date dateSearchOneWeekLowerBound;
- {
- GregorianCalendar calendar = new GregorianCalendar();
-
- calendar.setTime(now);
- calendar.add(Calendar.DAY_OF_WEEK, 1); // one day in future due to GMT conversion in index
- dateSearchUpperBound = calendar.getTime();
-
- calendar.setTime(now);
- calendar.add(Calendar.DAY_OF_WEEK, -7);
- dateSearchOneWeekLowerBound = calendar.getTime();
- }
-
- description = NLS.bind(Messages.IndexSearchHandler_Generic_date_range_search_1_week, field.getLabel());
-
- String label = NLS.bind(Messages.IndexSearchHandler_Past_week_date_range_label, field.getIndexKey());
-
- String queryText = reference.index().computeQueryFieldDateRange(field, dateSearchOneWeekLowerBound,
- dateSearchUpperBound);
-
- if (queryText.startsWith(prefix)) {
- proposals.add(new ContentProposal(beforePrefixContent + queryText, label, description));
- }
- }
-
- public void computePersonProposals(List<IContentProposal> proposals, String beforePrefixContent, String prefix) {
- Set<String> addresses = new TreeSet<String>();
-
- Collection<AbstractTask> allTasks = TasksUiPlugin.getTaskList().getAllTasks();
- for (AbstractTask task : allTasks) {
- addAddresses(addresses, task);
- }
-
- for (String address : addresses) {
- if (address.startsWith(prefix)) {
- String proposalContent = address;
- proposalContent = PATTERN_SPECIAL_CHARACTERS.matcher(proposalContent).replaceAll("\\\\$1"); //$NON-NLS-1$
- if (PATTERN_WHITESPACE.matcher(proposalContent).find()) {
- proposalContent = "\"" + proposalContent + "\""; //$NON-NLS-1$//$NON-NLS-2$
- }
- proposals.add(new ContentProposal(beforePrefixContent + proposalContent, address, null));
- }
- }
- }
-
- private void addAddresses(Set<String> addresses, AbstractTask task) {
- String name = task.getOwner();
- if (name != null && name.trim().length() > 0) {
- addresses.add(name.trim());
- }
- }
- }
-
private IndexReference reference;
public IndexSearchHandler() {
reference = new IndexReference();
}
- public Field computeIndexField(String fieldPrefix) {
- for (Field field : reference.index().getIndexedFields()) {
- if (field.getIndexKey().equals(fieldPrefix)) {
- return field;
- }
- }
- return null;
- }
-
@Override
public Composite createSearchComposite(Composite parent) {
Composite container = new Composite(parent, SWT.NULL);
@@ -231,7 +75,7 @@ public class IndexSearchHandler extends AbstractSearchHandler {
@Override
public void adaptTextSearchControl(Text textControl) {
- IContentProposalProvider proposalProvider = new ContentProposalProvider();
+ IContentProposalProvider proposalProvider = new ContentProposalProvider(TasksUiPlugin.getTaskList(), reference);
final ContentAssistCommandAdapter adapter = new ContentAssistCommandAdapter(textControl,
new TextContentAdapter(), proposalProvider, null, new char[0], true);
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);

Back to the top