]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/contentassist/AbstractContentAssistModifier.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.browsing.ui.swt / src / org / simantics / browsing / ui / swt / contentassist / AbstractContentAssistModifier.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2012 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.browsing.ui.swt.contentassist;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.List;\r
16 \r
17 import org.eclipse.swt.SWT;\r
18 import org.eclipse.swt.widgets.Composite;\r
19 import org.eclipse.swt.widgets.Event;\r
20 import org.eclipse.swt.widgets.Listener;\r
21 import org.eclipse.swt.widgets.TreeItem;\r
22 import org.simantics.browsing.ui.NodeContext;\r
23 import org.simantics.browsing.ui.common.modifiers.EnumeratedValue;\r
24 import org.simantics.browsing.ui.common.modifiers.Enumeration;\r
25 import org.simantics.browsing.ui.content.Labeler.CustomModifier;\r
26 \r
27 /**\r
28  * @author Tuukka Lehtonen\r
29  */\r
30 abstract public class AbstractContentAssistModifier<T> implements CustomModifier {\r
31 \r
32     protected final Enumeration<T>     enumeration;\r
33     protected final T value;\r
34 \r
35     protected ContentAssistTextField   text;\r
36 \r
37     public AbstractContentAssistModifier(Enumeration<T> enumeration, T value) {\r
38         if (enumeration == null)\r
39             throw new NullPointerException("null enumeration");\r
40         if (enumeration.size() == 0)\r
41             throw new IllegalArgumentException("");\r
42 \r
43         this.enumeration = enumeration;\r
44         this.value = value;\r
45     }\r
46 \r
47     @Override\r
48     public String getValue() {\r
49         if (value != null)\r
50             return value.toString();\r
51         return enumeration.values().get(0).getName();\r
52     }\r
53 \r
54     @Override\r
55     public String isValid(String label) {\r
56         if (enumeration.findByName(label) == null)\r
57             return "Value '" + label + "' is not among the enumerated values " + enumeration.values();\r
58         return null;\r
59     }\r
60 \r
61     @Override\r
62     public void modify(String label) {\r
63         String error = isValid(label); \r
64         if(error != null)\r
65             throw new IllegalArgumentException(error);\r
66         modifyWithValue(this.value, label);\r
67     }\r
68 \r
69     abstract void modifyWithValue(T oldEnumValue, String enumValue);\r
70 \r
71     /**\r
72      * Override to customize the content assist proposal objects created from\r
73      * the enumerated values.\r
74      * \r
75      * @param value\r
76      * @return\r
77      */\r
78     protected NamedObject<T> createNamedObject(EnumeratedValue<T> value) {\r
79         return new NamedObject<T>(value.getObject(), value.getName());\r
80     }\r
81 \r
82     protected List<NamedObject<T>> toNamedObjects(Enumeration<T> enumeration) {\r
83         List<NamedObject<T>> namedObjects = new ArrayList<NamedObject<T>>();\r
84         for (EnumeratedValue<T> v : enumeration.values())\r
85             namedObjects.add(createNamedObject(v));\r
86         return namedObjects;\r
87     }\r
88 \r
89     @Override\r
90     public Object createControl(Object parentControl, Object controlItem, final int columnIndex, NodeContext context) {\r
91         Composite parent = (Composite) parentControl;\r
92         final TreeItem item = (TreeItem) controlItem;\r
93 \r
94         List<NamedObject<T>> possibleValues = toNamedObjects(enumeration);\r
95         \r
96         EnumeratedValue<T> enuValue = enumeration.find(value);\r
97         \r
98         NamedObject<T> selectedValue = enuValue != null ? createNamedObject(enuValue) : null;\r
99 \r
100         text = new ContentAssistTextField(parent, selectedValue, possibleValues, SWT.NONE);\r
101 \r
102         Listener textListener = new Listener() {\r
103             String error;\r
104 \r
105             @Override\r
106             public void handleEvent(final Event e) {\r
107                 switch (e.type) {\r
108                     case SWT.Modify: {\r
109                         String newText = text.getControl().getText();\r
110 //                        System.out.println("VALIDATE NEW TEXT: " + newText);\r
111                         error = isValid(newText);\r
112                         if (error != null) {\r
113                             text.getControl().setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED));\r
114 //                                System.out.println("validation error: " + error);\r
115                         } else {\r
116                             text.getControl().setBackground(null);\r
117                         }\r
118 //                        text.getDisplay().asyncExec(new Runnable() {\r
119 //                            @Override\r
120 //                            public void run() {\r
121                         //if (!text.getControl().isDisposed())\r
122                         //text.getControl().traverse(SWT.TRAVERSE_ARROW_NEXT);\r
123                         //text.getControl().setSelection(text.getControl().getCaretPosition());\r
124 //                            }\r
125 //                        });\r
126                         break;\r
127                     }\r
128                     case SWT.Verify:\r
129                         // Safety check since it seems that this may happen with\r
130                         // virtual trees.\r
131 //                        if (item.isDisposed())\r
132 //                            return;\r
133 \r
134 //                        newText = text.getControl().getText();\r
135 //                        String leftText = newText.substring(0, e.start);\r
136 //                        String rightText = newText.substring(e.end, newText.length());\r
137 //                        GC gc = new GC(text.getControl());\r
138 //                        Point size = gc.textExtent(leftText + e.text + rightText);\r
139 //                        gc.dispose();\r
140 //                        size = text.getControl().computeSize(size.x, SWT.DEFAULT);\r
141 //                        Rectangle itemRect = item.getBounds(columnIndex),\r
142 //                        rect = tree.getClientArea();\r
143 //                        editor.minimumWidth = Math.max(size.x, itemRect.width) + insetX * 2;\r
144 //                        int left = itemRect.x,\r
145 //                        right = rect.x + rect.width;\r
146 //                        editor.minimumWidth = Math.min(editor.minimumWidth, right - left);\r
147 //                        editor.minimumHeight = size.y + insetY * 2;\r
148 //                        editor.layout();\r
149                         break;\r
150 //                    case SWT.FocusOut: {\r
151 //                        System.out.println("focus out");\r
152 //                        String t = text.getControl().getText();\r
153 //                        modify(t);\r
154 //\r
155 //                        // Item may be disposed if the tree gets reset after a previous editing.\r
156 //                        if (!item.isDisposed()) {\r
157 //                            item.setText(columnIndex, t);\r
158 //                            //queueSelectionRefresh(context);\r
159 //                        }\r
160 //                        text.dispose();\r
161 //                        break;\r
162 //                    }\r
163                     case SWT.Traverse: {\r
164                         //System.out.println(AbstractContentAssistEnumerationModifier.class.getSimpleName() + " TRAVERSE: " + e.detail);\r
165                         switch (e.detail) {\r
166                             case SWT.TRAVERSE_RETURN:\r
167                                 //System.out.println("TRAVERSE: RETURN");\r
168                                 INamedObject obj = text.getResult();\r
169                                 String txt = obj != null ? obj.getName() : text.getControl().getText();\r
170                                 if (txt ==  null || error != null) {\r
171                                     e.doit = false;\r
172                                     return;\r
173                                 }\r
174                                 modify(txt);\r
175                                 if (!item.isDisposed()) {\r
176                                     item.setText(columnIndex, txt);\r
177                                     //queueSelectionRefresh(context);\r
178                                 }\r
179                                 // FALL THROUGH\r
180                             case SWT.TRAVERSE_ESCAPE:\r
181                                 //System.out.println("TRAVERSE: ESCAPE");\r
182                                 text.dispose();\r
183                                 e.doit = false;\r
184                                 break;\r
185                             default:\r
186                                 //System.out.println("unhandled traversal: " + e.detail);\r
187                                 break;\r
188                         }\r
189                         break;\r
190                     }\r
191                 }\r
192             }\r
193         };\r
194         text.getControl().addListener(SWT.Modify, textListener);\r
195 //        text.getControl().addListener(SWT.Verify, textListener);\r
196 //        text.getControl().addListener(SWT.FocusOut, textListener);\r
197         text.getControl().addListener(SWT.Traverse, textListener);\r
198 \r
199         text.setFocus();\r
200         text.text.selectAll();\r
201         text.getDisplay().asyncExec(new Runnable() {\r
202             @Override\r
203             public void run() {\r
204                 if (!text.isDisposed())\r
205                     text.openAssist();\r
206             }\r
207         });\r
208 \r
209         return text;\r
210     }\r
211 \r
212 }\r