Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.mylyn.tasks.ui')
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/OptionsProposalProvider.java84
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/LabelsAttributeEditor.java88
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TextAttributeEditor.java6
-rw-r--r--org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java37
4 files changed, 206 insertions, 9 deletions
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/OptionsProposalProvider.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/OptionsProposalProvider.java
new file mode 100644
index 000000000..574b26282
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/OptionsProposalProvider.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jface.fieldassist.ContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.mylyn.internal.tasks.ui.editors.LabelsAttributeEditor;
+
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Ordering;
+
+public class OptionsProposalProvider implements IContentProposalProvider {
+
+ private static final String VALUE_SEPARATOR = ","; //$NON-NLS-1$
+
+ private final Set<String> proposals;
+
+ private final boolean isMultiSelect;
+
+ public OptionsProposalProvider(Map<String, String> proposals, boolean isMultiSelect) {
+ this.proposals = proposals.keySet();
+ this.isMultiSelect = isMultiSelect;
+ }
+
+ @Override
+ public IContentProposal[] getProposals(String contents, int position) {
+ Set<String> filteredProposals = new HashSet<>(proposals);
+ filteredProposals.remove(""); //$NON-NLS-1$
+ String lastValue = ""; //$NON-NLS-1$
+ // If the attribute is of type multi-select, filter the past values from the proposals
+ if (isMultiSelect) {
+ String[] contentsArray = contents.split(VALUE_SEPARATOR, -1);
+ if (contentsArray.length > 0) {
+ List<String> trimmedContents = LabelsAttributeEditor.getTrimmedValues(contentsArray);
+ filteredProposals.removeAll(trimmedContents);
+ lastValue = contentsArray[contentsArray.length - 1].trim();
+ }
+ } else {
+ lastValue = contents;
+ }
+
+ // If there is a last value, then filter the remaining the proposals to contain it
+ if (!lastValue.isEmpty()) {
+ for (Iterator<String> iterator = filteredProposals.iterator(); iterator.hasNext();) {
+ String proposal = iterator.next();
+ if (!proposal.toLowerCase().contains(lastValue.toLowerCase())) {
+ iterator.remove();
+ }
+
+ }
+ }
+ // Since the contents of the editor is replaced, we need to include the existing values in the replacement
+ final String existingValues = contents.substring(0, contents.length() - lastValue.length());
+ ImmutableList<String> sortedProposals = FluentIterable.from(filteredProposals).toSortedList(
+ Ordering.from(String.CASE_INSENSITIVE_ORDER));
+ return FluentIterable.from(sortedProposals).transform(new Function<String, IContentProposal>() {
+ public IContentProposal apply(String proposal) {
+ return new ContentProposal(existingValues + proposal, proposal, null);
+ }
+ }).toArray(IContentProposal.class);
+ }
+
+ public boolean isMultiSelect() {
+ return isMultiSelect;
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/LabelsAttributeEditor.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/LabelsAttributeEditor.java
new file mode 100644
index 000000000..d1a58c17a
--- /dev/null
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/LabelsAttributeEditor.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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 java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
+import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
+import org.eclipse.mylyn.tasks.ui.editors.LayoutHint;
+import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan;
+import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.collect.FluentIterable;
+
+public class LabelsAttributeEditor extends TextAttributeEditor {
+
+ private static final String VALUE_SEPARATOR = ","; //$NON-NLS-1$
+
+ private final boolean isMultiSelect;
+
+ public LabelsAttributeEditor(TaskDataModel manager, TaskAttribute taskAttribute) {
+ super(manager, taskAttribute);
+ this.isMultiSelect = TaskAttribute.TYPE_MULTI_SELECT.equals(taskAttribute.getMetaData().getType());
+ if (!isReadOnly() && isMultiSelect) {
+ setLayoutHint(new LayoutHint(RowSpan.MULTIPLE, ColumnSpan.SINGLE));
+ }
+ }
+
+ @Override
+ public void createControl(Composite parent, FormToolkit toolkit) {
+ super.createControl(parent, toolkit, (isMultiSelect ? SWT.WRAP : SWT.NONE));
+ if (!isReadOnly() && isMultiSelect) {
+ getText().setToolTipText("Separate multiple values with a comma"); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public String getValue() {
+ if (isMultiSelect) {
+ List<String> values = getAttributeMapper().getValues(getTaskAttribute());
+ return Joiner.on(VALUE_SEPARATOR + " ").skipNulls().join(values); //$NON-NLS-1$
+ } else {
+ return getAttributeMapper().getValue(getTaskAttribute());
+ }
+ }
+
+ @Override
+ public void setValue(String text) {
+ if (isMultiSelect) {
+ String[] values = text.split(VALUE_SEPARATOR);
+ getAttributeMapper().setValues(getTaskAttribute(), getTrimmedValues(values));
+ } else {
+ getAttributeMapper().setValue(getTaskAttribute(), text);
+ }
+ attributeChanged();
+ }
+
+ public static List<String> getTrimmedValues(String[] values) {
+ return FluentIterable.from(Arrays.asList(values)).transform(new Function<String, String>() {
+ @Override
+ public String apply(String input) {
+ return Strings.nullToEmpty(input).trim();
+ }
+ }).filter(new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return !Strings.isNullOrEmpty(input);
+ }
+ }).toList();
+ }
+}
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TextAttributeEditor.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TextAttributeEditor.java
index 5f4ea1e1d..6f6ed3238 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TextAttributeEditor.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TextAttributeEditor.java
@@ -45,6 +45,10 @@ public class TextAttributeEditor extends AbstractAttributeEditor {
@Override
public void createControl(Composite parent, FormToolkit toolkit) {
+ createControl(parent, toolkit, SWT.NONE);
+ }
+
+ protected void createControl(Composite parent, FormToolkit toolkit, int style) {
if (isReadOnly()) {
text = new Text(parent, SWT.FLAT | SWT.READ_ONLY);
text.setFont(EditorUtil.TEXT_FONT);
@@ -52,7 +56,7 @@ public class TextAttributeEditor extends AbstractAttributeEditor {
text.setToolTipText(getDescription());
text.setText(getValue());
} else {
- text = toolkit.createText(parent, getValue(), SWT.FLAT);
+ text = toolkit.createText(parent, getValue(), SWT.FLAT | style);
text.setFont(EditorUtil.TEXT_FONT);
text.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER);
text.setToolTipText(getDescription());
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java
index 47ac0b39f..b2a14c98a 100644
--- a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java
+++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AttributeEditorToolkit.java
@@ -28,9 +28,11 @@ import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.mylyn.commons.ui.compatibility.CommonThemes;
import org.eclipse.mylyn.commons.workbench.editors.CommonTextSupport;
+import org.eclipse.mylyn.internal.tasks.ui.OptionsProposalProvider;
import org.eclipse.mylyn.internal.tasks.ui.PersonProposalLabelProvider;
import org.eclipse.mylyn.internal.tasks.ui.PersonProposalProvider;
import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil;
+import org.eclipse.mylyn.internal.tasks.ui.editors.LabelsAttributeEditor;
import org.eclipse.mylyn.internal.tasks.ui.editors.Messages;
import org.eclipse.mylyn.internal.tasks.ui.editors.PersonAttributeEditor;
import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTextViewerConfiguration.Mode;
@@ -81,7 +83,16 @@ public class AttributeEditorToolkit {
}
public void adapt(AbstractAttributeEditor editor) {
- if (editor.getControl() instanceof Text || editor.getControl() instanceof CCombo
+ if (editor instanceof LabelsAttributeEditor) {
+ Control control = editor.getControl();
+ IContentProposalProvider contentProposalProvider = createContentProposalProvider(editor);
+ if (contentProposalProvider != null) {
+ ContentAssistCommandAdapter adapter = createContentAssistCommandAdapter(control,
+ contentProposalProvider);
+ adapter.setAutoActivationCharacters(null);
+ adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+ }
+ } else if (editor.getControl() instanceof Text || editor.getControl() instanceof CCombo
|| editor instanceof PersonAttributeEditor) {
Control control = (editor instanceof PersonAttributeEditor)
? ((PersonAttributeEditor) editor).getText()
@@ -91,12 +102,11 @@ public class AttributeEditorToolkit {
control = editor.getControl();
}
if (!editor.isReadOnly() && hasContentAssist(editor.getTaskAttribute())) {
- IContentProposalProvider contentProposalProvider = createContentProposalProvider(editor.getTaskAttribute());
+ IContentProposalProvider contentProposalProvider = createContentProposalProvider(editor);
ILabelProvider labelPropsalProvider = createLabelProposalProvider(editor.getTaskAttribute());
if (contentProposalProvider != null && labelPropsalProvider != null) {
- ContentAssistCommandAdapter adapter = new ContentAssistCommandAdapter(control,
- getContentAdapter(control), contentProposalProvider,
- ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, new char[0], true);
+ ContentAssistCommandAdapter adapter = createContentAssistCommandAdapter(control,
+ contentProposalProvider);
adapter.setLabelProvider(labelPropsalProvider);
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
if (editor instanceof PersonAttributeEditor) {
@@ -127,6 +137,12 @@ public class AttributeEditorToolkit {
editor.decorate(getColorIncoming());
}
+ ContentAssistCommandAdapter createContentAssistCommandAdapter(Control control,
+ IContentProposalProvider proposalProvider) {
+ return new ContentAssistCommandAdapter(control, getContentAdapter(control), proposalProvider,
+ ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, new char[0], true);
+ }
+
private IControlContentAdapter getContentAdapter(Control control) {
if (control instanceof Combo) {
return new ComboContentAdapter();
@@ -171,12 +187,17 @@ public class AttributeEditorToolkit {
/**
* Creates an IContentProposalProvider to provide content assist proposals for the given attribute.
*
- * @param attribute
- * attribute for which to provide content assist.
+ * @param editor
+ * editor for which to provide content assist.
* @return the IContentProposalProvider.
*/
- private IContentProposalProvider createContentProposalProvider(TaskAttribute attribute) {
+ IContentProposalProvider createContentProposalProvider(AbstractAttributeEditor editor) {
+ TaskAttribute attribute = editor.getTaskAttribute();
Map<String, String> proposals = attribute.getTaskData().getAttributeMapper().getOptions(attribute);
+ if (editor instanceof LabelsAttributeEditor) {
+ return new OptionsProposalProvider(proposals,
+ TaskAttribute.TYPE_MULTI_SELECT.equals(attribute.getMetaData().getType()));
+ }
return new PersonProposalProvider(null, attribute.getTaskData(), proposals);
}

Back to the top