]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartAndSubscriptionItemDialog.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.charts / src / org / simantics / charts / ui / ChartAndSubscriptionItemDialog.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * 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.charts.ui;\r
13 \r
14 import java.awt.Color;\r
15 \r
16 import org.eclipse.core.runtime.preferences.IEclipsePreferences;\r
17 import org.eclipse.core.runtime.preferences.InstanceScope;\r
18 import org.eclipse.jface.dialogs.Dialog;\r
19 import org.eclipse.jface.fieldassist.ControlDecoration;\r
20 import org.eclipse.jface.fieldassist.FieldDecorationRegistry;\r
21 import org.eclipse.jface.layout.GridDataFactory;\r
22 import org.eclipse.jface.layout.GridLayoutFactory;\r
23 import org.eclipse.jface.preference.ColorSelector;\r
24 import org.eclipse.jface.util.IPropertyChangeListener;\r
25 import org.eclipse.jface.util.PropertyChangeEvent;\r
26 import org.eclipse.swt.SWT;\r
27 import org.eclipse.swt.events.ModifyEvent;\r
28 import org.eclipse.swt.events.ModifyListener;\r
29 import org.eclipse.swt.events.SelectionAdapter;\r
30 import org.eclipse.swt.events.SelectionEvent;\r
31 import org.eclipse.swt.graphics.Image;\r
32 import org.eclipse.swt.graphics.RGB;\r
33 import org.eclipse.swt.widgets.Button;\r
34 import org.eclipse.swt.widgets.Combo;\r
35 import org.eclipse.swt.widgets.Composite;\r
36 import org.eclipse.swt.widgets.Control;\r
37 import org.eclipse.swt.widgets.Group;\r
38 import org.eclipse.swt.widgets.Label;\r
39 import org.eclipse.swt.widgets.Shell;\r
40 import org.eclipse.swt.widgets.Spinner;\r
41 import org.eclipse.swt.widgets.Text;\r
42 import org.simantics.charts.preference.ChartPreferences;\r
43 import org.simantics.charts.query.ChartAndSubscriptionItemData;\r
44 import org.simantics.databoard.util.URIStringUtils;\r
45 import org.simantics.modeling.preferences.SubscriptionPreferences;\r
46 import org.simantics.trend.configuration.Scale;\r
47 import org.simantics.trend.configuration.TrendItem.DrawMode;\r
48 import org.simantics.trend.impl.JarisPaints;\r
49 \r
50 /**\r
51  * ChartAndSubscriptionItemDialog is a dialog that has the following property\r
52  * queries:\r
53  *   Chart name  (Read only)\r
54  *   Variable    (Read only)\r
55  *   Label\r
56  *   Draw Mode   (Enumeration)\r
57  *   Scale, min, max ( Enum, int, int)\r
58  *   Subscription ( Text )\r
59  *   Deadband, Interval, Gain, Bias, Unit (Double)\r
60  *   Stroke settings (width, color)\r
61  * \r
62  * If the dialog is opened in binary mode the content is more stripped.\r
63  *   Chart name\r
64  *   Variable\r
65  *   Label\r
66  *   Subscription\r
67  *   Stroke settings\r
68  * \r
69  * @author toni.kalajainen\r
70  */\r
71 public class ChartAndSubscriptionItemDialog extends Dialog {\r
72 \r
73     private static final String MANUAL = "Manual";\r
74     private static final String AUTO = "Auto";\r
75 \r
76     // UI\r
77     Label lChart, lRVI, lLabel, lDrawMode, lScale, lMin, lMax, lSubscription, lDeadband, lInterval, lGain, lBias, lUnit;\r
78     Text tRVI, tLabel, tDeadband, tInterval, tGain, tBias, tUnit;\r
79     Combo cSubscription;\r
80     Button saveAsPrefs;\r
81 \r
82     // chart specific, not initialized, if includeChartSpecificProperties=false\r
83     Text tChart, tMin, tMax;\r
84     Combo cDrawMode, cScale;\r
85     Spinner sStrokeWidth;\r
86     ColorSelector colorSelector;\r
87 \r
88     // Input error decorations\r
89     ControlDecoration tMinDecor;\r
90     ControlDecoration tMaxDecor;\r
91     ControlDecoration tDeadbandDecor;\r
92     ControlDecoration tIntervalDecor;\r
93     ControlDecoration tGainDecor;\r
94     ControlDecoration tBiasDecor;\r
95 \r
96     //\r
97     ChartAndSubscriptionItemData baseData = new ChartAndSubscriptionItemData();\r
98     ChartAndSubscriptionItemData data;\r
99 \r
100     final Runnable applyAction;\r
101 \r
102     IEclipsePreferences chartnode; // chart specific, not initialized, if includeChartSpecificProperties=false\r
103     IEclipsePreferences subscriptionnode;\r
104     boolean includeChartSpecificProperties;\r
105 \r
106     public ChartAndSubscriptionItemDialog(Shell parentShell, ChartAndSubscriptionItemData data, boolean includeChartSpecificProperties) {\r
107         this(parentShell, data, includeChartSpecificProperties, null);\r
108     }\r
109 \r
110     public ChartAndSubscriptionItemDialog(Shell parentShell, ChartAndSubscriptionItemData data, boolean includeChartSpecificProperties, Runnable applyAction) {\r
111         super(parentShell);\r
112         this.data = data;\r
113         this.baseData.readFrom(data);\r
114         this.includeChartSpecificProperties = includeChartSpecificProperties;\r
115         this.applyAction = applyAction;\r
116 \r
117         if(includeChartSpecificProperties)\r
118             chartnode = InstanceScope.INSTANCE.getNode( ChartPreferences.P_NODE );\r
119         subscriptionnode = InstanceScope.INSTANCE.getNode( SubscriptionPreferences.P_NODE );\r
120 \r
121         setShellStyle(SWT.RESIZE | SWT.TITLE | SWT.CLOSE | SWT.BORDER);\r
122     }\r
123 \r
124     @Override\r
125     protected Control createContents(Composite parent) {\r
126         Control c = super.createContents(parent);\r
127         validate();\r
128         return c;\r
129     }\r
130 \r
131     @Override\r
132     protected void createButtonsForButtonBar(Composite parent) {\r
133         if (applyAction != null)\r
134             createButton(parent, ChartDialogConstants.APPLY_ID, ChartDialogConstants.APPLY_LABEL, true);\r
135         super.createButtonsForButtonBar(parent);\r
136     }\r
137 \r
138     public void setInput(ChartAndSubscriptionItemData data) {\r
139         // TODO: implement so that this reinitializes the UI of the dialog according to the new specified data\r
140     }\r
141 \r
142     protected void disposeDialogAreaContents() {\r
143         Composite area = (Composite) dialogArea;\r
144         for (Control child : area.getChildren())\r
145             child.dispose();\r
146     }\r
147 \r
148     @Override\r
149     protected Control createDialogArea(Composite parent) {\r
150         Composite c = (Composite) super.createDialogArea(parent);\r
151         GridLayoutFactory.fillDefaults().margins(8, 8).numColumns(9).applyTo(c);\r
152         createDialogAreaContents(c);\r
153         return c;\r
154     }\r
155 \r
156     protected void createDialogAreaContents(Composite c) {\r
157         GridDataFactory gd1 = GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(1, 1);\r
158         GridDataFactory gd2 = GridDataFactory.fillDefaults().grab(true, false).indent(5, 0).span(8, 1);\r
159 \r
160         // 1st line - Chart: [chart name]\r
161         if(includeChartSpecificProperties) {\r
162             lChart = new Label(c, 0);\r
163             lChart.setText("Chart:");\r
164             gd1.applyTo(lChart);\r
165             tChart = new Text(c, SWT.BORDER | SWT.READ_ONLY);\r
166             //tChart.setEnabled( false );\r
167             if ( data.chartName != null ) tChart.setText( data.chartName );\r
168             gd2.applyTo(tChart);\r
169         }\r
170 \r
171         // 2nd line - Variable Reference: [chart item label]\r
172         lRVI = new Label(c, 0);\r
173         lRVI.setText("Variable: ");\r
174         gd1.applyTo(lRVI);\r
175         tRVI = new Text(c, SWT.BORDER | SWT.READ_ONLY);\r
176         //tRVI.setEnabled(false);\r
177         if ( data.variableReference!=null ) tRVI.setText(URIStringUtils.unescape( data.variableReference ));\r
178         gd2.applyTo(tRVI);\r
179 \r
180         // 3rd line - Label: [chart item label]\r
181         lLabel = new Label(c, 0);\r
182         lLabel.setText("&Label: ");\r
183         gd1.applyTo(lLabel);\r
184         tLabel = new Text(c, SWT.BORDER);\r
185         if ( data.label!=null ) tLabel.setText(data.label);\r
186         gd2.applyTo(tLabel);\r
187 \r
188 //        if (!data.binaryMode) {\r
189 //              // 4th line - DrawMode: [ drop-down-list V ]\r
190 //              lDrawMode = new Label(c, 0);\r
191 //              lDrawMode.setText("DrawMode :");\r
192 //              gd1.applyTo(lDrawMode);\r
193 //              cDrawMode = new Combo(c, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
194 //              for (DrawMode dm : DrawMode.values()) cDrawMode.add( dm.name() );\r
195 //              String _drawmode = data.drawmode!=null ? data.drawmode.toString() : chartnode.get( ChartPreferences.P_DRAWMODE, ChartPreferences.DEFAULT_DRAWMODE ); \r
196 //              cDrawMode.setText( _drawmode );\r
197 //              gd2.applyTo(cDrawMode);\r
198 //        }\r
199 \r
200         if (!data.binaryMode && includeChartSpecificProperties) {\r
201                 // 5th line - Scale: [ Auto/Manual ] Min: [ ## ] Max: [ ## ]\r
202                 lScale = new Label(c, 0);\r
203                 lScale.setText("&Scale: ");\r
204                 gd1.applyTo(lScale);\r
205 \r
206                 Composite scaleComposite = new Composite(c, 0);\r
207                 gd2.applyTo(scaleComposite);\r
208                 GridLayoutFactory.fillDefaults().numColumns(8).applyTo(scaleComposite);\r
209 \r
210                 cScale = new Combo(scaleComposite, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
211                 cScale.add(AUTO);\r
212                 cScale.add(MANUAL);\r
213                 String _scale = data.scale != null ? data.scale.toString() : chartnode.get( ChartPreferences.P_SCALEMODE, ChartPreferences.DEFAULT_SCALEMODE ); \r
214                 cScale.setText( _scale );\r
215                 GridDataFactory.fillDefaults().span(2, 1).applyTo(cScale);\r
216                 \r
217                 lMin = new Label(scaleComposite, 0);\r
218                 lMin.setText("&Min: ");\r
219                 GridDataFactory.fillDefaults().span(1, 1).align(SWT.FILL, SWT.CENTER).applyTo(lMin);\r
220                 tMin = new Text(scaleComposite, SWT.BORDER);\r
221                 Double _min = data.min;\r
222                 if ( _min == null ) _min = chartnode.getDouble( ChartPreferences.P_SCALE_MIN, 0.0);\r
223                 tMin.setText( Double.toString(_min) );\r
224                 GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).indent(5, 0).grab(true, false).span(2, 1).applyTo(tMin);\r
225                 tMin.addModifyListener(new ModifyListener() {\r
226                     @Override\r
227                     public void modifyText(ModifyEvent e) {\r
228                         data.min = parseDouble(tMin, false, 0.0);\r
229                     if (data.min != null)\r
230                         cScale.setText(MANUAL);\r
231                         validate();\r
232                     }\r
233                 });\r
234 \r
235                 lMax = new Label(scaleComposite, 0);\r
236                 lMax.setText("Ma&x: ");\r
237                 GridDataFactory.fillDefaults().span(1, 1).align(SWT.FILL, SWT.CENTER).applyTo(lMax);\r
238                 tMax = new Text(scaleComposite, SWT.BORDER);\r
239                 Double _max = data.max;\r
240                 if ( _max==null ) _max = chartnode.getDouble( ChartPreferences.P_SCALE_MAX, 100.0);\r
241                 tMax.setText( Double.toString(_max) );\r
242                 GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).indent(5, 0).grab(true, false).span(2, 1).applyTo(tMax);\r
243             tMax.addModifyListener(new ModifyListener() {\r
244                 @Override\r
245                 public void modifyText(ModifyEvent e) {\r
246                     data.max = parseDouble(tMax, false, 100.0);\r
247                     if (data.max != null)\r
248                         cScale.setText(MANUAL);\r
249                     validate();\r
250                 }\r
251             });\r
252         }\r
253 \r
254         // 6th line - Subscription: [ Default / others ] [New] \r
255         lSubscription = new Label(c, 0);\r
256         lSubscription.setText("S&ubscription: ");\r
257         gd1.applyTo(lSubscription);\r
258         cSubscription = new Combo(c, SWT.BORDER);\r
259         for (String s : data.subscriptions) cSubscription.add(s);\r
260         gd2.applyTo(cSubscription);\r
261         String _subscription = data.subscription;\r
262         if ( _subscription == null ) _subscription = subscriptionnode.get( SubscriptionPreferences.P_SUBSCRIPTION_DEFAULT, data.subscriptions.length==0 ? "Default" : cSubscription.getItem(0) );\r
263         cSubscription.setText( _subscription );\r
264 \r
265         if (!data.binaryMode) {\r
266                 // 7th line - Deadband: [deadband] Interval: [interval]\r
267                 lDeadband = new Label(c, 0);\r
268                 lDeadband.setText("&Deadband: ");\r
269                 gd1.applyTo(lDeadband);\r
270                 tDeadband = new Text(c, SWT.BORDER);\r
271                 Double _deadband = data.deadband;\r
272                 if ( _deadband == null ) _deadband = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_DEADBAND, SubscriptionPreferences.DEFAULT_SUBSCRIPTION_DEADBAND );\r
273                 tDeadband.setText( Double.toString(_deadband) );\r
274                 tDeadband.setEditable(data.mutableCollectionSettings);\r
275                 GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tDeadband);\r
276             tDeadband.addModifyListener(new ModifyListener() {\r
277                 @Override\r
278                 public void modifyText(ModifyEvent e) {\r
279                     data.deadband = parseDouble(tDeadband, false, 0.0);\r
280                     validate();\r
281                 }\r
282             });\r
283 \r
284                 lInterval = new Label(c, 0);\r
285                 lInterval.setText("&Interval: ");\r
286                 lInterval.setToolTipText("Sampling Interval");\r
287                 GridDataFactory.fillDefaults().span(2, 1).applyTo(lInterval);\r
288                 tInterval = new Text(c, SWT.BORDER);\r
289                 Double _interval = data.interval;\r
290                 if ( _interval == null ) _interval = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_INTERVAL, SubscriptionPreferences.DEFAULT_SUBSCRIPTION_INTERVAL );\r
291                 tInterval.setText( Double.toString(_interval) );\r
292                 tInterval.setEditable(data.mutableCollectionSettings);\r
293                 GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tInterval);\r
294             tInterval.addModifyListener(new ModifyListener() {\r
295                 @Override\r
296                 public void modifyText(ModifyEvent e) {\r
297                     data.interval = parseDouble(tInterval, false, 0.0);\r
298                     validate();\r
299                 }\r
300             });\r
301         }\r
302 \r
303         // 8th line - Gain: [gain] Bias: [bias]\r
304         if (!data.binaryMode) {\r
305                 lGain = new Label(c, 0);\r
306                 lGain.setText("&Gain: ");\r
307                 gd1.applyTo(lGain);\r
308                 tGain = new Text(c, SWT.BORDER);\r
309                 Double _gain = data.gain;\r
310                 if (_gain == null) _gain = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_GAIN, 1.0);\r
311                 tGain.setText( Double.toString(_gain) );\r
312                 GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tGain);\r
313             tGain.addModifyListener(new ModifyListener() {\r
314                 @Override\r
315                 public void modifyText(ModifyEvent e) {\r
316                     data.gain = parseDouble(tGain, false, 1.0);\r
317                     validate();\r
318                 }\r
319             });\r
320 \r
321                 lBias = new Label(c, 0);\r
322                 lBias.setText("&Bias: ");\r
323                 GridDataFactory.fillDefaults().span(2, 1).applyTo(lBias);\r
324                 tBias = new Text(c, SWT.BORDER);\r
325                 Double _bias = data.bias;\r
326                 if (_bias == null) _bias = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_BIAS, 0.0);\r
327                 tBias.setText( Double.toString(_bias) );\r
328                 GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tBias);\r
329             tBias.addModifyListener(new ModifyListener() {\r
330                 @Override\r
331                 public void modifyText(ModifyEvent e) {\r
332                     data.bias = parseDouble(tBias, false, 0.0);\r
333                     validate();\r
334                 }\r
335             });\r
336         }\r
337 \r
338         // 9th line - Unit: [unit]\r
339         if (!data.binaryMode) {\r
340                 lUnit = new Label(c, 0);\r
341                 lUnit.setText("U&nit: ");\r
342                 gd1.applyTo(lUnit);\r
343                 tUnit = new Text(c, SWT.BORDER);\r
344                 String _unit = data.unit;\r
345                 if (_unit==null) _unit = subscriptionnode.get( SubscriptionPreferences.P_SUBSCRIPTION_UNIT, "");\r
346                 tUnit.setText( _unit );\r
347                 GridDataFactory.fillDefaults().hint(100, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tUnit);\r
348                 // Fill line\r
349             GridDataFactory.fillDefaults().span(5, 1).applyTo(new Label(c, 0));\r
350         }\r
351 \r
352         // Disable fields that edit subscription item\r
353         if (!data.hasSubscriptionItem) {\r
354                 tLabel.setEnabled( false );\r
355                 cSubscription.setEnabled( false );\r
356                 tDeadband.setEnabled( false );\r
357                 tInterval.setEnabled( false );\r
358                 tGain.setEnabled( false );\r
359                 tBias.setEnabled( false );\r
360                 tUnit.setEnabled( false );\r
361         }\r
362 \r
363         // 10th line - Color stroke / color\r
364         if (includeChartSpecificProperties) {\r
365             createStrokeGroup(c);\r
366         }\r
367 \r
368         saveAsPrefs = new Button(c, SWT.CHECK);\r
369         saveAsPrefs.setText("Sav&e as new defaults");\r
370         saveAsPrefs.setToolTipText("Sav&e these settings as new defaults");\r
371         // Always unchecked by default.\r
372         saveAsPrefs.setSelection(false);\r
373         GridDataFactory.fillDefaults().hint(100, SWT.DEFAULT).span(9, 1).applyTo(saveAsPrefs);\r
374 \r
375         // Error decorations\r
376         Image image = FieldDecorationRegistry.getDefault()\r
377                 .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR)\r
378                 .getImage();\r
379 \r
380         if (!data.binaryMode) {\r
381             if (includeChartSpecificProperties) {\r
382                 tMinDecor = createDecoration(tMin, SWT.LEFT | SWT.CENTER, image);\r
383                 tMaxDecor = createDecoration(tMax, SWT.LEFT | SWT.CENTER, image);\r
384             }\r
385             tDeadbandDecor = createDecoration(tDeadband, SWT.LEFT | SWT.CENTER, image);\r
386             tIntervalDecor = createDecoration(tInterval, SWT.LEFT | SWT.CENTER, image);\r
387             tGainDecor = createDecoration(tGain, SWT.LEFT | SWT.CENTER, image);\r
388             tBiasDecor = createDecoration(tBias, SWT.LEFT | SWT.CENTER, image);\r
389         }\r
390 \r
391         // Ensure that the data structure contains all the values that were\r
392         // initialized into the UI.\r
393         parseUiToData();\r
394 \r
395         tLabel.setFocus();\r
396     }\r
397 \r
398     private void createStrokeGroup(Composite c) {\r
399         GridDataFactory gd1 = GridDataFactory.fillDefaults().indent(10, 0).align(SWT.FILL, SWT.CENTER).span(1, 1);\r
400 \r
401         Group gStroke = new Group(c, 0);\r
402         gStroke.setText("Trend Line Stroke");\r
403         GridLayoutFactory.fillDefaults().margins(8, 8).spacing(10, 10).numColumns(5).applyTo(gStroke);\r
404         GridDataFactory.fillDefaults().span(9, 1).applyTo(gStroke);\r
405 \r
406         if (!data.binaryMode) {\r
407             // Custom stroke\r
408             Label lStrokeWidth = new Label(gStroke, 0);\r
409             lStrokeWidth.setText("&Width:");\r
410             gd1.applyTo(lStrokeWidth);\r
411             sStrokeWidth = new Spinner(gStroke, SWT.BORDER);\r
412             sStrokeWidth.setDigits(1);\r
413             sStrokeWidth.setIncrement(5);\r
414             sStrokeWidth.setMinimum(10);\r
415             sStrokeWidth.setMaximum(50);\r
416             GridDataFactory.fillDefaults().indent(10, 0).grab(false, false).span(1, 1).applyTo(sStrokeWidth);\r
417 \r
418             if (data.strokeWidth != null) {\r
419                 sStrokeWidth.setSelection((int) (data.strokeWidth * 10));\r
420             }\r
421 \r
422             sStrokeWidth.addSelectionListener(new SelectionAdapter() {\r
423                 @Override\r
424                 public void widgetSelected(SelectionEvent e) {\r
425                     float newWidth = ((float) sStrokeWidth.getSelection()) * 0.1f;\r
426                     data.strokeWidth = newWidth;\r
427                 }\r
428             });\r
429         }\r
430 \r
431         Label lColor = new Label(gStroke, 0);\r
432         lColor.setText("&Color: ");\r
433         gd1.applyTo(lColor);\r
434         colorSelector = new ColorSelector(gStroke);\r
435         GridDataFactory.fillDefaults().indent(10, 0).span(1, 1).grab(false, false).applyTo(colorSelector.getButton());\r
436         final RGB indexColor = toRGB(JarisPaints.getColor(data.index));\r
437         RGB customColor = data.color != null ? toRGB(data.color) : indexColor;\r
438         colorSelector.setColorValue(customColor);\r
439 \r
440         final Button bResetColor = new Button(gStroke, SWT.PUSH);\r
441         bResetColor.setText("Reset Color");\r
442         bResetColor.setToolTipText("Reset Color to Item Index Default");\r
443         bResetColor.setEnabled(!indexColor.equals(customColor));\r
444 \r
445         colorSelector.addListener(new IPropertyChangeListener() {\r
446             @Override\r
447             public void propertyChange(PropertyChangeEvent event) {\r
448                 RGB rgb = colorSelector.getColorValue();\r
449                 data.color = new Color(rgb.red, rgb.green, rgb.blue).getColorComponents(new float[4]);\r
450                 data.color[3] = 1;\r
451                 bResetColor.setEnabled(!indexColor.equals(rgb));\r
452             }\r
453         });\r
454 \r
455         bResetColor.addSelectionListener(new SelectionAdapter() {\r
456             @Override\r
457             public void widgetSelected(SelectionEvent e) {\r
458                 data.color = null;\r
459                 colorSelector.setColorValue(toRGB(JarisPaints.getColor(data.index)));\r
460                 bResetColor.setEnabled(false);\r
461             }\r
462         });\r
463     }\r
464 \r
465     protected RGB toRGB(float[] color) {\r
466         float r = color[0];\r
467         float g = color[1];\r
468         float b = color[2];\r
469         return new RGB( (int) (r*255+0.5), (int) (g*255+0.5), (int) (b*255+0.5) );\r
470     }\r
471 \r
472     protected RGB toRGB(Color color) {\r
473         return new RGB(color.getRed(), color.getGreen(), color.getBlue());\r
474     }\r
475 \r
476     protected ControlDecoration createDecoration(Control control, int position, Image image) {\r
477         ControlDecoration d = new ControlDecoration(control, position);\r
478         d.setMarginWidth(2);\r
479         d.setImage(image);\r
480         d.hide();\r
481         return d;\r
482     }\r
483 \r
484     protected Double parseDouble(Text text, boolean returnDefault, double defaultValue) {\r
485         if (text == null)\r
486             return null;\r
487         try {\r
488             String s = text.getText();\r
489             s = s.replace(',', '.');\r
490             return Double.valueOf(s);\r
491         } catch ( NumberFormatException nfe ) {\r
492             return returnDefault ? defaultValue : null;\r
493         }\r
494     }\r
495 \r
496     protected void parseUiToData() {\r
497         data.label = tLabel.getText();\r
498         if (!data.binaryMode) {\r
499             if (includeChartSpecificProperties) {\r
500                 data.min = parseDouble(tMin, true, 0.0);\r
501                 data.max = parseDouble(tMax, true, 100.0);\r
502             }\r
503             data.interval = parseDouble(tInterval, true, 0.0);\r
504             data.deadband = parseDouble(tDeadband, true, 0.0);\r
505             data.gain = parseDouble(tGain, true, 1.0);\r
506             data.bias = parseDouble(tBias, true, 0.0);\r
507             data.unit = tUnit.getText();\r
508 \r
509             if (includeChartSpecificProperties) {\r
510 //                data.drawmode = DrawMode.valueOf( cDrawMode.getText() );\r
511                 data.drawmode = DrawMode.Line;\r
512 \r
513                 if (cScale.getText().equals("Manual")) {\r
514                     data.scale = new Scale.Manual(data.min, data.max);\r
515                 } else if (cScale.getText().equals("Auto")) {\r
516                     data.scale = new Scale.Auto();\r
517                 }\r
518             }\r
519         }\r
520         data.subscription = cSubscription.getText();\r
521     }\r
522 \r
523     @Override\r
524     protected void buttonPressed(int buttonId) {\r
525         if (ChartDialogConstants.APPLY_ID == buttonId) {\r
526             applyPressed();\r
527         } else {\r
528             super.buttonPressed(buttonId);\r
529         }\r
530     }\r
531 \r
532     private void applyPressed() {\r
533         if (applyAction != null) {\r
534             parseUiToData();\r
535             if (!baseData.equals(data)) {\r
536                 baseData.readFrom(data);\r
537                 applyAction.run();\r
538             }\r
539         }\r
540     }\r
541 \r
542     @Override\r
543     protected void okPressed() {\r
544         boolean savePrefs = saveAsPrefs.getSelection();\r
545         parseUiToData();\r
546 \r
547         if (!data.binaryMode && savePrefs) {\r
548             if (includeChartSpecificProperties) {\r
549                 chartnode.put( ChartPreferences.P_DRAWMODE, data.drawmode.name() );\r
550                 chartnode.put( ChartPreferences.P_SCALEMODE, data.scale instanceof Scale.Manual ? "Manual" : "Auto" );\r
551                 chartnode.putDouble( ChartPreferences.P_SCALE_MIN, data.min );\r
552                 chartnode.putDouble( ChartPreferences.P_SCALE_MAX, data.max );\r
553             }\r
554             subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_DEADBAND, data.deadband );\r
555             subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_INTERVAL, data.interval );\r
556             subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_GAIN, data.gain );\r
557             subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_BIAS, data.bias );\r
558             subscriptionnode.put( SubscriptionPreferences.P_SUBSCRIPTION_UNIT, data.unit );\r
559         }\r
560 \r
561         if (savePrefs)\r
562             subscriptionnode.put( SubscriptionPreferences.P_SUBSCRIPTION_DEFAULT, data.subscription );\r
563 \r
564         if (applyAction != null && !baseData.equals(data))\r
565             applyAction.run();\r
566         super.okPressed();\r
567     }\r
568 \r
569     @Override\r
570     protected void configureShell(Shell newShell) {\r
571         super.configureShell(newShell);\r
572         newShell.setText(\r
573                 includeChartSpecificProperties ? "Edit Chart Item"\r
574                                                : "Edit Subscription Item"\r
575                 );\r
576     }\r
577 \r
578     public void validate() {\r
579         boolean ok = true;\r
580         if (!data.binaryMode) {\r
581             if (includeChartSpecificProperties) {\r
582                 setDecoration(tMinDecor, null);\r
583                 setDecoration(tMaxDecor, null);\r
584                 if (tMin != null && tMax != null) {\r
585                     if (data.min == null || data.max == null) {\r
586                         ok = false;\r
587                         if (data.min == null)\r
588                             setDecoration(tMinDecor, "Invalid non-numeric value");\r
589                         if (data.max == null)\r
590                             setDecoration(tMaxDecor, "Invalid non-numeric value");\r
591                     } else {\r
592                         if (data.min >= data.max) {\r
593                             setDecoration(tMinDecor, "Minimum value must be smaller than maximum value");\r
594                             setDecoration(tMaxDecor, "Maximum value must be larger than minimum value");\r
595                             ok = false;\r
596                         }\r
597                     }\r
598                 }\r
599             }\r
600 \r
601             ok &= data.interval != null && data.deadband != null && data.bias != null && data.gain != null;\r
602             setDecoration(tIntervalDecor, data.interval == null ? "Invalid non-numeric value" : null);\r
603             if (data.interval != null && data.interval < 0)\r
604                 setDecoration(tIntervalDecor, "Sampling interval cannot be negative");\r
605             setDecoration(tDeadbandDecor, data.deadband == null ? "Invalid non-numeric value" : null);\r
606             if (data.deadband != null && data.deadband < 0)\r
607                 setDecoration(tDeadbandDecor, "Deadband cannot be negative");\r
608             setDecoration(tGainDecor, data.gain == null ? "Invalid non-numeric value" : null);\r
609             setDecoration(tBiasDecor, data.bias == null ? "Invalid non-numeric value" : null);\r
610         }\r
611         setFinishable(ok);\r
612     }\r
613 \r
614     private void setDecoration(ControlDecoration decor, String desc) {\r
615         if (decor == null)\r
616             return;\r
617         if (desc != null) {\r
618             decor.setDescriptionText(desc);\r
619             decor.show();\r
620         } else {\r
621             decor.hide();\r
622         }\r
623     }\r
624 \r
625     protected void setFinishable(boolean ok) {\r
626         getButton(OK).setEnabled(ok);\r
627     }\r
628 \r
629 }\r