]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartDialog.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.charts / src / org / simantics / charts / ui / ChartDialog.java
1 package org.simantics.charts.ui;\r
2 \r
3 import java.awt.Color;\r
4 import java.text.Format;\r
5 import java.util.ArrayList;\r
6 import java.util.List;\r
7 import java.util.Set;\r
8 \r
9 import org.eclipse.core.runtime.IStatus;\r
10 import org.eclipse.core.runtime.Status;\r
11 import org.eclipse.jface.dialogs.Dialog;\r
12 import org.eclipse.jface.fieldassist.ControlDecoration;\r
13 import org.eclipse.jface.fieldassist.FieldDecorationRegistry;\r
14 import org.eclipse.jface.layout.GridDataFactory;\r
15 import org.eclipse.jface.layout.GridLayoutFactory;\r
16 import org.eclipse.jface.preference.ColorSelector;\r
17 import org.eclipse.jface.viewers.ArrayContentProvider;\r
18 import org.eclipse.jface.viewers.DoubleClickEvent;\r
19 import org.eclipse.jface.viewers.IDoubleClickListener;\r
20 import org.eclipse.jface.viewers.ISelection;\r
21 import org.eclipse.jface.viewers.LabelProvider;\r
22 import org.eclipse.jface.viewers.ListViewer;\r
23 import org.eclipse.swt.SWT;\r
24 import org.eclipse.swt.events.KeyAdapter;\r
25 import org.eclipse.swt.events.KeyEvent;\r
26 import org.eclipse.swt.events.ModifyEvent;\r
27 import org.eclipse.swt.events.ModifyListener;\r
28 import org.eclipse.swt.events.SelectionAdapter;\r
29 import org.eclipse.swt.events.SelectionEvent;\r
30 import org.eclipse.swt.graphics.Image;\r
31 import org.eclipse.swt.graphics.RGB;\r
32 import org.eclipse.swt.widgets.Button;\r
33 import org.eclipse.swt.widgets.Combo;\r
34 import org.eclipse.swt.widgets.Composite;\r
35 import org.eclipse.swt.widgets.Control;\r
36 import org.eclipse.swt.widgets.Group;\r
37 import org.eclipse.swt.widgets.Label;\r
38 import org.eclipse.swt.widgets.Scale;\r
39 import org.eclipse.swt.widgets.Shell;\r
40 import org.eclipse.swt.widgets.Text;\r
41 import org.simantics.Simantics;\r
42 import org.simantics.charts.Activator;\r
43 import org.simantics.charts.query.ChartAndSubscriptionItemData;\r
44 import org.simantics.charts.query.ChartAndSubscriptionItemReadQuery;\r
45 import org.simantics.charts.ui.ChartData.ItemKey;\r
46 import org.simantics.db.exception.DatabaseException;\r
47 import org.simantics.modeling.ui.chart.property.ChartComposite;\r
48 import org.simantics.trend.configuration.TrendItem;\r
49 import org.simantics.trend.configuration.YAxisMode;\r
50 import org.simantics.trend.impl.Plot;\r
51 import org.simantics.utils.format.TimeFormat;\r
52 import org.simantics.utils.ui.ISelectionUtils;\r
53 \r
54 /**\r
55  * Dialog for chart properties:\r
56  * \r
57  * <pre>\r
58  * Name:             [ Process ]\r
59  * Time Start:       [   ]\r
60  * Length:           [   ]\r
61  * Scroll Increment: [--|--] n%\r
62  * Axis Mode:        [Single/Multi]\r
63  * [ ] Hairline Tracks Experiment Time\r
64  * \r
65  * --- Styling ------------------------------------------\r
66  * | [ ] Background Vertical Gradient {color1} {color2} |\r
67  * | [ ] Show Grid                    {grid color}      |\r
68  * | [ ] Show Milestones                                |\r
69  * ------------------------------------------------------\r
70  * \r
71  * --- Item visibility ---------------\r
72  * | Visible          Hidden         |\r
73  * | -----------      -------------- |\r
74  * | |         | HIDE |            | |\r
75  * | |         | SHOW |            | |\r
76  * | -----------      -------------- |\r
77  * -----------------------------------\r
78  * </pre>\r
79  * \r
80  * @author toni.kalajainen@semantum.fi\r
81  * @author Tuukka Lehtonen\r
82  */\r
83 public class ChartDialog extends Dialog {\r
84 \r
85     private static final RGB DEFAULT_BG_COLOR1 = toRGB(Plot.PLOT_AREA_BG_GRADIENT_COLOR_BOTTOM.getColorComponents(new float[3]), null);\r
86     private static final RGB DEFAULT_BG_COLOR2 = toRGB(Plot.PLOT_AREA_BG_GRADIENT_COLOR_TOP.getColorComponents(new float[3]), null);\r
87     private static final RGB DEFAULT_GRID_COLOR = toRGB(Plot.GRID_LINE_COLOR.getColorComponents(new float[3]), null);\r
88 \r
89     Format timeFormat = new TimeFormat(100, 3);\r
90 \r
91     // UI\r
92     Label lName, lStartTime, lLength, lScrollIncrement, lAxisMode;\r
93     Text tName, tStartTime, tLength;\r
94     Scale sIncrement;\r
95     Combo cAxisMode;\r
96     Button bBackgroundGradient;\r
97     ColorSelector backgroundColor1;\r
98     ColorSelector backgroundColor2;\r
99     Button bShowGrid;\r
100     ColorSelector gridColor;\r
101     Button bMilestones;\r
102     Button bTrackExperimentTime;\r
103     ListViewer lVisibleItems;\r
104     ListViewer lHiddenItems;\r
105 \r
106     ControlDecoration tStartTimeDecor;\r
107     ControlDecoration tLengthDecor;\r
108 \r
109     final ChartData baseData = new ChartData();\r
110     final ChartData data;\r
111     final Runnable applyAction;\r
112 \r
113     /**\r
114      * Set when a chart item dialog has previously been opened by this dialog.\r
115      */\r
116     ChartAndSubscriptionItemDialog currentItemDialog = null;\r
117 \r
118     public ChartDialog(Shell parentShell, ChartData data, Runnable applyAction) {\r
119         super(parentShell);\r
120         this.data = data;\r
121         this.baseData.readFrom(data);\r
122         this.applyAction = applyAction;\r
123         setShellStyle(SWT.RESIZE | SWT.TITLE | SWT.CLOSE | SWT.BORDER);\r
124     }\r
125 \r
126     @Override\r
127     protected void createButtonsForButtonBar(Composite parent) {\r
128         if (applyAction != null)\r
129             createButton(parent, ChartDialogConstants.APPLY_ID, ChartDialogConstants.APPLY_LABEL, true);\r
130         super.createButtonsForButtonBar(parent);\r
131     }\r
132 \r
133     @Override\r
134     protected Control createDialogArea(Composite parent) {\r
135         Composite c = (Composite) super.createDialogArea(parent);\r
136         GridLayoutFactory.fillDefaults().margins(8, 8).numColumns(9).applyTo(c);\r
137         createDialogAreaContents(c);\r
138         return c;\r
139     }\r
140 \r
141     protected void createDialogAreaContents(Composite c) {\r
142         GridDataFactory gd1 = GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(1, 1);\r
143         GridDataFactory gd2 = GridDataFactory.fillDefaults().indent(5, 0).grab(true, false).span(8, 1);\r
144 \r
145         // 1st line - Chart: [chart name]\r
146         lName = new Label(c, 0);\r
147         lName.setText("&Name:");\r
148         gd1.applyTo(lName);\r
149         tName = new Text(c, SWT.BORDER);\r
150         tName.setEnabled( true );\r
151         if ( data.name != null ) tName.setText( data.name );\r
152         gd2.applyTo(tName);\r
153 \r
154         // 2nd line - start time + length\r
155         Label l = new Label(c, 0);\r
156         l.setText("Chart Time Window Preference (Auto-scale)");\r
157         GridDataFactory.fillDefaults().span(9, 1).applyTo(l);\r
158 \r
159         lStartTime = new Label(c, 0);\r
160         lStartTime.setText("&Time Start:");\r
161         gd1.applyTo(lStartTime);\r
162         tStartTime = new Text(c, SWT.BORDER);\r
163         tStartTime.setToolTipText("Chart Window Fixed Start Time in Seconds or Yy Dd HH:mm:ss.ddd");\r
164         if ( data.timeStart!=null ) {\r
165             String str = timeFormat.format(data.timeStart);\r
166             tStartTime.setText(str);\r
167         }\r
168         gd2.applyTo(tStartTime);\r
169         tStartTime.addModifyListener(new ModifyListener() {\r
170             @Override\r
171             public void modifyText(ModifyEvent e) {\r
172                 data.timeStart = parseTime(tStartTime, false, 0.0);\r
173                 validate();\r
174             }\r
175         });\r
176 \r
177         lLength = new Label(c, 0);\r
178         lLength.setText("&Length:");\r
179         gd1.applyTo(lLength);\r
180         tLength = new Text(c, SWT.BORDER);\r
181         tLength.setToolTipText("Chart Window Fixed Time Axis Length in Seconds or Yy Dd HH:mm:ss.ddd");\r
182         if ( data.timeLength!=null ) {\r
183             String str = timeFormat.format(data.timeLength);\r
184             tLength.setText(str);\r
185         }\r
186         gd2.applyTo(tLength);\r
187         tLength.addModifyListener(new ModifyListener() {\r
188             @Override\r
189             public void modifyText(ModifyEvent e) {\r
190                 data.timeLength = parseTime(tLength, false, 0.0);\r
191                 validate();\r
192             }\r
193         });\r
194 \r
195         // 3rd line - Increment scrollbar\r
196         lScrollIncrement = new Label(c, 0);\r
197         lScrollIncrement.setText("Scroll Increment:");\r
198         gd1.applyTo(lScrollIncrement);\r
199         sIncrement = new Scale(c, SWT.HORIZONTAL);\r
200         sIncrement.setMinimum(1);\r
201         sIncrement.setMaximum(100);\r
202         sIncrement.setIncrement(10);\r
203         sIncrement.setPageIncrement(10);\r
204         if (data.timeIncrement!=null) {\r
205             sIncrement.setSelection( (int) (double) data.timeIncrement );\r
206         }\r
207         gd2.copy().span(7, 1).applyTo(sIncrement);\r
208         final Text sIncrementText = new Text(c, SWT.READ_ONLY | SWT.RIGHT);\r
209         gd1.copy().hint(35, SWT.DEFAULT).applyTo(sIncrementText);\r
210         sIncrement.addSelectionListener(new SelectionAdapter() {\r
211             @Override\r
212             public void widgetSelected(SelectionEvent e) {\r
213                 sIncrementText.setText(sIncrement.getSelection() + " %");\r
214             }\r
215         });\r
216         sIncrementText.setText(sIncrement.getSelection() + " %");\r
217 \r
218         // 4th line -- AxisMode + Milestone\r
219         lAxisMode = new Label(c, 0);\r
220         lAxisMode.setText("A&xis Mode:");\r
221         gd1.applyTo(lAxisMode);\r
222         cAxisMode = new Combo(c, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
223         GridDataFactory.fillDefaults().indent(5, 0).span(1, 1).applyTo(cAxisMode);\r
224         cAxisMode.add("Single");\r
225         cAxisMode.add("Multi");\r
226         String _mode = data.axisMode==YAxisMode.SingleAxis ? "Single" : "Multi"; \r
227         cAxisMode.setText( _mode );\r
228         // Filler\r
229         GridDataFactory.fillDefaults().span(7, 1).applyTo(new Label(c, 0));\r
230 \r
231         bTrackExperimentTime = new Button(c, SWT.CHECK);\r
232         bTrackExperimentTime.setText("Ha&irline Tracks Experiment Time");\r
233         bTrackExperimentTime.setSelection( data.trackExperimentTime );\r
234         GridDataFactory.fillDefaults().span(9, 1).applyTo(bTrackExperimentTime);\r
235 \r
236         // Styling group begins\r
237 \r
238         Group gStyling = new Group(c, 0);\r
239         gStyling.setText("Styling");\r
240         GridDataFactory.fillDefaults().indent(0, 5).grab(true, true).span(9, 1).applyTo(gStyling);\r
241         GridLayoutFactory.fillDefaults().margins(8, 8).numColumns(4).applyTo(gStyling);\r
242 \r
243         // Background color settings\r
244         {\r
245             bBackgroundGradient = new Button(gStyling, SWT.CHECK);\r
246             bBackgroundGradient.setText("&Background Vertical Gradient");\r
247             bBackgroundGradient.setToolTipText("Solid Color or Vertical Gradient");\r
248             bBackgroundGradient.setSelection(data.backgroundGradient);\r
249             bBackgroundGradient.addSelectionListener(new SelectionAdapter() {\r
250                 @Override\r
251                 public void widgetSelected(SelectionEvent e) {\r
252                     data.backgroundGradient = bBackgroundGradient.getSelection();\r
253                     setBackgroundGradient(data.backgroundGradient);\r
254                 }\r
255             });\r
256             GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(bBackgroundGradient);\r
257 \r
258             backgroundColor1 = new ColorSelector(gStyling);\r
259             backgroundColor2 = new ColorSelector(gStyling);\r
260             backgroundColor1.getButton().setToolTipText("Select Gradient Bottom Color");\r
261             backgroundColor2.getButton().setToolTipText("Select Gradient Top Color");\r
262             GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(backgroundColor1.getButton());\r
263             GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(backgroundColor2.getButton());\r
264             backgroundColor1.setColorValue(toRGB(data.backgroundColor1, DEFAULT_BG_COLOR1));\r
265             backgroundColor2.setColorValue(toRGB(data.backgroundColor2, DEFAULT_BG_COLOR2));\r
266             setBackgroundGradient(data.backgroundGradient);\r
267 \r
268             Button bResetBackgroundColors = new Button(gStyling, SWT.PUSH);\r
269             bResetBackgroundColors.setText("Reset");\r
270             bResetBackgroundColors.setToolTipText("Reset Background Color to Default");\r
271             bResetBackgroundColors.addSelectionListener(new SelectionAdapter() {\r
272                 public void widgetSelected(SelectionEvent e) {\r
273                     backgroundColor1.setColorValue(toRGB(null, DEFAULT_BG_COLOR1));\r
274                     backgroundColor2.setColorValue(toRGB(null, DEFAULT_BG_COLOR2));\r
275                 }\r
276             });\r
277         }\r
278 \r
279         // Grid settings\r
280         {\r
281             bShowGrid = new Button(gStyling, SWT.CHECK);\r
282             bShowGrid.setText("Show &Grid");\r
283             bShowGrid.setToolTipText("Toggle Background Grid Visibility");\r
284             bShowGrid.setSelection(data.showGrid);\r
285             GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(bShowGrid);\r
286 \r
287             gridColor = new ColorSelector(gStyling);\r
288             gridColor.getButton().setToolTipText("Select Grid Color");\r
289             GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(gridColor.getButton());\r
290             gridColor.setColorValue(toRGB(data.gridColor, DEFAULT_GRID_COLOR));\r
291 \r
292             Button bResetGridColor = new Button(gStyling, SWT.PUSH);\r
293             bResetGridColor.setText("Reset");\r
294             bResetGridColor.setToolTipText("Reset Grid Color to Default");\r
295             bResetGridColor.addSelectionListener(new SelectionAdapter() {\r
296                 public void widgetSelected(SelectionEvent e) {\r
297                     gridColor.setColorValue(toRGB(null, DEFAULT_GRID_COLOR));\r
298                 }\r
299             });\r
300         }\r
301 \r
302         // Grid settings\r
303         {\r
304             GridDataFactory.fillDefaults().span(1, 1).applyTo(new Label(gStyling, 0));\r
305             bMilestones = new Button(gStyling, SWT.CHECK);\r
306             bMilestones.setText("Show &Milestones");\r
307             bMilestones.setToolTipText("Toggle Milestone Event Visibility");\r
308             bMilestones.setSelection( data.showMilestones );\r
309             GridDataFactory.fillDefaults().indent(0, 0).span(4, 1).applyTo(bMilestones);\r
310         }\r
311 \r
312         // Item visibility group begins\r
313 \r
314         Group gItemVisibility = new Group(c, 0);\r
315         gItemVisibility.setText("Item Visibility");\r
316         GridDataFactory.fillDefaults().indent(0, 5).grab(true, true).span(9, 1).applyTo(gItemVisibility);\r
317         GridLayoutFactory.fillDefaults().margins(8, 8).numColumns(3).applyTo(gItemVisibility);\r
318 \r
319         Label visible = new Label(gItemVisibility, 0);\r
320         visible.setText("Visible");\r
321         GridDataFactory.fillDefaults().grab(true, false).applyTo(visible);\r
322         new Label(gItemVisibility, 0);\r
323         Label hidden = new Label(gItemVisibility, 0);\r
324         hidden.setText("Hidden");\r
325         GridDataFactory.fillDefaults().grab(true, false).applyTo(hidden);\r
326 \r
327         lVisibleItems = new ListViewer(gItemVisibility, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);\r
328         GridDataFactory.fillDefaults().hint(200, 200).grab(true, true).applyTo(lVisibleItems.getControl());\r
329         Composite addRemoveButtons = new Composite(gItemVisibility, 0);\r
330         GridLayoutFactory.fillDefaults().numColumns(1).applyTo(addRemoveButtons);\r
331         GridDataFactory.fillDefaults().grab(false, true).span(1, 1).applyTo(addRemoveButtons);\r
332         Button hideButton = new Button(addRemoveButtons, SWT.PUSH);\r
333         hideButton.setText("&Hide \u2192");\r
334         GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(hideButton);\r
335         Button showButton = new Button(addRemoveButtons, SWT.PUSH);\r
336         showButton.setText("\u2190 &Show");\r
337         GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(showButton);\r
338         lHiddenItems = new ListViewer(gItemVisibility, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);\r
339         GridDataFactory.fillDefaults().hint(200, 200).grab(true, true).applyTo(lHiddenItems.getControl());\r
340 \r
341         lVisibleItems.addDoubleClickListener(new OpenChartItemProperties());\r
342         lVisibleItems.setContentProvider(new ItemContentProvider(false));\r
343         lHiddenItems.addDoubleClickListener(new OpenChartItemProperties());\r
344         lHiddenItems.setContentProvider(new ItemContentProvider(true));\r
345         lVisibleItems.setLabelProvider(new ItemLabeler());\r
346         lHiddenItems.setLabelProvider(new ItemLabeler());\r
347         lVisibleItems.setInput(data);\r
348         lHiddenItems.setInput(data);\r
349 \r
350         lVisibleItems.getList().addKeyListener(new SelectAllListener(lVisibleItems));\r
351         lHiddenItems.getList().addKeyListener(new SelectAllListener(lHiddenItems));\r
352         showButton.addSelectionListener(new ShowHideListener(false));\r
353         hideButton.addSelectionListener(new ShowHideListener(true));\r
354 \r
355         Image image = FieldDecorationRegistry.getDefault()\r
356                 .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR)\r
357                 .getImage();\r
358 \r
359         tStartTimeDecor = createDecoration(tStartTime, SWT.LEFT | SWT.CENTER, image);\r
360         tLengthDecor = createDecoration(tLength, SWT.LEFT | SWT.CENTER, image);\r
361     }\r
362 \r
363     class ShowHideListener extends SelectionAdapter {\r
364         private boolean hide;\r
365 \r
366         public ShowHideListener(boolean hide) {\r
367             this.hide = hide;\r
368         }\r
369 \r
370         @Override\r
371         public void widgetSelected(SelectionEvent e) {\r
372             ISelection selection = hide ? lVisibleItems.getSelection() : lHiddenItems.getSelection();\r
373             Set<ItemKey> selected = ISelectionUtils.filterSetSelection(selection, ItemKey.class);\r
374             if (!selected.isEmpty()) {\r
375                 if (hide) {\r
376                     data.hiddenItems.addAll(selected);\r
377                 } else {\r
378                     data.hiddenItems.removeAll(selected);\r
379                 }\r
380                 lVisibleItems.refresh();\r
381                 lHiddenItems.refresh();\r
382             }\r
383         }\r
384     }\r
385 \r
386     static class SelectAllListener extends KeyAdapter {\r
387         private ListViewer list;\r
388 \r
389         public SelectAllListener(ListViewer list) {\r
390             this.list = list;\r
391         }\r
392 \r
393         @Override\r
394         public void keyPressed(KeyEvent e) {\r
395             if (e.stateMask == SWT.CTRL && e.keyCode == 'a') {\r
396                 list.getList().selectAll();\r
397             }\r
398         }\r
399     };\r
400 \r
401     class ItemContentProvider extends ArrayContentProvider {\r
402         private final boolean expectedHidden;\r
403 \r
404         public ItemContentProvider(boolean expectedHidden) {\r
405             this.expectedHidden = expectedHidden;\r
406         }\r
407 \r
408         @Override\r
409         public Object[] getElements(Object inputElement) {\r
410             List<Object> result = new ArrayList<>();\r
411             for (ItemKey item : data.allItems.keySet())\r
412                 if (data.hiddenItems.contains(item) == expectedHidden)\r
413                     result.add(item);\r
414             return result.toArray();\r
415         }\r
416     }\r
417 \r
418     private void setBackgroundGradient(boolean backgroundGradient) {\r
419         backgroundColor2.setEnabled(backgroundGradient);\r
420         backgroundColor1.getButton().setToolTipText(backgroundGradient ? "Select Gradient Bottom Color" : "Select Solid Color");\r
421     }\r
422 \r
423     protected Double parseTime(Text text, boolean returnDefault, double defaultValue) {\r
424         if (text == null)\r
425             return null;\r
426         String s = text.getText();\r
427         Double time = ChartComposite.START_VALIDATOR.parse(s);\r
428         if (time == null)\r
429             return returnDefault ? defaultValue : null;\r
430         return time;\r
431     }\r
432 \r
433     protected ControlDecoration createDecoration(Control control, int position, Image image) {\r
434         ControlDecoration d = new ControlDecoration(control, position);\r
435         d.setMarginWidth(2);\r
436         d.setImage(image);\r
437         d.hide();\r
438         return d;\r
439     }\r
440 \r
441     class ItemLabeler extends LabelProvider {\r
442         @Override\r
443         public String getText(Object element) {\r
444             ItemKey item = (ItemKey) element;\r
445             TrendItem ti = data.allItems.get(item);\r
446             return ti.label;\r
447         }\r
448     }\r
449 \r
450     protected void parseUiToData() {\r
451         data.name = tName.getText();\r
452         data.backgroundColor1 = toColorComponents( backgroundColor1.getColorValue() );\r
453         data.backgroundColor2 = toColorComponents( backgroundColor2.getColorValue() );\r
454         data.showGrid = bShowGrid.getSelection();\r
455         data.gridColor = toColorComponents( gridColor.getColorValue() );\r
456         data.showMilestones = bMilestones.getSelection();\r
457         data.trackExperimentTime = bTrackExperimentTime.getSelection();\r
458         data.axisMode = cAxisMode.getSelectionIndex()==0?YAxisMode.SingleAxis:YAxisMode.MultiAxis;\r
459         data.timeIncrement = (double) sIncrement.getSelection();\r
460         data.timeLength = ChartComposite.LENGTH_VALIDATOR.parse(tLength.getText());\r
461         data.timeStart = ChartComposite.START_VALIDATOR.parse(tStartTime.getText());\r
462     }\r
463 \r
464     @Override\r
465     protected void buttonPressed(int buttonId) {\r
466         if (ChartDialogConstants.APPLY_ID == buttonId) {\r
467             applyPressed();\r
468         } else {\r
469             super.buttonPressed(buttonId);\r
470         }\r
471     }\r
472 \r
473     private void applyPressed() {\r
474         if (applyAction != null) {\r
475             parseUiToData();\r
476             if (!baseData.equals(data)) {\r
477                 baseData.readFrom(data);\r
478                 applyAction.run();\r
479             }\r
480         }\r
481     }\r
482 \r
483     @Override\r
484     protected void okPressed() {\r
485         parseUiToData();\r
486         if (applyAction != null && !baseData.equals(data))\r
487             applyAction.run();\r
488         super.okPressed();\r
489     }\r
490 \r
491     @Override\r
492     protected void configureShell(Shell newShell) {\r
493         super.configureShell(newShell);\r
494         newShell.setText("Edit Chart");\r
495     }\r
496 \r
497     public void validate() {\r
498         String startTimeError = ChartComposite.START_VALIDATOR.isValid(tStartTime.getText());\r
499         String lengthError = ChartComposite.LENGTH_VALIDATOR.isValid(tLength.getText());\r
500         setDecoration(tStartTimeDecor, startTimeError);\r
501         setDecoration(tLengthDecor, lengthError);\r
502         boolean ok = startTimeError == null && lengthError == null;\r
503         setFinishable(ok);\r
504     }\r
505 \r
506     private void setDecoration(ControlDecoration decor, String desc) {\r
507         if (decor == null)\r
508             return;\r
509         if (desc != null) {\r
510             decor.setDescriptionText(desc);\r
511             decor.show();\r
512         } else {\r
513             decor.hide();\r
514         }\r
515     }\r
516 \r
517     protected void setFinishable(boolean ok) {\r
518         getButton(OK).setEnabled(ok);\r
519     }\r
520 \r
521     private static RGB toRGB(float[] components, RGB defaultValue) {\r
522         if (components == null || components.length < 3)\r
523             return defaultValue;\r
524         Color c = new Color(components[0], components[1], components[2]);\r
525         return new RGB(c.getRed(), c.getGreen(), c.getBlue());\r
526     }\r
527 \r
528     private static float[] toColorComponents(RGB rgb) {\r
529         return new Color(rgb.red, rgb.green, rgb.blue).getColorComponents(new float[3]);\r
530     }\r
531 \r
532     class OpenChartItemProperties implements IDoubleClickListener {\r
533         @Override\r
534         public void doubleClick(DoubleClickEvent event) {\r
535             final ItemKey item = ISelectionUtils.filterSingleSelection(event.getSelection(), ItemKey.class);\r
536             if (item == null)\r
537                 return;\r
538             try {\r
539                 final ChartAndSubscriptionItemData data = Simantics.getSession().syncRequest(\r
540                         new ChartAndSubscriptionItemReadQuery(item.resource.getResource()));\r
541                 if (currentItemDialog != null && currentItemDialog.getShell() != null && !currentItemDialog.getShell().isDisposed()) {\r
542                     // TODO: reinitialize existing dialog with the specified data.\r
543                     // Close current dialog before opening new one.\r
544                     currentItemDialog.close();\r
545                 }\r
546                 currentItemDialog = ChartDoubleClickHandler.openChartItemPropertiesDialog(\r
547                         event.getViewer().getControl().getShell(),\r
548                         item.resource.getResource(),\r
549                         data,\r
550                         false);\r
551             } catch (DatabaseException e) {\r
552                 Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Problems opening chart item property dialog."));\r
553             }\r
554         }\r
555     }\r
556 \r
557 }\r