]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
StringChooser for selecting objects with labels.
authorluukkainen <luukkainen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Fri, 18 Jan 2013 11:18:04 +0000 (11:18 +0000)
committerluukkainen <luukkainen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Fri, 18 Jan 2013 11:18:04 +0000 (11:18 +0000)
Replaced TrackedText with StingChooser in Bar/PiePropertyComposite2.

refs #3988
fixes #3996

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@26647 ac1ea38d-2e2b-0410-8846-a27921b304fc

13 files changed:
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariable.java
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableFactory.java [new file with mode: 0644]
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableModifier.java [moved from org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableModifier.java with 66% similarity]
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/IdLabelProposalProvider.java [deleted file]
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RVIModifier.java
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooser.java [new file with mode: 0644]
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyEvent.java [new file with mode: 0644]
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListener.java [new file with mode: 0644]
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListenerImpl.java [new file with mode: 0644]
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableFactory.java [deleted file]
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableProposalProvider.java
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesPropertyComposite2.java
org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesPropertyComposite2.java

index 994e7462f98017f94bb7b6361ba3c256817d6e1c..1498b47afa4b4ca6cb924de47f91f013ca9ba467 100644 (file)
@@ -29,17 +29,17 @@ public class ChartVariable {
                return rvi;\r
        }\r
        \r
-//     @Override\r
-//     public int hashCode() {\r
-//             return rvi.hashCode();\r
-//     }\r
-//     \r
-//     @Override\r
-//     public boolean equals(Object obj) {\r
-//             if (obj.getClass() != getClass())\r
-//                     return false;\r
-//             ChartVariable other = (ChartVariable)obj;\r
-//             return rvi.equals(other.rvi);\r
-//     }\r
+       @Override\r
+       public int hashCode() {\r
+               return rvi.hashCode();\r
+       }\r
+       \r
+       @Override\r
+       public boolean equals(Object obj) {\r
+               if (obj.getClass() != getClass())\r
+                       return false;\r
+               ChartVariable other = (ChartVariable)obj;\r
+               return rvi.equals(other.rvi);\r
+       }\r
 \r
 }\r
diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableFactory.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableFactory.java
new file mode 100644 (file)
index 0000000..fea5415
--- /dev/null
@@ -0,0 +1,34 @@
+package org.simantics.jfreechart.chart.properties;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+\r
+public class ChartVariableFactory extends ReadFactoryImpl<Resource, ChartVariable>{\r
+       \r
+       private Map<String,ChartVariable> map;\r
+       \r
+       public ChartVariableFactory(Collection<ChartVariable> data) {\r
+               map = new HashMap<String, ChartVariable>();\r
+               for (ChartVariable v : data) {\r
+                       map.put(v.getRvi(), v);\r
+               }\r
+       }\r
+       \r
+       @Override\r
+       public ChartVariable perform(ReadGraph graph, Resource input)\r
+                       throws DatabaseException {\r
+                String rvi = graph.getPossibleRelatedValue(input, JFreeChartResource.getInstance(graph).variableRVI);\r
+                if (rvi == null)\r
+                        return null;\r
+                return map.get(rvi);\r
+               \r
+       }\r
+\r
+}\r
similarity index 66%
rename from org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableModifier.java
rename to org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableModifier.java
index 84de0b05b0cd1d4c2ccdd62e9116642d720f8f36..a1e13dd05da9cdba100275435399f50e7ef7e5e9 100644 (file)
@@ -8,8 +8,6 @@ import org.eclipse.jface.fieldassist.IContentProposalListener;
 import org.eclipse.jface.fieldassist.IContentProposalListener2;\r
 import org.eclipse.jface.fieldassist.TextContentAdapter;\r
 import org.eclipse.swt.widgets.Control;\r
-import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
-import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent;\r
 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.Resource;\r
@@ -17,7 +15,7 @@ import org.simantics.db.WriteGraph;
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.sysdyn.JFreeChartResource;\r
 \r
