--- /dev/null
+package org.simantics.charts.ui;\r
+\r
+import java.awt.Color;\r
+import java.text.Format;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.jface.dialogs.Dialog;\r
+import org.eclipse.jface.fieldassist.ControlDecoration;\r
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.preference.ColorSelector;\r
+import org.eclipse.jface.viewers.ArrayContentProvider;\r
+import org.eclipse.jface.viewers.DoubleClickEvent;\r
+import org.eclipse.jface.viewers.IDoubleClickListener;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.ListViewer;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.KeyAdapter;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Scale;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.Simantics;\r
+import org.simantics.charts.Activator;\r
+import org.simantics.charts.query.ChartAndSubscriptionItemData;\r
+import org.simantics.charts.query.ChartAndSubscriptionItemReadQuery;\r
+import org.simantics.charts.ui.ChartData.ItemKey;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.modeling.ui.chart.property.ChartComposite;\r
+import org.simantics.trend.configuration.TrendItem;\r
+import org.simantics.trend.configuration.YAxisMode;\r
+import org.simantics.trend.impl.Plot;\r
+import org.simantics.utils.format.TimeFormat;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Dialog for chart properties:\r
+ * \r
+ * <pre>\r
+ * Name: [ Process ]\r
+ * Time Start: [ ]\r
+ * Length: [ ]\r
+ * Scroll Increment: [--|--] n%\r
+ * Axis Mode: [Single/Multi]\r
+ * [ ] Hairline Tracks Experiment Time\r
+ * \r
+ * --- Styling ------------------------------------------\r
+ * | [ ] Background Vertical Gradient {color1} {color2} |\r
+ * | [ ] Show Grid {grid color} |\r
+ * | [ ] Show Milestones |\r
+ * ------------------------------------------------------\r
+ * \r
+ * --- Item visibility ---------------\r
+ * | Visible Hidden |\r
+ * | ----------- -------------- |\r
+ * | | | HIDE | | |\r
+ * | | | SHOW | | |\r
+ * | ----------- -------------- |\r
+ * -----------------------------------\r
+ * </pre>\r
+ * \r
+ * @author toni.kalajainen@semantum.fi\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class ChartDialog extends Dialog {\r
+\r
+ private static final RGB DEFAULT_BG_COLOR1 = toRGB(Plot.PLOT_AREA_BG_GRADIENT_COLOR_BOTTOM.getColorComponents(new float[3]), null);\r
+ private static final RGB DEFAULT_BG_COLOR2 = toRGB(Plot.PLOT_AREA_BG_GRADIENT_COLOR_TOP.getColorComponents(new float[3]), null);\r
+ private static final RGB DEFAULT_GRID_COLOR = toRGB(Plot.GRID_LINE_COLOR.getColorComponents(new float[3]), null);\r
+\r
+ Format timeFormat = new TimeFormat(100, 3);\r
+\r
+ // UI\r
+ Label lName, lStartTime, lLength, lScrollIncrement, lAxisMode;\r
+ Text tName, tStartTime, tLength;\r
+ Scale sIncrement;\r
+ Combo cAxisMode;\r
+ Button bBackgroundGradient;\r
+ ColorSelector backgroundColor1;\r
+ ColorSelector backgroundColor2;\r
+ Button bShowGrid;\r
+ ColorSelector gridColor;\r
+ Button bMilestones;\r
+ Button bTrackExperimentTime;\r
+ ListViewer lVisibleItems;\r
+ ListViewer lHiddenItems;\r
+\r
+ ControlDecoration tStartTimeDecor;\r
+ ControlDecoration tLengthDecor;\r
+\r
+ final ChartData baseData = new ChartData();\r
+ final ChartData data;\r
+ final Runnable applyAction;\r
+\r
+ /**\r
+ * Set when a chart item dialog has previously been opened by this dialog.\r
+ */\r
+ ChartAndSubscriptionItemDialog currentItemDialog = null;\r
+\r
+ public ChartDialog(Shell parentShell, ChartData data, Runnable applyAction) {\r
+ super(parentShell);\r
+ this.data = data;\r
+ this.baseData.readFrom(data);\r
+ this.applyAction = applyAction;\r
+ setShellStyle(SWT.RESIZE | SWT.TITLE | SWT.CLOSE | SWT.BORDER);\r
+ }\r
+\r
+ @Override\r
+ protected void createButtonsForButtonBar(Composite parent) {\r
+ if (applyAction != null)\r
+ createButton(parent, ChartDialogConstants.APPLY_ID, ChartDialogConstants.APPLY_LABEL, true);\r
+ super.createButtonsForButtonBar(parent);\r
+ }\r
+\r
+ @Override\r
+ protected Control createDialogArea(Composite parent) {\r
+ Composite c = (Composite) super.createDialogArea(parent);\r
+ GridLayoutFactory.fillDefaults().margins(8, 8).numColumns(9).applyTo(c);\r
+ createDialogAreaContents(c);\r
+ return c;\r
+ }\r
+\r
+ protected void createDialogAreaContents(Composite c) {\r
+ GridDataFactory gd1 = GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(1, 1);\r
+ GridDataFactory gd2 = GridDataFactory.fillDefaults().indent(5, 0).grab(true, false).span(8, 1);\r
+\r
+ // 1st line - Chart: [chart name]\r
+ lName = new Label(c, 0);\r
+ lName.setText("&Name:");\r
+ gd1.applyTo(lName);\r
+ tName = new Text(c, SWT.BORDER);\r
+ tName.setEnabled( true );\r
+ if ( data.name != null ) tName.setText( data.name );\r
+ gd2.applyTo(tName);\r
+\r
+ // 2nd line - start time + length\r
+ Label l = new Label(c, 0);\r
+ l.setText("Chart Time Window Preference (Auto-scale)");\r
+ GridDataFactory.fillDefaults().span(9, 1).applyTo(l);\r
+\r
+ lStartTime = new Label(c, 0);\r
+ lStartTime.setText("&Time Start:");\r
+ gd1.applyTo(lStartTime);\r
+ tStartTime = new Text(c, SWT.BORDER);\r
+ tStartTime.setToolTipText("Chart Window Fixed Start Time in Seconds or Yy Dd HH:mm:ss.ddd");\r
+ if ( data.timeStart!=null ) {\r
+ String str = timeFormat.format(data.timeStart);\r
+ tStartTime.setText(str);\r
+ }\r
+ gd2.applyTo(tStartTime);\r
+ tStartTime.addModifyListener(new ModifyListener() {\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ data.timeStart = parseTime(tStartTime, false, 0.0);\r
+ validate();\r
+ }\r
+ });\r
+\r
+ lLength = new Label(c, 0);\r
+ lLength.setText("&Length:");\r
+ gd1.applyTo(lLength);\r
+ tLength = new Text(c, SWT.BORDER);\r
+ tLength.setToolTipText("Chart Window Fixed Time Axis Length in Seconds or Yy Dd HH:mm:ss.ddd");\r
+ if ( data.timeLength!=null ) {\r
+ String str = timeFormat.format(data.timeLength);\r
+ tLength.setText(str);\r
+ }\r
+ gd2.applyTo(tLength);\r
+ tLength.addModifyListener(new ModifyListener() {\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ data.timeLength = parseTime(tLength, false, 0.0);\r
+ validate();\r
+ }\r
+ });\r
+\r
+ // 3rd line - Increment scrollbar\r
+ lScrollIncrement = new Label(c, 0);\r
+ lScrollIncrement.setText("Scroll Increment:");\r
+ gd1.applyTo(lScrollIncrement);\r
+ sIncrement = new Scale(c, SWT.HORIZONTAL);\r
+ sIncrement.setMinimum(1);\r
+ sIncrement.setMaximum(100);\r
+ sIncrement.setIncrement(10);\r
+ sIncrement.setPageIncrement(10);\r
+ if (data.timeIncrement!=null) {\r
+ sIncrement.setSelection( (int) (double) data.timeIncrement );\r
+ }\r
+ gd2.copy().span(7, 1).applyTo(sIncrement);\r
+ final Text sIncrementText = new Text(c, SWT.READ_ONLY | SWT.RIGHT);\r
+ gd1.copy().hint(35, SWT.DEFAULT).applyTo(sIncrementText);\r
+ sIncrement.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ sIncrementText.setText(sIncrement.getSelection() + " %");\r
+ }\r
+ });\r
+ sIncrementText.setText(sIncrement.getSelection() + " %");\r
+\r
+ // 4th line -- AxisMode + Milestone\r
+ lAxisMode = new Label(c, 0);\r
+ lAxisMode.setText("A&xis Mode:");\r
+ gd1.applyTo(lAxisMode);\r
+ cAxisMode = new Combo(c, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+ GridDataFactory.fillDefaults().indent(5, 0).span(1, 1).applyTo(cAxisMode);\r
+ cAxisMode.add("Single");\r
+ cAxisMode.add("Multi");\r
+ String _mode = data.axisMode==YAxisMode.SingleAxis ? "Single" : "Multi"; \r
+ cAxisMode.setText( _mode );\r
+ // Filler\r
+ GridDataFactory.fillDefaults().span(7, 1).applyTo(new Label(c, 0));\r
+\r
+ bTrackExperimentTime = new Button(c, SWT.CHECK);\r
+ bTrackExperimentTime.setText("Ha&irline Tracks Experiment Time");\r
+ bTrackExperimentTime.setSelection( data.trackExperimentTime );\r
+ GridDataFactory.fillDefaults().span(9, 1).applyTo(bTrackExperimentTime);\r
+\r
+ // Styling group begins\r
+\r
+ Group gStyling = new Group(c, 0);\r
+ gStyling.setText("Styling");\r
+ GridDataFactory.fillDefaults().indent(0, 5).grab(true, true).span(9, 1).applyTo(gStyling);\r
+ GridLayoutFactory.fillDefaults().margins(8, 8).numColumns(4).applyTo(gStyling);\r
+\r
+ // Background color settings\r
+ {\r
+ bBackgroundGradient = new Button(gStyling, SWT.CHECK);\r
+ bBackgroundGradient.setText("&Background Vertical Gradient");\r
+ bBackgroundGradient.setToolTipText("Solid Color or Vertical Gradient");\r
+ bBackgroundGradient.setSelection(data.backgroundGradient);\r
+ bBackgroundGradient.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ data.backgroundGradient = bBackgroundGradient.getSelection();\r
+ setBackgroundGradient(data.backgroundGradient);\r
+ }\r
+ });\r
+ GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(bBackgroundGradient);\r
+\r
+ backgroundColor1 = new ColorSelector(gStyling);\r
+ backgroundColor2 = new ColorSelector(gStyling);\r
+ backgroundColor1.getButton().setToolTipText("Select Gradient Bottom Color");\r
+ backgroundColor2.getButton().setToolTipText("Select Gradient Top Color");\r
+ GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(backgroundColor1.getButton());\r
+ GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(backgroundColor2.getButton());\r
+ backgroundColor1.setColorValue(toRGB(data.backgroundColor1, DEFAULT_BG_COLOR1));\r
+ backgroundColor2.setColorValue(toRGB(data.backgroundColor2, DEFAULT_BG_COLOR2));\r
+ setBackgroundGradient(data.backgroundGradient);\r
+\r
+ Button bResetBackgroundColors = new Button(gStyling, SWT.PUSH);\r
+ bResetBackgroundColors.setText("Reset");\r
+ bResetBackgroundColors.setToolTipText("Reset Background Color to Default");\r
+ bResetBackgroundColors.addSelectionListener(new SelectionAdapter() {\r
+ public void widgetSelected(SelectionEvent e) {\r
+ backgroundColor1.setColorValue(toRGB(null, DEFAULT_BG_COLOR1));\r
+ backgroundColor2.setColorValue(toRGB(null, DEFAULT_BG_COLOR2));\r
+ }\r
+ });\r
+ }\r
+\r
+ // Grid settings\r
+ {\r
+ bShowGrid = new Button(gStyling, SWT.CHECK);\r
+ bShowGrid.setText("Show &Grid");\r
+ bShowGrid.setToolTipText("Toggle Background Grid Visibility");\r
+ bShowGrid.setSelection(data.showGrid);\r
+ GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(bShowGrid);\r
+\r
+ gridColor = new ColorSelector(gStyling);\r
+ gridColor.getButton().setToolTipText("Select Grid Color");\r
+ GridDataFactory.fillDefaults().indent(0, 0).span(1, 1).grab(false, false).applyTo(gridColor.getButton());\r
+ gridColor.setColorValue(toRGB(data.gridColor, DEFAULT_GRID_COLOR));\r
+\r
+ Button bResetGridColor = new Button(gStyling, SWT.PUSH);\r
+ bResetGridColor.setText("Reset");\r
+ bResetGridColor.setToolTipText("Reset Grid Color to Default");\r
+ bResetGridColor.addSelectionListener(new SelectionAdapter() {\r
+ public void widgetSelected(SelectionEvent e) {\r
+ gridColor.setColorValue(toRGB(null, DEFAULT_GRID_COLOR));\r
+ }\r
+ });\r
+ }\r
+\r
+ // Grid settings\r
+ {\r
+ GridDataFactory.fillDefaults().span(1, 1).applyTo(new Label(gStyling, 0));\r
+ bMilestones = new Button(gStyling, SWT.CHECK);\r
+ bMilestones.setText("Show &Milestones");\r
+ bMilestones.setToolTipText("Toggle Milestone Event Visibility");\r
+ bMilestones.setSelection( data.showMilestones );\r
+ GridDataFactory.fillDefaults().indent(0, 0).span(4, 1).applyTo(bMilestones);\r
+ }\r
+\r
+ // Item visibility group begins\r
+\r
+ Group gItemVisibility = new Group(c, 0);\r
+ gItemVisibility.setText("Item Visibility");\r
+ GridDataFactory.fillDefaults().indent(0, 5).grab(true, true).span(9, 1).applyTo(gItemVisibility);\r
+ GridLayoutFactory.fillDefaults().margins(8, 8).numColumns(3).applyTo(gItemVisibility);\r
+\r
+ Label visible = new Label(gItemVisibility, 0);\r
+ visible.setText("Visible");\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(visible);\r
+ new Label(gItemVisibility, 0);\r
+ Label hidden = new Label(gItemVisibility, 0);\r
+ hidden.setText("Hidden");\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(hidden);\r
+\r
+ lVisibleItems = new ListViewer(gItemVisibility, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);\r
+ GridDataFactory.fillDefaults().hint(200, 200).grab(true, true).applyTo(lVisibleItems.getControl());\r
+ Composite addRemoveButtons = new Composite(gItemVisibility, 0);\r
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(addRemoveButtons);\r
+ GridDataFactory.fillDefaults().grab(false, true).span(1, 1).applyTo(addRemoveButtons);\r
+ Button hideButton = new Button(addRemoveButtons, SWT.PUSH);\r
+ hideButton.setText("&Hide \u2192");\r
+ GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(hideButton);\r
+ Button showButton = new Button(addRemoveButtons, SWT.PUSH);\r
+ showButton.setText("\u2190 &Show");\r
+ GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(showButton);\r
+ lHiddenItems = new ListViewer(gItemVisibility, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);\r
+ GridDataFactory.fillDefaults().hint(200, 200).grab(true, true).applyTo(lHiddenItems.getControl());\r
+\r
+ lVisibleItems.addDoubleClickListener(new OpenChartItemProperties());\r
+ lVisibleItems.setContentProvider(new ItemContentProvider(false));\r
+ lHiddenItems.addDoubleClickListener(new OpenChartItemProperties());\r
+ lHiddenItems.setContentProvider(new ItemContentProvider(true));\r
+ lVisibleItems.setLabelProvider(new ItemLabeler());\r
+ lHiddenItems.setLabelProvider(new ItemLabeler());\r
+ lVisibleItems.setInput(data);\r
+ lHiddenItems.setInput(data);\r
+\r
+ lVisibleItems.getList().addKeyListener(new SelectAllListener(lVisibleItems));\r
+ lHiddenItems.getList().addKeyListener(new SelectAllListener(lHiddenItems));\r
+ showButton.addSelectionListener(new ShowHideListener(false));\r
+ hideButton.addSelectionListener(new ShowHideListener(true));\r
+\r
+ Image image = FieldDecorationRegistry.getDefault()\r
+ .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR)\r
+ .getImage();\r
+\r
+ tStartTimeDecor = createDecoration(tStartTime, SWT.LEFT | SWT.CENTER, image);\r
+ tLengthDecor = createDecoration(tLength, SWT.LEFT | SWT.CENTER, image);\r
+ }\r
+\r
+ class ShowHideListener extends SelectionAdapter {\r
+ private boolean hide;\r
+\r
+ public ShowHideListener(boolean hide) {\r
+ this.hide = hide;\r
+ }\r
+\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ ISelection selection = hide ? lVisibleItems.getSelection() : lHiddenItems.getSelection();\r
+ Set<ItemKey> selected = ISelectionUtils.filterSetSelection(selection, ItemKey.class);\r
+ if (!selected.isEmpty()) {\r
+ if (hide) {\r
+ data.hiddenItems.addAll(selected);\r
+ } else {\r
+ data.hiddenItems.removeAll(selected);\r
+ }\r
+ lVisibleItems.refresh();\r
+ lHiddenItems.refresh();\r
+ }\r
+ }\r
+ }\r
+\r
+ static class SelectAllListener extends KeyAdapter {\r
+ private ListViewer list;\r
+\r
+ public SelectAllListener(ListViewer list) {\r
+ this.list = list;\r
+ }\r
+\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if (e.stateMask == SWT.CTRL && e.keyCode == 'a') {\r
+ list.getList().selectAll();\r
+ }\r
+ }\r
+ };\r
+\r
+ class ItemContentProvider extends ArrayContentProvider {\r
+ private final boolean expectedHidden;\r
+\r
+ public ItemContentProvider(boolean expectedHidden) {\r
+ this.expectedHidden = expectedHidden;\r
+ }\r
+\r
+ @Override\r
+ public Object[] getElements(Object inputElement) {\r
+ List<Object> result = new ArrayList<>();\r
+ for (ItemKey item : data.allItems.keySet())\r
+ if (data.hiddenItems.contains(item) == expectedHidden)\r
+ result.add(item);\r
+ return result.toArray();\r
+ }\r
+ }\r
+\r
+ private void setBackgroundGradient(boolean backgroundGradient) {\r
+ backgroundColor2.setEnabled(backgroundGradient);\r
+ backgroundColor1.getButton().setToolTipText(backgroundGradient ? "Select Gradient Bottom Color" : "Select Solid Color");\r
+ }\r
+\r
+ protected Double parseTime(Text text, boolean returnDefault, double defaultValue) {\r
+ if (text == null)\r
+ return null;\r
+ String s = text.getText();\r
+ Double time = ChartComposite.START_VALIDATOR.parse(s);\r
+ if (time == null)\r
+ return returnDefault ? defaultValue : null;\r
+ return time;\r
+ }\r
+\r
+ protected ControlDecoration createDecoration(Control control, int position, Image image) {\r
+ ControlDecoration d = new ControlDecoration(control, position);\r
+ d.setMarginWidth(2);\r
+ d.setImage(image);\r
+ d.hide();\r
+ return d;\r
+ }\r
+\r
+ class ItemLabeler extends LabelProvider {\r
+ @Override\r
+ public String getText(Object element) {\r
+ ItemKey item = (ItemKey) element;\r
+ TrendItem ti = data.allItems.get(item);\r
+ return ti.label;\r
+ }\r
+ }\r
+\r
+ protected void parseUiToData() {\r
+ data.name = tName.getText();\r
+ data.backgroundColor1 = toColorComponents( backgroundColor1.getColorValue() );\r
+ data.backgroundColor2 = toColorComponents( backgroundColor2.getColorValue() );\r
+ data.showGrid = bShowGrid.getSelection();\r
+ data.gridColor = toColorComponents( gridColor.getColorValue() );\r
+ data.showMilestones = bMilestones.getSelection();\r
+ data.trackExperimentTime = bTrackExperimentTime.getSelection();\r
+ data.axisMode = cAxisMode.getSelectionIndex()==0?YAxisMode.SingleAxis:YAxisMode.MultiAxis;\r
+ data.timeIncrement = (double) sIncrement.getSelection();\r
+ data.timeLength = ChartComposite.LENGTH_VALIDATOR.parse(tLength.getText());\r
+ data.timeStart = ChartComposite.START_VALIDATOR.parse(tStartTime.getText());\r
+ }\r
+\r
+ @Override\r
+ protected void buttonPressed(int buttonId) {\r
+ if (ChartDialogConstants.APPLY_ID == buttonId) {\r
+ applyPressed();\r
+ } else {\r
+ super.buttonPressed(buttonId);\r
+ }\r
+ }\r
+\r
+ private void applyPressed() {\r
+ if (applyAction != null) {\r
+ parseUiToData();\r
+ if (!baseData.equals(data)) {\r
+ baseData.readFrom(data);\r
+ applyAction.run();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ protected void okPressed() {\r
+ parseUiToData();\r
+ if (applyAction != null && !baseData.equals(data))\r
+ applyAction.run();\r
+ super.okPressed();\r
+ }\r
+\r
+ @Override\r
+ protected void configureShell(Shell newShell) {\r
+ super.configureShell(newShell);\r
+ newShell.setText("Edit Chart");\r
+ }\r
+\r
+ public void validate() {\r
+ String startTimeError = ChartComposite.START_VALIDATOR.isValid(tStartTime.getText());\r
+ String lengthError = ChartComposite.LENGTH_VALIDATOR.isValid(tLength.getText());\r
+ setDecoration(tStartTimeDecor, startTimeError);\r
+ setDecoration(tLengthDecor, lengthError);\r
+ boolean ok = startTimeError == null && lengthError == null;\r
+ setFinishable(ok);\r
+ }\r
+\r
+ private void setDecoration(ControlDecoration decor, String desc) {\r
+ if (decor == null)\r
+ return;\r
+ if (desc != null) {\r
+ decor.setDescriptionText(desc);\r
+ decor.show();\r
+ } else {\r
+ decor.hide();\r
+ }\r
+ }\r
+\r
+ protected void setFinishable(boolean ok) {\r
+ getButton(OK).setEnabled(ok);\r
+ }\r
+\r
+ private static RGB toRGB(float[] components, RGB defaultValue) {\r
+ if (components == null || components.length < 3)\r
+ return defaultValue;\r
+ Color c = new Color(components[0], components[1], components[2]);\r
+ return new RGB(c.getRed(), c.getGreen(), c.getBlue());\r
+ }\r
+\r
+ private static float[] toColorComponents(RGB rgb) {\r
+ return new Color(rgb.red, rgb.green, rgb.blue).getColorComponents(new float[3]);\r
+ }\r
+\r
+ class OpenChartItemProperties implements IDoubleClickListener {\r
+ @Override\r
+ public void doubleClick(DoubleClickEvent event) {\r
+ final ItemKey item = ISelectionUtils.filterSingleSelection(event.getSelection(), ItemKey.class);\r
+ if (item == null)\r
+ return;\r
+ try {\r
+ final ChartAndSubscriptionItemData data = Simantics.getSession().syncRequest(\r
+ new ChartAndSubscriptionItemReadQuery(item.resource.getResource()));\r
+ if (currentItemDialog != null && currentItemDialog.getShell() != null && !currentItemDialog.getShell().isDisposed()) {\r
+ // TODO: reinitialize existing dialog with the specified data.\r
+ // Close current dialog before opening new one.\r
+ currentItemDialog.close();\r
+ }\r
+ currentItemDialog = ChartDoubleClickHandler.openChartItemPropertiesDialog(\r
+ event.getViewer().getControl().getShell(),\r
+ item.resource.getResource(),\r
+ data,\r
+ false);\r
+ } catch (DatabaseException e) {\r
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Problems opening chart item property dialog."));\r
+ }\r
+ }\r
+ }\r
+\r
+}\r