]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.ui.workbench/src/org/simantics/utils/ui/workbench/dialogs/PropertyEditorDialog.java
Sync git svn branch with SVN repository r33269.
[simantics/platform.git] / bundles / org.simantics.utils.ui.workbench / src / org / simantics / utils / ui / workbench / dialogs / PropertyEditorDialog.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 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.utils.ui.workbench.dialogs;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.HashSet;\r
16 import java.util.List;\r
17 import java.util.Set;\r
18 \r
19 import org.eclipse.jface.viewers.CellEditor;\r
20 import org.eclipse.jface.viewers.ICellModifier;\r
21 import org.eclipse.jface.viewers.IStructuredSelection;\r
22 import org.eclipse.jface.viewers.StructuredSelection;\r
23 import org.eclipse.jface.viewers.TableViewer;\r
24 import org.eclipse.jface.viewers.TextCellEditor;\r
25 import org.eclipse.swt.SWT;\r
26 import org.eclipse.swt.events.VerifyEvent;\r
27 import org.eclipse.swt.events.VerifyListener;\r
28 import org.eclipse.swt.widgets.Composite;\r
29 import org.eclipse.swt.widgets.Control;\r
30 import org.eclipse.swt.widgets.Shell;\r
31 import org.eclipse.swt.widgets.Table;\r
32 import org.eclipse.swt.widgets.TableItem;\r
33 import org.eclipse.swt.widgets.Text;\r
34 \r
35 \r
36 /**\r
37  * EditablePropertyDialog is a property dialog where dialog cells can be\r
38  * modified\r
39  * \r
40  */\r
41 public class PropertyEditorDialog extends PropertyDialog {\r
42 \r
43     public static final int ADD_PROPERTY_ID = -5000;\r
44 \r
45     public static final int REMOVE_PROPERTY_ID = -5000 + 1;\r
46 \r
47     /** Fields that are read-only */\r
48     protected Set<String> readOnlyKeys = new HashSet<String>();\r
49     \r
50     protected List<PropertyLineVerifyListener> verifyListeners = new ArrayList<PropertyLineVerifyListener>();\r
51 \r
52     public PropertyEditorDialog(Shell parent) {\r
53         super(parent);\r
54     }\r
55 \r
56     @Override\r
57     protected Control createDialogArea(Composite container) {\r
58         Control composite = super.createDialogArea(container);\r
59         TableViewer viewer = getTableViewer();\r
60         Table table = viewer.getTable();\r
61 \r
62         viewer.setInput(getTableViewer().getInput());\r
63 \r
64         CellEditor keyEditor = new TextCellEditor(table, SWT.NORMAL);\r
65         TextCellEditor valueEditor = new TextCellEditor(table, SWT.NORMAL);\r
66         ((Text)valueEditor.getControl()).addVerifyListener(new VerifyListener() {\r
67             public void verifyText(VerifyEvent e) {\r
68                 String sel[] = getSelection();\r
69                 if (sel==null) return;\r
70                 Text w = (Text)e.widget;\r
71                 String newText = w.getText();\r
72                 // deleting text\r
73                 if (e.text.length()==0)\r
74                     newText = newText.substring(0,e.start) + newText.substring(e.end, newText.length());\r
75                 else \r
76                     // inserting text\r
77                     newText = newText.substring(0,e.start) + e.text + newText.substring(e.end );\r
78                 \r
79                 e.doit = verifyValueModification(sel[0], newText    );\r
80             }});\r
81         viewer.setCellEditors(new CellEditor[] { keyEditor, valueEditor });\r
82 \r
83         viewer.setCellModifier(new ICellModifier() {\r
84             public boolean canModify(Object element, String property) {\r
85                 int column = columnNameToColumn(property);\r
86                 if (column < 0)\r
87                     return false;\r
88                 String line[] = (String[]) element;\r
89                 String key = line[0];\r
90                 boolean keyReadOnly = isKeyReadonly(key);\r
91                 \r
92                 return !keyReadOnly;\r
93             }\r
94 \r
95             public Object getValue(Object element, String property) {\r
96                 int column = columnNameToColumn(property);\r
97                 String line[] = (String[]) element;\r
98                 return line[column];\r
99             }\r
100 \r
101             public void modify(Object element, String property, Object value) {\r
102                 // Some kind of bug? This returns TableItem object sometimes\r
103                 if (element instanceof TableItem)\r
104                     element = ((TableItem) element).getData();\r
105                 int column = columnNameToColumn(property);\r
106                 String line[] = (String[]) element;\r
107                 String key = line[0];\r
108                 \r
109                 // Cannot have two values with same key\r
110                 if (column==0 && containsKey(value.toString()))\r
111                     return;\r
112                 if (column==0 && isKeyReadonly(key))\r
113                     return;\r
114                 if (column==0 && !verifyValueModification(value.toString(), line[1]))\r
115                     return;\r
116                 \r
117                 line[column] = value.toString();\r
118                 labelProvider.elementChanged(element);\r
119             }\r
120         });\r
121 \r
122         return composite;\r
123     }\r
124 \r
125     protected boolean containsKey(String key) {\r
126         for (String[] line : data)\r
127             if (line[0].equals(key))\r
128                 return true;\r
129         return false;                \r
130     }\r
131     \r
132     @Override\r
133     protected void createButtonsForButtonBar(Composite parent) {\r
134         // Add property button\r
135         createButton(parent, ADD_PROPERTY_ID, "Add property", false);\r
136         // Remove property button\r
137         createButton(parent, REMOVE_PROPERTY_ID, "Remove property", false);\r
138 \r
139         setAddCancelButton(true);\r
140         super.createButtonsForButtonBar(parent);\r
141         // Having this true enables double-click listener later\r
142         // Which is annoying\r
143         setAddCancelButton(false);\r
144     }\r
145 \r
146     @Override\r
147     protected void buttonPressed(int buttonId) {\r
148         if (buttonId == ADD_PROPERTY_ID)\r
149             addPropertyPressed();\r
150         else if (buttonId == REMOVE_PROPERTY_ID)\r
151             removePropertyPressed();\r
152         else\r
153             super.buttonPressed(buttonId);\r
154     }\r
155 \r
156     protected String[] getSelection() {\r
157         IStructuredSelection sel = (IStructuredSelection) this.getTableViewer().getSelection();\r
158         if (sel==null) return null;\r
159         Object o = sel.getFirstElement();\r
160         if (o==null) return null;\r
161         return (String[]) o;\r
162     }\r
163     \r
164     private void removePropertyPressed() {\r
165         String o[] = getSelection();\r
166         if (o==null) return;\r
167         if (readOnlyKeys.contains(o[0]))\r
168             return;\r
169         if (!data.remove(o)) return;\r
170         labelProvider.refreshAll();\r
171     }\r
172 \r
173     private void addPropertyPressed() {\r
174         String newElement[] = new String[] {"<new property>", "<value>"}; \r
175         data.add(newElement);        \r
176         labelProvider.refreshAll();\r
177         getTableViewer().setSelection(new StructuredSelection(newElement));\r
178     }\r
179 \r
180     /**\r
181      * Set fields that are read-only (These are 1st column key names)\r
182      * \r
183      * @param readOnlyFields fields that are read only\r
184      */\r
185     public void setReadOnlyFields(String[] readOnlyFields) {\r
186         for (String key : readOnlyFields)\r
187             readOnlyKeys.add(key);        \r
188     }\r
189     \r
190     /**\r
191      * Set a key read-only / writable\r
192      * @param key key name\r
193      * @param readOnly true = readonly, false = writable\r
194      */\r
195     public void setFieldReadOnlyStatus(String key, boolean readOnly) {\r
196         if (readOnly)\r
197             readOnlyKeys.add(key);\r
198         else \r
199             readOnlyKeys.remove(key);\r
200     }\r
201     \r
202     protected boolean isKeyReadonly(String key) {\r
203         return readOnlyKeys.contains(key);\r
204     }\r
205 \r
206     /**\r
207      * Get result data\r
208      * @return result data\r
209      */\r
210     public List<String[]> getData() {\r
211         return data;\r
212     }\r
213     \r
214     public void addVerifyListener(PropertyLineVerifyListener listener) {\r
215         verifyListeners.add(listener);\r
216     }\r
217     \r
218     public void removeVerifyListener(PropertyLineVerifyListener listener) {\r
219         verifyListeners.remove(listener);\r
220     }\r
221     \r
222     protected boolean verifyValueModification(String key, String value) {\r
223         boolean result = true;\r
224         for (PropertyLineVerifyListener l : verifyListeners)\r
225             result = result & l.verifyValue(key, value);\r
226         return result;\r
227     }\r
228 }\r