-public class VariableModifier extends TextModifyListenerImpl<Resource> {\r
+public class ChartVariableModifier extends StringChooserModifyListenerImpl<Resource, ChartVariable> {\r
        \r
         private boolean active;\r
         private Control control;\r
@@ -27,7 +25,7 @@ public class VariableModifier extends TextModifyListenerImpl<Resource> {
                        'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö',\r
                        '1','2','3','4','5','6','7','8','9','0','.','_'};\r
         \r
-        public VariableModifier(Control control, WidgetSupport support) {\r
+        public ChartVariableModifier(Control control, WidgetSupport support) {\r
                this.control = control;\r
                this.active = true;\r
                \r
@@ -39,7 +37,7 @@ public class VariableModifier extends TextModifyListenerImpl<Resource> {
                }\r
                \r
                //SimpleContentProposalProvider scpp = new VariableProposalProvider(control, support);\r
-               IdLabelProposalProvider scpp = new VariableProposalProvider(control, support);\r
+               VariableProposalProvider scpp = new VariableProposalProvider(control, support);\r
                scpp.setFiltering(true);\r
 \r
                ContentProposalAdapter adapter = new ContentProposalAdapter(\r
@@ -50,14 +48,14 @@ public class VariableModifier extends TextModifyListenerImpl<Resource> {
 \r
                    @Override\r
                    public void proposalPopupOpened(ContentProposalAdapter adapter) {\r
-                       if(VariableModifier.this != null)\r
-                               VariableModifier.this.deactivate();\r
+                       if(ChartVariableModifier.this != null)\r
+                               ChartVariableModifier.this.deactivate();\r
                    }\r
 \r
                    @Override\r
                    public void proposalPopupClosed(ContentProposalAdapter adapter) {\r
-                       if(VariableModifier.this != null)\r
-                               VariableModifier.this.activate();\r
+                       if(ChartVariableModifier.this != null)\r
+                               ChartVariableModifier.this.activate();\r
                    }\r
                });\r
 \r
@@ -66,30 +64,32 @@ public class VariableModifier extends TextModifyListenerImpl<Resource> {
                        \r
                    @Override\r
                    public void proposalAccepted(IContentProposal proposal) {\r
-                       if(VariableModifier.this.control != null && !VariableModifier.this.control.isDisposed())\r
-                               VariableModifier.this.modifyText(new TrackedModifyEvent(VariableModifier.this.control, proposal.getLabel()));\r
+                       if(ChartVariableModifier.this.control != null && !ChartVariableModifier.this.control.isDisposed())\r
+                               ChartVariableModifier.this.modifySelection(new StringChooserModifyEvent<ChartVariable>(ChartVariableModifier.this.control, new ChartVariable(proposal.getContent(), proposal.getLabel()), proposal.getLabel()));\r
                    }\r
                });\r
            \r
            \r
            }\r
-           \r
-\r
-           @Override\r
-           public void applyText(WriteGraph graph, Resource resource, String text) throws DatabaseException {\r
-               if(active) {\r
+        \r
+        @Override\r
+       public void applyObject(WriteGraph graph, Resource resource, ChartVariable object, String text) throws DatabaseException {\r
+                   if(active) {\r
                    JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
-                   graph.claimLiteral(resource, jfree.variableRVI, text, Bindings.STRING);\r
+                   graph.claimLiteral(resource, jfree.variableRVI, object.getRvi(), Bindings.STRING);\r
                    graph.deny(resource, jfree.variableFilter);\r
                }\r
-           }\r
+               \r
+       }\r
+           \r
 \r
-           public void deactivate() {\r
-               active = false;\r
-           }\r
 \r
-           public void activate() {\r
-               active = true;\r
-           }    \r
+    public void deactivate() {\r
+        active = false;\r
+    }\r
+\r
+    public void activate() {\r
+        active = true;\r
+    }   \r
 \r
 }\r
diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/IdLabelProposalProvider.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/IdLabelProposalProvider.java
deleted file mode 100644 (file)
index f643e70..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.simantics.jfreechart.chart.properties;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Iterator;\r
-\r
-import org.eclipse.jface.fieldassist.ContentProposal;\r
-import org.eclipse.jface.fieldassist.IContentProposal;\r
-import org.eclipse.jface.fieldassist.IContentProposalProvider;\r
-import org.simantics.utils.datastructures.Pair;\r
-\r
-public class IdLabelProposalProvider implements IContentProposalProvider{\r
-\r
-       /*\r
-        * The proposals provided.\r
-        */\r
-       private Collection<ChartVariable> proposals;\r
-\r
-       /*\r
-        * The proposals mapped to IContentProposal. Cached for speed in the case\r
-        * where filtering is not used.\r
-        */\r
-       private IContentProposal[] contentProposals;\r
-\r
-       /*\r
-        * Boolean that tracks whether filtering is used.\r
-        */\r
-       private boolean filterProposals = false;\r
-\r
-       /**\r
-        * Construct a SimpleContentProposalProvider whose content proposals are\r
-        * always the specified array of Objects.\r
-        * \r
-        * @param proposals\r
-        *            the array of Strings to be returned whenever proposals are\r
-        *            requested.\r
-        */\r
-       public IdLabelProposalProvider(Collection<ChartVariable> proposals) {\r
-               super();\r
-               this.proposals = proposals;\r
-       }\r
-\r
-       /**\r
-        * Return an array of Objects representing the valid content proposals for a\r
-        * field. \r
-        * \r
-        * @param contents\r
-        *            the current contents of the field (only consulted if filtering\r
-        *            is set to <code>true</code>)\r
-        * @param position\r
-        *            the current cursor position within the field (ignored)\r
-        * @return the array of Objects that represent valid proposals for the field\r
-        *         given its current content.\r
-        */\r
-       @SuppressWarnings("unchecked")\r
-       public IContentProposal[] getProposals(String contents, int position) {\r
-               if (filterProposals) {\r
-                       ArrayList list = new ArrayList();\r
-                       for (ChartVariable proposal : proposals) {\r
-                               if (proposal.getRvi().length() >= contents.length() && proposal.getRvi().substring(0, contents.length()).equalsIgnoreCase(contents)) {\r
-                                       if (proposal.getLabel() != null)\r
-                                               list.add(new ContentProposal(proposal.getRvi(),proposal.getLabel(), null));\r
-                                       else\r
-                                               list.add(new ContentProposal(proposal.getRvi()));\r
-                               } else if (proposal.getLabel() != null && proposal.getLabel().length() >= contents.length() && proposal.getLabel().substring(0, contents.length()).equalsIgnoreCase(contents)) {\r
-                                       list.add(new ContentProposal(proposal.getRvi(),proposal.getLabel(), null));\r
-                               }\r
-                       }\r
-                       \r
-                       return (IContentProposal[]) list.toArray(new IContentProposal[list\r
-                                       .size()]);\r
-               }\r
-               if (contentProposals == null) {\r
-                       contentProposals = new IContentProposal[proposals.size()];\r
-                       Iterator<ChartVariable> iter = proposals.iterator();\r
-                       for (int i = 0; i < proposals.size(); i++) {\r
-                               ChartVariable proposal = iter.next();\r
-                               if (proposal.getLabel() != null)\r
-                                       contentProposals[i] = new ContentProposal(proposal.getRvi(),proposal.getLabel(),null);\r
-                               else\r
-                                       contentProposals[i] = new ContentProposal(proposal.getRvi());\r
-                       }\r
-               }\r
-               return contentProposals;\r
-       }\r
-\r
-       /**\r
-        * Set the Strings to be used as content proposals.\r
-        * \r
-        * @param items\r
-        *            the array of Strings to be used as proposals.\r
-        */\r
-       public void setProposals(Collection<ChartVariable> items) {\r
-               this.proposals = items;\r
-               contentProposals = null;\r
-       }\r
-\r
-       /**\r
-        * Set the boolean that controls whether proposals are filtered according to\r
-        * the current field content.\r
-        * \r
-        * @param filterProposals\r
-        *            <code>true</code> if the proposals should be filtered to\r
-        *            show only those that match the current contents of the field,\r
-        *            and <code>false</code> if the proposals should remain the\r
-        *            same, ignoring the field content.\r
-        * @since 3.3\r
-        */\r
-       public void setFiltering(boolean filterProposals) {\r
-               this.filterProposals = filterProposals;\r
-               // Clear any cached proposals.\r
-               contentProposals = null;\r
-       }\r
-}\r
index b9359e0d2105732d916bf9b3edfc83cdec17c472..81edb2b974e395d54750d01b68702be64803d2b9 100644 (file)
@@ -17,7 +17,6 @@ import org.eclipse.jface.fieldassist.ContentProposalAdapter;
 import org.eclipse.jface.fieldassist.IContentProposal;\r
 import org.eclipse.jface.fieldassist.IContentProposalListener;\r
 import org.eclipse.jface.fieldassist.IContentProposalListener2;\r
-import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;\r
 import org.eclipse.jface.fieldassist.TextContentAdapter;\r
 import org.eclipse.swt.widgets.Control;\r
 import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
@@ -63,7 +62,7 @@ public class RVIModifier extends TextModifyListenerImpl<Resource> {
         }\r
         \r
         //SimpleContentProposalProvider scpp = new VariableProposalProvider(control, support);\r
-        IdLabelProposalProvider scpp = new VariableProposalProvider(control, support);\r
+        VariableProposalProvider scpp = new VariableProposalProvider(control, support);\r
         scpp.setFiltering(true);\r
 \r
         ContentProposalAdapter adapter = new ContentProposalAdapter(\r
diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooser.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooser.java
new file mode 100644 (file)
index 0000000..892e998
--- /dev/null
@@ -0,0 +1,590 @@
+package org.simantics.jfreechart.chart.properties;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.runtime.Assert;\r
+import org.eclipse.core.runtime.ListenerList;\r
+import org.eclipse.jface.dialogs.IInputValidator;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.jface.resource.ResourceManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.events.MouseListener;\r
+import org.eclipse.swt.events.MouseTrackListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.browsing.ui.swt.widgets.DefaultColorProvider;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ITrackedColorProvider;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactory;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.Listener;\r
+\r
+/**\r
+ * Widget for choosing and labeled object from a set of objects.\r
+ * \r
+ * Supports cases when multiple objects have the same label (as much as possible)\r
+ * \r
+ * \r
+ * Based on org.simantics.browsing.ui.swt.widgets.Trackedtext\r
+ * \r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class StringChooser<T> implements Widget{\r
+    private static final int      EDITING                 = 1 << 0;\r
+    private static final int      MODIFIED_DURING_EDITING = 1 << 1;\r
+\r
+    /**\r
+     * Used to tell whether or not a mouseDown has occurred after a focusGained\r
+     * event to be able to select the whole text field when it is pressed for\r
+     * the first time while the widget holds focus.\r
+     */\r
+    private static final int      MOUSE_DOWN_FIRST_TIME   = 1 << 2;\r
+    private static final int      MOUSE_INSIDE_CONTROL    = 1 << 3;\r
+    \r
+    private int                   caretPositionBeforeEdit;\r
+    \r
+    private String                textBeforeEdit;\r
+\r
+    private int                   state;\r
+\r
+       private Map<T,String> objectToLabel;\r
+       private Set<String> allowedLabels;\r
+       \r
+       private T selected;\r
+       \r
+    private final Display         display;\r
+\r
+    private final Text            text;\r
+    \r
+    private CompositeListener     listener;\r
+\r
+    private ListenerList          modifyListeners;\r
+\r
+    private ReadFactory<?, T>     objectFactory;\r
+    \r
+    private ITrackedColorProvider colorProvider;\r
+\r
+    private final ResourceManager resourceManager;\r
+    \r
+       private boolean moveCaretAfterEdit = true;\r
+       \r
+       private boolean selectAllOnStartEdit = true;\r
+       \r
+       public StringChooser(Composite parent, WidgetSupport support, int style) {\r
+               this.state = 0;\r
+        this.text = new Text(parent, style);\r
+        this.display = text.getDisplay();\r
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), text);\r
+        this.colorProvider = new DefaultColorProvider(resourceManager);\r
+        if (support!=null) support.register(this);\r
+        initialize();\r
+       }\r
+       \r
+\r
+       \r
+       public ResourceManager getResourceManager() {\r
+       return resourceManager;\r
+    }\r
+       \r
+       public void setFont(Font font) {\r
+               text.setFont(font);\r
+       }\r
+       \r
+       public void setObjectFactory(ReadFactory<?, T> objectFactory) {\r
+               this.objectFactory = objectFactory;\r
+       }\r
+       \r
+       public void setMoveCaretAfterEdit(boolean value) {\r
+               this.moveCaretAfterEdit = value;\r
+       }\r
+       \r
+       public void setData(Map<T,String> data) {\r
+               this.objectToLabel = data;\r
+               this.allowedLabels = new HashSet<String>();\r
+               this.allowedLabels.addAll(objectToLabel.values());\r
+       }\r
+       \r
+       public void setData(Collection<T> data) {\r
+               this.objectToLabel = new HashMap<T, String>();\r
+               this.allowedLabels = new HashSet<String>();\r
+               for (T t : data) {\r
+                       String label = t.toString();\r
+                       objectToLabel.put(t, label);\r
+                       allowedLabels.add(label);\r
+               }\r
+       }\r
+       \r
+       public void setSelected(T selected) {\r
+               if (selected != null) {\r
+                       String label = objectToLabel.get(selected);\r
+                       if (label == null)\r
+                               return;\r
+                       this.selected = selected;\r
+                       this.text.setText(label);\r
+               } else {\r
+                       this.selected = null;\r
+                       this.text.setText("");\r
+               }\r
+       }\r
+       \r
+       public void setSelected(String label) {\r
+               // TODO : we could create a label to object map.\r
+               for (T t : objectToLabel.keySet()) {\r
+                       if (label.equals(objectToLabel.get(t))) {\r
+                               setSelected(t);\r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       \r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+        if (modifyListeners != null) {\r
+            for (Object o : modifyListeners.getListeners()) {\r
+               if(o instanceof Widget) {\r
+                    ((Widget) o).setInput(context, input);\r
+               }\r
+            }\r
+        }\r
+               \r
+               if(objectFactory != null) {\r
+                       objectFactory.listen(context, input, new Listener<T>() {\r
+\r
+                               @Override\r
+                public void exception(final Throwable t) {\r
+                                       display.asyncExec(new Runnable() {\r
+\r
+                                               @Override\r
+                                               public void run() {\r
+                                                       if(isDisposed()) return;\r
+//                                                     System.out.println("Button received new text: " + text);\r
+                                                       text.setText(t.toString());\r
+                                               }\r
+\r
+                                       });\r
+                               }\r
+\r
+                               @Override\r
+                               public void execute(final T object) {\r
+                                       \r
+                                       if(text.isDisposed()) return;\r
+                                       \r
+                                       display.asyncExec(new Runnable() {\r
+\r
+                                               @Override\r
+                                               public void run() {\r
+                                                       if(isDisposed()) return;\r
+                                                       setSelected(object);\r
+//                                                     text.getParent().layout();\r
+//                                                     text.getParent().getParent().layout();\r
+                                               }\r
+\r
+                                       });\r
+                               }\r
+\r
+                               @Override\r
+                               public boolean isDisposed() {\r
+                                       return text.isDisposed();\r
+                               }\r
+\r
+                       });\r
+               }\r
+               \r
+       }\r
+       \r
+       /**\r
+     * Common initialization. Assumes that text is already created.\r
+     */\r
+    private void initialize() {\r
+        Assert.isNotNull(text);\r
+\r
+        text.setBackground(colorProvider.getInactiveBackground());\r
+        text.setDoubleClickEnabled(false);\r
+\r
+        listener = new CompositeListener();\r
+\r
+        text.addModifyListener(listener);\r
+        text.addDisposeListener(listener);\r
+        text.addKeyListener(listener);\r
+        text.addMouseTrackListener(listener);\r
+        text.addMouseListener(listener);\r
+        text.addFocusListener(listener);\r
+    }\r
+    \r
+    public void startEdit(boolean selectAll) {\r
+        if (isEditing()) {\r
+            // Print some debug incase we end are in an invalid state\r
+            System.out.println("TrackedText: BUG: startEdit called when in editing state");\r
+        }\r
+//        System.out.println("start edit: selectall=" + selectAll + ", text=" + text.getText() + ", caretpos=" + caretPositionBeforeEdit);\r
+\r
+        // Backup text-field data for reverting purposes\r
+        caretPositionBeforeEdit = text.getCaretPosition();\r
+        textBeforeEdit = text.getText();\r
+\r
+        // Signal editing state\r
+        setBackground(colorProvider.getEditingBackground());\r
+\r
+        if (selectAll) {\r
+            text.selectAll();\r
+        }\r
+        state |= EDITING | MOUSE_DOWN_FIRST_TIME;\r
+    }\r
+\r
+    private void applyEdit() {\r
+        try {\r
+            if (isTextValid() != null) {\r
+                text.setText(textBeforeEdit);\r
+            } else if (isModified() && !text.getText().equals(textBeforeEdit)) {\r
+               setSelected(text.getText());\r
+                //System.out.println("apply");\r
+                if (modifyListeners != null) {\r
+                    StringChooserModifyEvent event = new StringChooserModifyEvent(text, selected, text.getText());\r
+                    for (Object o : modifyListeners.getListeners()) {\r
+                        ((StringChooserModifyListener) o).modifySelection(event);\r
+                    }\r
+                }\r
+            }\r
+        } catch (Throwable t) {\r
+            t.printStackTrace();\r
+        } finally {\r
+            endEdit();\r
+        }\r
+    }\r
+\r
+    private void endEdit() {\r
+        if (text.isDisposed())\r
+            return;\r
+\r
+        if (!isEditing()) {\r
+            // Print some debug incase we end are in an invalid state\r
+            //ExceptionUtils.logError(new Exception("BUG: endEdit called when not in editing state"));\r
+            //System.out.println();\r
+        }\r
+        setBackground(isMouseInsideControl() ? colorProvider.getHoverBackground() : colorProvider.getInactiveBackground());\r
+//        System.out.println("endEdit: " + text.getText() + ", caret: " + text.getCaretLocation() + ", selection: " + text.getSelection());\r
+        // Always move the caret to the end of the string\r
+        if(moveCaretAfterEdit)\r
+            text.setSelection(text.getCharCount());\r
+        state &= ~(EDITING | MOUSE_DOWN_FIRST_TIME);\r
+        setModified(false);\r
+    }\r
+\r
+    private void revertEdit() {\r
+        if (!isEditing()) {\r
+            // Print some debug incase we end are in an invalid state\r
+            //ExceptionUtils.logError(new Exception("BUG: revertEdit called when not in editing state"));\r
+            System.out.println("BUG: revertEdit called when not in editing state");\r
+        }\r
+        text.setText(textBeforeEdit);\r
+        text.setSelection(caretPositionBeforeEdit);\r
+        setBackground(isMouseInsideControl() ? colorProvider.getHoverBackground() : colorProvider.getInactiveBackground());\r
+        state &= ~(EDITING | MOUSE_DOWN_FIRST_TIME);\r
+        setModified(false);\r
+    }\r
+\r
+    private boolean isEditing() {\r
+        return (state & EDITING) != 0;\r
+    }\r
+\r
+    private void setModified(boolean modified) {\r
+        if (modified) {\r
+            state |= MODIFIED_DURING_EDITING;\r
+        } else {\r
+            state &= ~MODIFIED_DURING_EDITING;\r
+        }\r
+    }\r
+\r
+    private boolean isMouseInsideControl() {\r
+        return (state & MOUSE_INSIDE_CONTROL) != 0;\r
+    }\r
+\r
+    private void setMouseInsideControl(boolean inside) {\r
+        if (inside)\r
+            state |= MOUSE_INSIDE_CONTROL;\r
+        else\r
+            state &= ~MOUSE_INSIDE_CONTROL;\r
+    }\r
+\r
+    private boolean isModified() {\r
+        return (state & MODIFIED_DURING_EDITING) != 0;\r
+    }\r
+\r
+    public void setSelectAllOnStartEdit(boolean selectAll) {\r
+        this.selectAllOnStartEdit = selectAll;\r
+    }\r
+    \r
+    public void setEditable(boolean editable) {\r
+        if (editable) {\r
+            text.setEditable(true);\r
+            setBackground(isMouseInsideControl() ? colorProvider.getHoverBackground() : colorProvider.getInactiveBackground());\r
+        } else {\r
+            text.setEditable(false);\r
+            text.setBackground(null);\r
+        }\r
+    }\r
+\r
+    public void setText(String text) {\r
+        this.text.setText(text);\r
+    }\r
+\r
+    public void setTextWithoutNotify(String text) {\r
+        this.text.removeModifyListener(listener);\r
+        setText(text);\r
+        this.text.addModifyListener(listener);\r
+    }\r
+\r
+    public Text getWidget() {\r
+        return text;\r
+    }\r
+\r
+    public synchronized void addModifyListener(StringChooserModifyListener listener) {\r
+        if (modifyListeners == null) {\r
+            modifyListeners = new ListenerList(ListenerList.IDENTITY);\r
+        }\r
+        modifyListeners.add(listener);\r
+    }\r
+\r
+    public synchronized void removeModifyListener(StringChooserModifyListener listener) {\r
+        if (modifyListeners == null)\r
+            return;\r
+        modifyListeners.remove(listener);\r
+    }\r
+\r
+  \r
+\r
+    private String isTextValid() {\r
+        if (allowedLabels.contains(getWidget().getText()))\r
+               return null;\r
+        return "There is no such object.";\r
+    }\r
+\r
+    public void setColorProvider(ITrackedColorProvider provider) {\r
+        Assert.isNotNull(provider);\r
+        this.colorProvider = provider;\r
+    }\r
+\r
+    private void setBackground(Color background) {\r
+       if(text.isDisposed()) return;\r
+        if (!text.getEditable()) {\r
+            // Do not alter background when the widget is not editable.\r
+            return;\r
+        }\r
+        text.setBackground(background);\r
+    }\r
+    \r
+    public boolean isDisposed() {\r
+       return text.isDisposed();\r
+    }\r
+    \r
+    public Display getDisplay() {\r
+       return display;\r
+    }\r
+    \r
+    public String getText() {\r
+               return text.getText();\r
+       }\r
+    \r
+    public int getCaretPosition() {\r
+       return text.getCaretPosition();\r
+    }\r
+       \r
+       \r
+    /**\r
+     * A composite of many UI listeners for creating the functionality of this\r
+     * class.\r
+     */\r
+    private class CompositeListener\r
+    implements ModifyListener, DisposeListener, KeyListener, MouseTrackListener,\r
+    MouseListener, FocusListener\r
+    {\r
+        // Keyboard/editing events come in the following order:\r
+        //   1. keyPressed\r
+        //   2. verifyText\r
+        //   3. modifyText\r
+        //   4. keyReleased\r
+\r
+        @Override\r
+        public void modifyText(ModifyEvent e) {\r
+            //System.out.println("modifyText: " + e);\r
+            setModified(true);\r
+\r
+            String valid = isTextValid();\r
+            if (valid != null) {\r
+                setBackground(colorProvider.getInvalidBackground());\r
+            } else {\r
+                if (isEditing())\r
+                    setBackground(colorProvider.getEditingBackground());\r
+                else\r
+                    setBackground(colorProvider.getInactiveBackground());\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void widgetDisposed(DisposeEvent e) {\r
+            getWidget().removeModifyListener(this);\r
+        }\r
+\r
+        private boolean isMultiLine() {\r
+            return (text.getStyle() & SWT.MULTI) != 0;\r
+        }\r
+\r
+        private boolean hasMultiLineCommitModifier(KeyEvent e) {\r
+            return (e.stateMask & SWT.CTRL) != 0;\r
+        }\r
+\r
+        @Override\r
+        public void keyPressed(KeyEvent e) {\r
+            //System.out.println("keyPressed: " + e);\r
+            if (!isEditing()) {\r
+                // ESC, ENTER & keypad ENTER must not start editing\r
+                if (e.keyCode == SWT.ESC)\r
+                    return;\r
+\r
+                if (!isMultiLine()) {\r
+                    if (e.keyCode == SWT.F2 || e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {\r
+                        startEdit(selectAllOnStartEdit);\r
+                    } else if (e.character != '\0') {\r
+                        startEdit(false);\r
+                    }\r
+                } else {\r
+                    // In multi-line mode, TAB must not start editing!\r
+                    if (e.keyCode == SWT.F2) {\r
+                        startEdit(selectAllOnStartEdit);\r
+                    } else if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {\r
+                        if (hasMultiLineCommitModifier(e)) {\r
+                            e.doit = false;\r
+                        } else {\r
+                            startEdit(false);\r
+                        }\r
+                    } else if (e.keyCode == SWT.TAB) {\r
+                        text.traverse(((e.stateMask & SWT.SHIFT) != 0) ? SWT.TRAVERSE_TAB_PREVIOUS : SWT.TRAVERSE_TAB_NEXT);\r
+                        e.doit = false;\r
+                    } else if (e.character != '\0') {\r
+                        startEdit(false);\r
+                    }\r
+                }\r
+            } else {\r
+                // ESC reverts any changes made during this edit\r
+                if (e.keyCode == SWT.ESC) {\r
+                    revertEdit();\r
+                }\r
+                if (!isMultiLine()) {\r
+                    if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {\r
+                        applyEdit();\r
+                    }\r
+                } else {\r
+                    if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {\r
+                        if (hasMultiLineCommitModifier(e)) {\r
+                            applyEdit();\r
+                            e.doit = false;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void keyReleased(KeyEvent e) {\r
+            //System.out.println("keyReleased: " + e);\r
+        }\r
+\r
+        @Override\r
+        public void mouseEnter(MouseEvent e) {\r
+            //System.out.println("mouseEnter");\r
+            if (!isEditing()) {\r
+                setBackground(colorProvider.getHoverBackground());\r
+            }\r
+            setMouseInsideControl(true);\r
+        }\r
+\r
+        @Override\r
+        public void mouseExit(MouseEvent e) {\r
+            //System.out.println("mouseExit");\r
+            if (!isEditing()) {\r
+                setBackground(colorProvider.getInactiveBackground());\r
+            }\r
+            setMouseInsideControl(false);\r
+        }\r
+\r
+        @Override\r
+        public void mouseHover(MouseEvent e) {\r
+            //System.out.println("mouseHover");\r
+            setMouseInsideControl(true);\r
+        }\r
+\r
+        @Override\r
+        public void mouseDoubleClick(MouseEvent e) {\r
+            //System.out.println("mouseDoubleClick: " + e);\r
+            if (e.button == 1) {\r
+                getWidget().selectAll();\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void mouseDown(MouseEvent e) {\r
+            //System.out.println("mouseDown: " + e);\r
+            if (!isEditing()) {\r
+                // In reality we should never get here, since focusGained\r
+                // always comes before mouseDown, but let's keep this\r
+                // fallback just to be safe.\r
+                if (e.button == 1) {\r
+                    startEdit(selectAllOnStartEdit);\r
+                }\r
+            } else {\r
+                if (e.button == 1 && (state & MOUSE_DOWN_FIRST_TIME) != 0) {\r
+                    if (!isMultiLine()) {\r
+                        // This is useless for multi-line texts\r
+                        getWidget().selectAll();\r
+                    }\r
+                    state &= ~MOUSE_DOWN_FIRST_TIME;\r
+                }\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void mouseUp(MouseEvent e) {\r
+        }\r
+\r
+        @Override\r
+        public void focusGained(FocusEvent e) {\r
+            //System.out.println("focusGained");\r
+            if (!isEditing()) {\r
+                if (!isMultiLine()) {\r
+                    // Always start edit on single line texts when focus is gained\r
+                    startEdit(selectAllOnStartEdit);\r
+                }\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void focusLost(FocusEvent e) {\r
+            //System.out.println("focusLost");\r
+            if (isEditing()) {\r
+                applyEdit();\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyEvent.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyEvent.java
new file mode 100644 (file)
index 0000000..c491665
--- /dev/null
@@ -0,0 +1,32 @@
+package org.simantics.jfreechart.chart.properties;\r
+\r
+import java.util.EventObject;\r
+\r
+import org.eclipse.swt.widgets.Widget;\r
+\r
+public class StringChooserModifyEvent<T>  extends EventObject {\r
+\r
+       private static final long serialVersionUID = 2630732165074702762L;\r
+       \r
+       private T object;\r
+       private String text;\r
+        \r
+       public StringChooserModifyEvent(Widget source, T object, String text) {\r
+                super(source);\r
+                this.object = object;\r
+                this.text = text;\r
+       }\r
+        \r
+       public Widget getWidget() {\r
+               return (Widget) getSource();\r
+       }\r
+       \r
+       public T getObject() {\r
+               return object;\r
+       }\r
+\r
+       public String getText() {\r
+               return text;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListener.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListener.java
new file mode 100644 (file)
index 0000000..b975640
--- /dev/null
@@ -0,0 +1,7 @@
+package org.simantics.jfreechart.chart.properties;\r
+\r
+public interface StringChooserModifyListener<T> {\r
+\r
+       \r
+       void modifySelection(StringChooserModifyEvent<T> e);\r
+}\r
diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListenerImpl.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListenerImpl.java
new file mode 100644 (file)
index 0000000..8fa748d
--- /dev/null
@@ -0,0 +1,71 @@
+package org.simantics.jfreechart.chart.properties;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.utils.ReflectionUtils;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public abstract class StringChooserModifyListenerImpl<T,T2> implements StringChooserModifyListener<T2>, Widget {\r
+       protected ISessionContext context;\r
+       protected T lastInput = null;\r
+\r
+       protected final Class<?> clazz;\r
+\r
+       public StringChooserModifyListenerImpl() {\r
+               clazz = ReflectionUtils.getSingleParameterType(getClass());\r
+       }\r
+\r
+       private Object getInputContents(Object input, Class<?> inputClass) {\r
+               if (inputClass.isInstance(input))\r
+                       return input;\r
+               if (input instanceof ISelection)\r
+                       return ISelectionUtils.filterSingleSelection(input, inputClass);\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public void modifySelection(StringChooserModifyEvent<T2> e) {\r
+\r
+               Text text = (Text)e.getWidget();\r
+               final T2 object = e.getObject();\r
+               final String textValue = text.getText();\r
+               final T input = lastInput;\r
+\r
+               try {\r
+                       context.getSession().syncRequest(new WriteRequest() {\r
+\r
+                               @SuppressWarnings("unchecked")\r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       \r
+                                       if(clazz.isInstance(input)) {\r
+                                               applyObject(graph, (T)input, object, textValue);\r
+                                       } else {\r
+                                               T single = (T)getInputContents(input, clazz);\r
+                                               if(single != null)\r
+                                                       applyObject(graph, single, object, textValue);\r
+                                       }\r
+\r
+                                       \r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object parameter) {\r
+               this.context = context;\r
+               lastInput = (T)parameter;\r
+       }\r
+\r
+       abstract public void applyObject(WriteGraph graph, T input, T2 object, String text) throws DatabaseException;\r
+\r
+}\r
diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableFactory.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableFactory.java
deleted file mode 100644 (file)
index f994709..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.simantics.jfreechart.chart.properties;\r
-\r
-import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.sysdyn.JFreeChartResource;\r
-import org.simantics.utils.datastructures.BijectionMap;\r
-\r
-public class VariableFactory extends ReadFactoryImpl<Resource, String> {\r
-       BijectionMap<String , String> map = new BijectionMap<String, String>();\r
-       \r
-       public VariableFactory(BijectionMap<String , String> map) {\r
-               this.map = map;\r
-       }\r
-       \r
-        @Override\r
-        public String perform(ReadGraph graph, Resource input) throws DatabaseException {\r
-               String value = graph.getPossibleRelatedValue(input, JFreeChartResource.getInstance(graph).variableRVI);\r
-               if (value == null)\r
-                       return "";\r
-               value = map.getRight(value);\r
-               if (value == null)\r
-                       return "";\r
-               return value;\r
-        \r
-        }\r
-\r
-}\r
index 2f6f20f44bca4dba8284d6867b9f1856fd25f673..aa19d6def8a5d1f7284c8a1ef597b7584901b966 100644 (file)
@@ -13,8 +13,11 @@ package org.simantics.jfreechart.chart.properties;
 \r
 import java.util.ArrayList;\r
 import java.util.Collection;\r
+import java.util.Iterator;\r
 \r
-import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;\r
+import org.eclipse.jface.fieldassist.ContentProposal;\r
+import org.eclipse.jface.fieldassist.IContentProposal;\r
+import org.eclipse.jface.fieldassist.IContentProposalProvider;\r
 import org.eclipse.swt.widgets.Control;\r
 import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
@@ -23,16 +26,112 @@ import org.simantics.db.management.ISessionContext;
 import org.simantics.db.procedure.Listener;\r
 import org.simantics.ui.SimanticsUI;\r
 import org.simantics.ui.utils.AdaptionUtils;\r
-import org.simantics.utils.datastructures.Pair;\r
 \r
 /**\r
- * Provides all variables a model contains\r
  * \r
- * @author Teemu Lempinen\r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
  *\r
  */\r
-public class VariableProposalProvider extends IdLabelProposalProvider implements Widget {\r
+public class VariableProposalProvider implements IContentProposalProvider, Widget {\r
 \r
+       /*\r
+        * The proposals provided.\r
+        */\r
+       private Collection<ChartVariable> proposals;\r
+\r
+       /*\r
+        * The proposals mapped to IContentProposal. Cached for speed in the case\r
+        * where filtering is not used.\r
+        */\r
+       private IContentProposal[] contentProposals;\r
+\r
+       /*\r
+        * Boolean that tracks whether filtering is used.\r
+        */\r
+       private boolean filterProposals = false;\r
+\r
+\r
+       private boolean compareRVI = false;\r
+       /**\r
+        * Return an array of Objects representing the valid content proposals for a\r
+        * field. \r
+        * \r
+        * @param contents\r
+        *            the current contents of the field (only consulted if filtering\r
+        *            is set to <code>true</code>)\r
+        * @param position\r
+        *            the current cursor position within the field (ignored)\r
+        * @return the array of Objects that represent valid proposals for the field\r
+        *         given its current content.\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       public IContentProposal[] getProposals(String contents, int position) {\r
+               if (filterProposals) {\r
+                       ArrayList list = new ArrayList();\r
+                       if (compareRVI) {\r
+                               for (ChartVariable proposal : proposals) {\r
+                                       if (proposal.getRvi().length() >= contents.length() && proposal.getRvi().substring(0, contents.length()).equalsIgnoreCase(contents)) {\r
+                                               if (proposal.getLabel() != null)\r
+                                                       list.add(new ContentProposal(proposal.getRvi(),proposal.getLabel(), null));\r
+                                               else\r
+                                                       list.add(new ContentProposal(proposal.getRvi()));\r
+                                       } else if (proposal.getLabel() != null && proposal.getLabel().length() >= contents.length() && proposal.getLabel().substring(0, contents.length()).equalsIgnoreCase(contents)) {\r
+                                               list.add(new ContentProposal(proposal.getRvi(),proposal.getLabel(), null));\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               for (ChartVariable proposal : proposals) {\r
+                                       if (proposal.getLabel() != null && proposal.getLabel().length() >= contents.length() && proposal.getLabel().substring(0, contents.length()).equalsIgnoreCase(contents)) {\r
+                                               list.add(new ContentProposal(proposal.getRvi(),proposal.getLabel(), null));\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
+                       return (IContentProposal[]) list.toArray(new IContentProposal[list\r
+                                       .size()]);\r
+               }\r
+               if (contentProposals == null) {\r
+                       contentProposals = new IContentProposal[proposals.size()];\r
+                       Iterator<ChartVariable> iter = proposals.iterator();\r
+                       for (int i = 0; i < proposals.size(); i++) {\r
+                               ChartVariable proposal = iter.next();\r
+                               if (proposal.getLabel() != null)\r
+                                       contentProposals[i] = new ContentProposal(proposal.getRvi(),proposal.getLabel(),null);\r
+                               else\r
+                                       contentProposals[i] = new ContentProposal(proposal.getRvi());\r
+                       }\r
+               }\r
+               return contentProposals;\r
+       }\r
+\r
+       /**\r
+        * Set the Strings to be used as content proposals.\r
+        * \r
+        * @param items\r
+        *            the array of Strings to be used as proposals.\r
+        */\r
+       public void setProposals(Collection<ChartVariable> items) {\r
+               this.proposals = items;\r
+               contentProposals = null;\r
+       }\r
+\r
+       /**\r
+        * Set the boolean that controls whether proposals are filtered according to\r
+        * the current field content.\r
+        * \r
+        * @param filterProposals\r
+        *            <code>true</code> if the proposals should be filtered to\r
+        *            show only those that match the current contents of the field,\r
+        *            and <code>false</code> if the proposals should remain the\r
+        *            same, ignoring the field content.\r
+        * @since 3.3\r
+        */\r
+       public void setFiltering(boolean filterProposals) {\r
+               this.filterProposals = filterProposals;\r
+               // Clear any cached proposals.\r
+               contentProposals = null;\r
+       }\r
+       \r
     /**\r
      * Provides all variables a model contains. Given resource needs to be\r
      * part of a model (i.e. using PartOf leads eventually to a SysdynModel).\r
@@ -41,7 +140,7 @@ public class VariableProposalProvider extends IdLabelProposalProvider implements
      * @param resource A resource that is part of a model\r
      */\r
     public VariableProposalProvider(final Control control, WidgetSupport support) {\r
-        super(new ArrayList<ChartVariable>());// super(String [] {});\r
+        this.proposals = new ArrayList<ChartVariable>();\r
         support.register(this);\r
         this.control = control;\r
     }\r
index a53d122d443b47e0ac61fe6e10b45c1a57daed86..ec2f1dc98aeb0e2700f45e7e53bd5d0a76907559 100644 (file)
@@ -24,20 +24,16 @@ import org.simantics.browsing.ui.swt.widgets.TrackedText;
 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
 import org.simantics.db.management.ISessionContext;\r
 import org.simantics.jfreechart.chart.properties.ChartVariable;\r
+import org.simantics.jfreechart.chart.properties.ChartVariableFactory;\r
+import org.simantics.jfreechart.chart.properties.ChartVariableModifier;\r
 import org.simantics.jfreechart.chart.properties.DoubleValidator;\r
 import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider;\r
-import org.simantics.jfreechart.chart.properties.RVIFactory;\r
-import org.simantics.jfreechart.chart.properties.RVIModifier;\r
 import org.simantics.jfreechart.chart.properties.RangeComposite;\r
-import org.simantics.jfreechart.chart.properties.VariableExistsValidator;\r
-import org.simantics.jfreechart.chart.properties.VariableFactory;\r
-import org.simantics.jfreechart.chart.properties.VariableModifier;\r
+import org.simantics.jfreechart.chart.properties.StringChooser;\r
 import org.simantics.layer0.Layer0;\r
 import org.simantics.modeling.ui.chart.property.DoublePropertyFactory;\r
 import org.simantics.modeling.ui.chart.property.DoublePropertyModifier;\r
 import org.simantics.sysdyn.JFreeChartResource;\r
-import org.simantics.utils.datastructures.BijectionMap;\r
-import org.simantics.utils.datastructures.Pair;\r
 \r
 /**\r
  * Composite for modifying properties of a series in a bar chart\r
@@ -46,7 +42,8 @@ import org.simantics.utils.datastructures.Pair;
  */\r
 public class BarSeriesPropertyComposite2 extends Composite {\r
     \r
-    private TrackedText variable, label, time;\r
+    private TrackedText label, time;\r
+    private StringChooser<ChartVariable> variable;\r
     \r
     public BarSeriesPropertyComposite2(Composite parent, final ISessionContext context, WidgetSupport support, Collection<ChartVariable> variables, int style) {\r
         super(parent, style);\r
@@ -58,17 +55,23 @@ public class BarSeriesPropertyComposite2 extends Composite {
         label.setText("Variable:");\r
         GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
 \r
-        variable = new TrackedText(this, support, SWT.BORDER);\r
-       \r
-       // FIXME: using bijectionmap and trackedText looses the variables that have the same label.\r
-       BijectionMap<String , String> map = new BijectionMap<String, String>();\r
-       for (ChartVariable variable : variables) {\r
-                       map.map(variable.getRvi(), variable.toString());\r
-               }\r
-       variable.setTextFactory(new VariableFactory(map));\r
-       variable.addModifyListener(new VariableModifier(variable.getWidget(), support));\r
-       variable.setInputValidator(new VariableExistsValidator(support, variable, false, true));\r
+//        variable = new TrackedText(this, support, SWT.BORDER);\r
+//       \r
+//     // FIXME: using bijectionmap and trackedText looses the variables that have the same label.\r
+//     BijectionMap<String , String> map = new BijectionMap<String, String>();\r
+//     for (ChartVariable variable : variables) {\r
+//                     map.map(variable.getRvi(), variable.toString());\r
+//             }\r
+//     variable.setTextFactory(new VariableFactory(map));\r
+//     variable.addModifyListener(new VariableModifier(variable.getWidget(), support));\r
+//     variable.setInputValidator(new VariableExistsValidator(support, variable, false, true));\r
        \r
+\r
+        variable = new StringChooser<ChartVariable>(this, support, SWT.BORDER);\r
+        variable.setData(variables);\r
+        variable.setObjectFactory(new ChartVariableFactory(variables));\r
+        variable.addModifyListener(new ChartVariableModifier(variable.getWidget(), support));\r
+        \r
         variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager()));\r
         GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget());\r
 \r
index e0c3d891d87e0d735cb2a89c71bffd81232fcc83..70d0076e25457ec69080ca397c20c9116c4d67be 100644 (file)
@@ -27,21 +27,17 @@ import org.simantics.db.management.ISessionContext;
 import org.simantics.jfreechart.chart.properties.BooleanPropertyFactory;\r
 import org.simantics.jfreechart.chart.properties.BooleanSelectionListener;\r
 import org.simantics.jfreechart.chart.properties.ChartVariable;\r
+import org.simantics.jfreechart.chart.properties.ChartVariableFactory;\r
+import org.simantics.jfreechart.chart.properties.ChartVariableModifier;\r
 import org.simantics.jfreechart.chart.properties.ColorPicker;\r
 import org.simantics.jfreechart.chart.properties.DoubleValidator;\r
 import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider;\r
-import org.simantics.jfreechart.chart.properties.RVIFactory;\r
-import org.simantics.jfreechart.chart.properties.RVIModifier;\r
 import org.simantics.jfreechart.chart.properties.RangeComposite;\r
-import org.simantics.jfreechart.chart.properties.VariableExistsValidator;\r
-import org.simantics.jfreechart.chart.properties.VariableFactory;\r
-import org.simantics.jfreechart.chart.properties.VariableModifier;\r
+import org.simantics.jfreechart.chart.properties.StringChooser;\r
 import org.simantics.layer0.Layer0;\r
 import org.simantics.modeling.ui.chart.property.DoublePropertyFactory;\r
 import org.simantics.modeling.ui.chart.property.DoublePropertyModifier;\r
 import org.simantics.sysdyn.JFreeChartResource;\r
-import org.simantics.utils.datastructures.BijectionMap;\r
-import org.simantics.utils.datastructures.Pair;\r
 \r
 /**\r
  * Composite containing the properties of a series\r
@@ -50,7 +46,8 @@ import org.simantics.utils.datastructures.Pair;
  */\r
 public class PieSeriesPropertyComposite2 extends Composite {\r
     \r
-    private TrackedText variable, label, time;\r
+    private TrackedText label, time;\r
+    private StringChooser<ChartVariable> variable;\r
     \r
     public PieSeriesPropertyComposite2(Composite parent, ISessionContext context, WidgetSupport support, Collection<ChartVariable> variables,int style) {\r
         super(parent, style);\r
@@ -62,14 +59,11 @@ public class PieSeriesPropertyComposite2 extends Composite {
         label.setText("Variable:");\r
         GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
 \r
-        variable = new TrackedText(this, support, SWT.BORDER);\r
-        BijectionMap<String , String> map = new BijectionMap<String, String>();\r
-        for (ChartVariable variable : variables) {\r
-                       map.map(variable.getRvi(), variable.toString());\r
-               }\r
-       variable.setTextFactory(new VariableFactory(map));\r
-       variable.addModifyListener(new VariableModifier(variable.getWidget(), support));\r
-       variable.setInputValidator(new VariableExistsValidator(support, variable, false, true));\r
+        \r
+        variable = new StringChooser<ChartVariable>(this, support, SWT.BORDER);\r
+        variable.setData(variables);\r
+        variable.setObjectFactory(new ChartVariableFactory(variables));\r
+        variable.addModifyListener(new ChartVariableModifier(variable.getWidget(), support));\r
         \r
         variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager()));\r
         GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget());\r