-/*******************************************************************************\r
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.charts.ui;\r
-\r
-import java.awt.Color;\r
-\r
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;\r
-import org.eclipse.core.runtime.preferences.InstanceScope;\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.util.IPropertyChangeListener;\r
-import org.eclipse.jface.util.PropertyChangeEvent;\r
-import org.eclipse.swt.SWT;\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.Shell;\r
-import org.eclipse.swt.widgets.Spinner;\r
-import org.eclipse.swt.widgets.Text;\r
-import org.simantics.charts.preference.ChartPreferences;\r
-import org.simantics.charts.query.ChartAndSubscriptionItemData;\r
-import org.simantics.databoard.util.URIStringUtils;\r
-import org.simantics.modeling.preferences.SubscriptionPreferences;\r
-import org.simantics.trend.configuration.Scale;\r
-import org.simantics.trend.configuration.TrendItem.DrawMode;\r
-import org.simantics.trend.impl.JarisPaints;\r
-\r
-/**\r
- * ChartAndSubscriptionItemDialog is a dialog that has the following property\r
- * queries:\r
- * Chart name (Read only)\r
- * Variable (Read only)\r
- * Label\r
- * Draw Mode (Enumeration)\r
- * Scale, min, max ( Enum, int, int)\r
- * Subscription ( Text )\r
- * Deadband, Interval, Gain, Bias, Unit (Double)\r
- * Stroke settings (width, color)\r
- * \r
- * If the dialog is opened in binary mode the content is more stripped.\r
- * Chart name\r
- * Variable\r
- * Label\r
- * Subscription\r
- * Stroke settings\r
- * \r
- * @author toni.kalajainen\r
- */\r
-public class ChartAndSubscriptionItemDialog extends Dialog {\r
-\r
- private static final String MANUAL = "Manual";\r
- private static final String AUTO = "Auto";\r
-\r
- // UI\r
- Label lChart, lRVI, lLabel, lDrawMode, lScale, lMin, lMax, lSubscription, lDeadband, lInterval, lGain, lBias, lUnit;\r
- Text tRVI, tLabel, tDeadband, tInterval, tGain, tBias, tUnit;\r
- Combo cSubscription;\r
- Button saveAsPrefs;\r
-\r
- // chart specific, not initialized, if includeChartSpecificProperties=false\r
- Text tChart, tMin, tMax;\r
- Combo cDrawMode, cScale;\r
- Spinner sStrokeWidth;\r
- ColorSelector colorSelector;\r
-\r
- // Input error decorations\r
- ControlDecoration tMinDecor;\r
- ControlDecoration tMaxDecor;\r
- ControlDecoration tDeadbandDecor;\r
- ControlDecoration tIntervalDecor;\r
- ControlDecoration tGainDecor;\r
- ControlDecoration tBiasDecor;\r
-\r
- //\r
- ChartAndSubscriptionItemData baseData = new ChartAndSubscriptionItemData();\r
- ChartAndSubscriptionItemData data;\r
-\r
- final Runnable applyAction;\r
-\r
- IEclipsePreferences chartnode; // chart specific, not initialized, if includeChartSpecificProperties=false\r
- IEclipsePreferences subscriptionnode;\r
- boolean includeChartSpecificProperties;\r
-\r
- public ChartAndSubscriptionItemDialog(Shell parentShell, ChartAndSubscriptionItemData data, boolean includeChartSpecificProperties) {\r
- this(parentShell, data, includeChartSpecificProperties, null);\r
- }\r
-\r
- public ChartAndSubscriptionItemDialog(Shell parentShell, ChartAndSubscriptionItemData data, boolean includeChartSpecificProperties, Runnable applyAction) {\r
- super(parentShell);\r
- this.data = data;\r
- this.baseData.readFrom(data);\r
- this.includeChartSpecificProperties = includeChartSpecificProperties;\r
- this.applyAction = applyAction;\r
-\r
- if(includeChartSpecificProperties)\r
- chartnode = InstanceScope.INSTANCE.getNode( ChartPreferences.P_NODE );\r
- subscriptionnode = InstanceScope.INSTANCE.getNode( SubscriptionPreferences.P_NODE );\r
-\r
- setShellStyle(SWT.RESIZE | SWT.TITLE | SWT.CLOSE | SWT.BORDER);\r
- }\r
-\r
- @Override\r
- protected Control createContents(Composite parent) {\r
- Control c = super.createContents(parent);\r
- validate();\r
- return c;\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
- public void setInput(ChartAndSubscriptionItemData data) {\r
- // TODO: implement so that this reinitializes the UI of the dialog according to the new specified data\r
- }\r
-\r
- protected void disposeDialogAreaContents() {\r
- Composite area = (Composite) dialogArea;\r
- for (Control child : area.getChildren())\r
- child.dispose();\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().grab(true, false).indent(5, 0).span(8, 1);\r
-\r
- // 1st line - Chart: [chart name]\r
- if(includeChartSpecificProperties) {\r
- lChart = new Label(c, 0);\r
- lChart.setText("Chart:");\r
- gd1.applyTo(lChart);\r
- tChart = new Text(c, SWT.BORDER | SWT.READ_ONLY);\r
- //tChart.setEnabled( false );\r
- if ( data.chartName != null ) tChart.setText( data.chartName );\r
- gd2.applyTo(tChart);\r
- }\r
-\r
- // 2nd line - Variable Reference: [chart item label]\r
- lRVI = new Label(c, 0);\r
- lRVI.setText("Variable: ");\r
- gd1.applyTo(lRVI);\r
- tRVI = new Text(c, SWT.BORDER | SWT.READ_ONLY);\r
- //tRVI.setEnabled(false);\r
- if ( data.variableReference!=null ) tRVI.setText(URIStringUtils.unescape( data.variableReference ));\r
- gd2.applyTo(tRVI);\r
-\r
- // 3rd line - Label: [chart item label]\r
- lLabel = new Label(c, 0);\r
- lLabel.setText("&Label: ");\r
- gd1.applyTo(lLabel);\r
- tLabel = new Text(c, SWT.BORDER);\r
- if ( data.label!=null ) tLabel.setText(data.label);\r
- gd2.applyTo(tLabel);\r
-\r
-// if (!data.binaryMode) {\r
-// // 4th line - DrawMode: [ drop-down-list V ]\r
-// lDrawMode = new Label(c, 0);\r
-// lDrawMode.setText("DrawMode :");\r
-// gd1.applyTo(lDrawMode);\r
-// cDrawMode = new Combo(c, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
-// for (DrawMode dm : DrawMode.values()) cDrawMode.add( dm.name() );\r
-// String _drawmode = data.drawmode!=null ? data.drawmode.toString() : chartnode.get( ChartPreferences.P_DRAWMODE, ChartPreferences.DEFAULT_DRAWMODE ); \r
-// cDrawMode.setText( _drawmode );\r
-// gd2.applyTo(cDrawMode);\r
-// }\r
-\r
- if (!data.binaryMode && includeChartSpecificProperties) {\r
- // 5th line - Scale: [ Auto/Manual ] Min: [ ## ] Max: [ ## ]\r
- lScale = new Label(c, 0);\r
- lScale.setText("&Scale: ");\r
- gd1.applyTo(lScale);\r
-\r
- Composite scaleComposite = new Composite(c, 0);\r
- gd2.applyTo(scaleComposite);\r
- GridLayoutFactory.fillDefaults().numColumns(8).applyTo(scaleComposite);\r
-\r
- cScale = new Combo(scaleComposite, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
- cScale.add(AUTO);\r
- cScale.add(MANUAL);\r
- String _scale = data.scale != null ? data.scale.toString() : chartnode.get( ChartPreferences.P_SCALEMODE, ChartPreferences.DEFAULT_SCALEMODE ); \r
- cScale.setText( _scale );\r
- GridDataFactory.fillDefaults().span(2, 1).applyTo(cScale);\r
- \r
- lMin = new Label(scaleComposite, 0);\r
- lMin.setText("&Min: ");\r
- GridDataFactory.fillDefaults().span(1, 1).align(SWT.FILL, SWT.CENTER).applyTo(lMin);\r
- tMin = new Text(scaleComposite, SWT.BORDER);\r
- Double _min = data.min;\r
- if ( _min == null ) _min = chartnode.getDouble( ChartPreferences.P_SCALE_MIN, 0.0);\r
- tMin.setText( Double.toString(_min) );\r
- GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).indent(5, 0).grab(true, false).span(2, 1).applyTo(tMin);\r
- tMin.addModifyListener(new ModifyListener() {\r
- @Override\r
- public void modifyText(ModifyEvent e) {\r
- data.min = parseDouble(tMin, false, 0.0);\r
- if (data.min != null)\r
- cScale.setText(MANUAL);\r
- validate();\r
- }\r
- });\r
-\r
- lMax = new Label(scaleComposite, 0);\r
- lMax.setText("Ma&x: ");\r
- GridDataFactory.fillDefaults().span(1, 1).align(SWT.FILL, SWT.CENTER).applyTo(lMax);\r
- tMax = new Text(scaleComposite, SWT.BORDER);\r
- Double _max = data.max;\r
- if ( _max==null ) _max = chartnode.getDouble( ChartPreferences.P_SCALE_MAX, 100.0);\r
- tMax.setText( Double.toString(_max) );\r
- GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).indent(5, 0).grab(true, false).span(2, 1).applyTo(tMax);\r
- tMax.addModifyListener(new ModifyListener() {\r
- @Override\r
- public void modifyText(ModifyEvent e) {\r
- data.max = parseDouble(tMax, false, 100.0);\r
- if (data.max != null)\r
- cScale.setText(MANUAL);\r
- validate();\r
- }\r
- });\r
- }\r
-\r
- // 6th line - Subscription: [ Default / others ] [New] \r
- lSubscription = new Label(c, 0);\r
- lSubscription.setText("S&ubscription: ");\r
- gd1.applyTo(lSubscription);\r
- cSubscription = new Combo(c, SWT.BORDER);\r
- for (String s : data.subscriptions) cSubscription.add(s);\r
- gd2.applyTo(cSubscription);\r
- String _subscription = data.subscription;\r
- if ( _subscription == null ) _subscription = subscriptionnode.get( SubscriptionPreferences.P_SUBSCRIPTION_DEFAULT, data.subscriptions.length==0 ? "Default" : cSubscription.getItem(0) );\r
- cSubscription.setText( _subscription );\r
-\r
- if (!data.binaryMode) {\r
- // 7th line - Deadband: [deadband] Interval: [interval]\r
- lDeadband = new Label(c, 0);\r
- lDeadband.setText("&Deadband: ");\r
- gd1.applyTo(lDeadband);\r
- tDeadband = new Text(c, SWT.BORDER);\r
- Double _deadband = data.deadband;\r
- if ( _deadband == null ) _deadband = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_DEADBAND, SubscriptionPreferences.DEFAULT_SUBSCRIPTION_DEADBAND );\r
- tDeadband.setText( Double.toString(_deadband) );\r
- tDeadband.setEditable(data.mutableCollectionSettings);\r
- GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tDeadband);\r
- tDeadband.addModifyListener(new ModifyListener() {\r
- @Override\r
- public void modifyText(ModifyEvent e) {\r
- data.deadband = parseDouble(tDeadband, false, 0.0);\r
- validate();\r
- }\r
- });\r
-\r
- lInterval = new Label(c, 0);\r
- lInterval.setText("&Interval: ");\r
- lInterval.setToolTipText("Sampling Interval");\r
- GridDataFactory.fillDefaults().span(2, 1).applyTo(lInterval);\r
- tInterval = new Text(c, SWT.BORDER);\r
- Double _interval = data.interval;\r
- if ( _interval == null ) _interval = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_INTERVAL, SubscriptionPreferences.DEFAULT_SUBSCRIPTION_INTERVAL );\r
- tInterval.setText( Double.toString(_interval) );\r
- tInterval.setEditable(data.mutableCollectionSettings);\r
- GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tInterval);\r
- tInterval.addModifyListener(new ModifyListener() {\r
- @Override\r
- public void modifyText(ModifyEvent e) {\r
- data.interval = parseDouble(tInterval, false, 0.0);\r
- validate();\r
- }\r
- });\r
- }\r
-\r
- // 8th line - Gain: [gain] Bias: [bias]\r
- if (!data.binaryMode) {\r
- lGain = new Label(c, 0);\r
- lGain.setText("&Gain: ");\r
- gd1.applyTo(lGain);\r
- tGain = new Text(c, SWT.BORDER);\r
- Double _gain = data.gain;\r
- if (_gain == null) _gain = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_GAIN, 1.0);\r
- tGain.setText( Double.toString(_gain) );\r
- GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tGain);\r
- tGain.addModifyListener(new ModifyListener() {\r
- @Override\r
- public void modifyText(ModifyEvent e) {\r
- data.gain = parseDouble(tGain, false, 1.0);\r
- validate();\r
- }\r
- });\r
-\r
- lBias = new Label(c, 0);\r
- lBias.setText("&Bias: ");\r
- GridDataFactory.fillDefaults().span(2, 1).applyTo(lBias);\r
- tBias = new Text(c, SWT.BORDER);\r
- Double _bias = data.bias;\r
- if (_bias == null) _bias = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_BIAS, 0.0);\r
- tBias.setText( Double.toString(_bias) );\r
- GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tBias);\r
- tBias.addModifyListener(new ModifyListener() {\r
- @Override\r
- public void modifyText(ModifyEvent e) {\r
- data.bias = parseDouble(tBias, false, 0.0);\r
- validate();\r
- }\r
- });\r
- }\r
-\r
- // 9th line - Unit: [unit]\r
- if (!data.binaryMode) {\r
- lUnit = new Label(c, 0);\r
- lUnit.setText("U&nit: ");\r
- gd1.applyTo(lUnit);\r
- tUnit = new Text(c, SWT.BORDER);\r
- String _unit = data.unit;\r
- if (_unit==null) _unit = subscriptionnode.get( SubscriptionPreferences.P_SUBSCRIPTION_UNIT, "");\r
- tUnit.setText( _unit );\r
- GridDataFactory.fillDefaults().hint(100, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tUnit);\r
- // Fill line\r
- GridDataFactory.fillDefaults().span(5, 1).applyTo(new Label(c, 0));\r
- }\r
-\r
- // Disable fields that edit subscription item\r
- if (!data.hasSubscriptionItem) {\r
- tLabel.setEnabled( false );\r
- cSubscription.setEnabled( false );\r
- tDeadband.setEnabled( false );\r
- tInterval.setEnabled( false );\r
- tGain.setEnabled( false );\r
- tBias.setEnabled( false );\r
- tUnit.setEnabled( false );\r
- }\r
-\r
- // 10th line - Color stroke / color\r
- if (includeChartSpecificProperties) {\r
- createStrokeGroup(c);\r
- }\r
-\r
- saveAsPrefs = new Button(c, SWT.CHECK);\r
- saveAsPrefs.setText("Sav&e as new defaults");\r
- saveAsPrefs.setToolTipText("Sav&e these settings as new defaults");\r
- // Always unchecked by default.\r
- saveAsPrefs.setSelection(false);\r
- GridDataFactory.fillDefaults().hint(100, SWT.DEFAULT).span(9, 1).applyTo(saveAsPrefs);\r
-\r
- // Error decorations\r
- Image image = FieldDecorationRegistry.getDefault()\r
- .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR)\r
- .getImage();\r
-\r
- if (!data.binaryMode) {\r
- if (includeChartSpecificProperties) {\r
- tMinDecor = createDecoration(tMin, SWT.LEFT | SWT.CENTER, image);\r
- tMaxDecor = createDecoration(tMax, SWT.LEFT | SWT.CENTER, image);\r
- }\r
- tDeadbandDecor = createDecoration(tDeadband, SWT.LEFT | SWT.CENTER, image);\r
- tIntervalDecor = createDecoration(tInterval, SWT.LEFT | SWT.CENTER, image);\r
- tGainDecor = createDecoration(tGain, SWT.LEFT | SWT.CENTER, image);\r
- tBiasDecor = createDecoration(tBias, SWT.LEFT | SWT.CENTER, image);\r
- }\r
-\r
- // Ensure that the data structure contains all the values that were\r
- // initialized into the UI.\r
- parseUiToData();\r
-\r
- tLabel.setFocus();\r
- }\r
-\r
- private void createStrokeGroup(Composite c) {\r
- GridDataFactory gd1 = GridDataFactory.fillDefaults().indent(10, 0).align(SWT.FILL, SWT.CENTER).span(1, 1);\r
-\r
- Group gStroke = new Group(c, 0);\r
- gStroke.setText("Trend Line Stroke");\r
- GridLayoutFactory.fillDefaults().margins(8, 8).spacing(10, 10).numColumns(5).applyTo(gStroke);\r
- GridDataFactory.fillDefaults().span(9, 1).applyTo(gStroke);\r
-\r
- if (!data.binaryMode) {\r
- // Custom stroke\r
- Label lStrokeWidth = new Label(gStroke, 0);\r
- lStrokeWidth.setText("&Width:");\r
- gd1.applyTo(lStrokeWidth);\r
- sStrokeWidth = new Spinner(gStroke, SWT.BORDER);\r
- sStrokeWidth.setDigits(1);\r
- sStrokeWidth.setIncrement(5);\r
- sStrokeWidth.setMinimum(10);\r
- sStrokeWidth.setMaximum(50);\r
- GridDataFactory.fillDefaults().indent(10, 0).grab(false, false).span(1, 1).applyTo(sStrokeWidth);\r
-\r
- if (data.strokeWidth != null) {\r
- sStrokeWidth.setSelection((int) (data.strokeWidth * 10));\r
- }\r
-\r
- sStrokeWidth.addSelectionListener(new SelectionAdapter() {\r
- @Override\r
- public void widgetSelected(SelectionEvent e) {\r
- float newWidth = ((float) sStrokeWidth.getSelection()) * 0.1f;\r
- data.strokeWidth = newWidth;\r
- }\r
- });\r
- }\r
-\r
- Label lColor = new Label(gStroke, 0);\r
- lColor.setText("&Color: ");\r
- gd1.applyTo(lColor);\r
- colorSelector = new ColorSelector(gStroke);\r
- GridDataFactory.fillDefaults().indent(10, 0).span(1, 1).grab(false, false).applyTo(colorSelector.getButton());\r
- final RGB indexColor = toRGB(JarisPaints.getColor(data.index));\r
- RGB customColor = data.color != null ? toRGB(data.color) : indexColor;\r
- colorSelector.setColorValue(customColor);\r
-\r
- final Button bResetColor = new Button(gStroke, SWT.PUSH);\r
- bResetColor.setText("Reset Color");\r
- bResetColor.setToolTipText("Reset Color to Item Index Default");\r
- bResetColor.setEnabled(!indexColor.equals(customColor));\r
-\r
- colorSelector.addListener(new IPropertyChangeListener() {\r
- @Override\r
- public void propertyChange(PropertyChangeEvent event) {\r
- RGB rgb = colorSelector.getColorValue();\r
- data.color = new Color(rgb.red, rgb.green, rgb.blue).getColorComponents(new float[4]);\r
- data.color[3] = 1;\r
- bResetColor.setEnabled(!indexColor.equals(rgb));\r
- }\r
- });\r
-\r
- bResetColor.addSelectionListener(new SelectionAdapter() {\r
- @Override\r
- public void widgetSelected(SelectionEvent e) {\r
- data.color = null;\r
- colorSelector.setColorValue(toRGB(JarisPaints.getColor(data.index)));\r
- bResetColor.setEnabled(false);\r
- }\r
- });\r
- }\r
-\r
- protected RGB toRGB(float[] color) {\r
- float r = color[0];\r
- float g = color[1];\r
- float b = color[2];\r
- return new RGB( (int) (r*255+0.5), (int) (g*255+0.5), (int) (b*255+0.5) );\r
- }\r
-\r
- protected RGB toRGB(Color color) {\r
- return new RGB(color.getRed(), color.getGreen(), color.getBlue());\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
- protected Double parseDouble(Text text, boolean returnDefault, double defaultValue) {\r
- if (text == null)\r
- return null;\r
- try {\r
- String s = text.getText();\r
- s = s.replace(',', '.');\r
- return Double.valueOf(s);\r
- } catch ( NumberFormatException nfe ) {\r
- return returnDefault ? defaultValue : null;\r
- }\r
- }\r
-\r
- protected void parseUiToData() {\r
- data.label = tLabel.getText();\r
- if (!data.binaryMode) {\r
- if (includeChartSpecificProperties) {\r
- data.min = parseDouble(tMin, true, 0.0);\r
- data.max = parseDouble(tMax, true, 100.0);\r
- }\r
- data.interval = parseDouble(tInterval, true, 0.0);\r
- data.deadband = parseDouble(tDeadband, true, 0.0);\r
- data.gain = parseDouble(tGain, true, 1.0);\r
- data.bias = parseDouble(tBias, true, 0.0);\r
- data.unit = tUnit.getText();\r
-\r
- if (includeChartSpecificProperties) {\r
-// data.drawmode = DrawMode.valueOf( cDrawMode.getText() );\r
- data.drawmode = DrawMode.Line;\r
-\r
- if (cScale.getText().equals("Manual")) {\r
- data.scale = new Scale.Manual(data.min, data.max);\r
- } else if (cScale.getText().equals("Auto")) {\r
- data.scale = new Scale.Auto();\r
- }\r
- }\r
- }\r
- data.subscription = cSubscription.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
- boolean savePrefs = saveAsPrefs.getSelection();\r
- parseUiToData();\r
-\r
- if (!data.binaryMode && savePrefs) {\r
- if (includeChartSpecificProperties) {\r
- chartnode.put( ChartPreferences.P_DRAWMODE, data.drawmode.name() );\r
- chartnode.put( ChartPreferences.P_SCALEMODE, data.scale instanceof Scale.Manual ? "Manual" : "Auto" );\r
- chartnode.putDouble( ChartPreferences.P_SCALE_MIN, data.min );\r
- chartnode.putDouble( ChartPreferences.P_SCALE_MAX, data.max );\r
- }\r
- subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_DEADBAND, data.deadband );\r
- subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_INTERVAL, data.interval );\r
- subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_GAIN, data.gain );\r
- subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_BIAS, data.bias );\r
- subscriptionnode.put( SubscriptionPreferences.P_SUBSCRIPTION_UNIT, data.unit );\r
- }\r
-\r
- if (savePrefs)\r
- subscriptionnode.put( SubscriptionPreferences.P_SUBSCRIPTION_DEFAULT, data.subscription );\r
-\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(\r
- includeChartSpecificProperties ? "Edit Chart Item"\r
- : "Edit Subscription Item"\r
- );\r
- }\r
-\r
- public void validate() {\r
- boolean ok = true;\r
- if (!data.binaryMode) {\r
- if (includeChartSpecificProperties) {\r
- setDecoration(tMinDecor, null);\r
- setDecoration(tMaxDecor, null);\r
- if (tMin != null && tMax != null) {\r
- if (data.min == null || data.max == null) {\r
- ok = false;\r
- if (data.min == null)\r
- setDecoration(tMinDecor, "Invalid non-numeric value");\r
- if (data.max == null)\r
- setDecoration(tMaxDecor, "Invalid non-numeric value");\r
- } else {\r
- if (data.min >= data.max) {\r
- setDecoration(tMinDecor, "Minimum value must be smaller than maximum value");\r
- setDecoration(tMaxDecor, "Maximum value must be larger than minimum value");\r
- ok = false;\r
- }\r
- }\r
- }\r
- }\r
-\r
- ok &= data.interval != null && data.deadband != null && data.bias != null && data.gain != null;\r
- setDecoration(tIntervalDecor, data.interval == null ? "Invalid non-numeric value" : null);\r
- if (data.interval != null && data.interval < 0)\r
- setDecoration(tIntervalDecor, "Sampling interval cannot be negative");\r
- setDecoration(tDeadbandDecor, data.deadband == null ? "Invalid non-numeric value" : null);\r
- if (data.deadband != null && data.deadband < 0)\r
- setDecoration(tDeadbandDecor, "Deadband cannot be negative");\r
- setDecoration(tGainDecor, data.gain == null ? "Invalid non-numeric value" : null);\r
- setDecoration(tBiasDecor, data.bias == null ? "Invalid non-numeric value" : null);\r
- }\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
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.charts.ui;
+
+import java.awt.Color;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Text;
+import org.simantics.charts.preference.ChartPreferences;
+import org.simantics.charts.query.ChartAndSubscriptionItemData;
+import org.simantics.databoard.util.URIStringUtils;
+import org.simantics.modeling.preferences.SubscriptionPreferences;
+import org.simantics.trend.configuration.Scale;
+import org.simantics.trend.configuration.TrendItem.DrawMode;
+import org.simantics.trend.impl.JarisPaints;
+
+/**
+ * ChartAndSubscriptionItemDialog is a dialog that has the following property
+ * queries:
+ * Chart name (Read only)
+ * Variable (Read only)
+ * Label
+ * Draw Mode (Enumeration)
+ * Scale, min, max ( Enum, int, int)
+ * Subscription ( Text )
+ * Deadband, Interval, Gain, Bias, Unit (Double)
+ * Stroke settings (width, color)
+ *
+ * If the dialog is opened in binary mode the content is more stripped.
+ * Chart name
+ * Variable
+ * Label
+ * Subscription
+ * Stroke settings
+ *
+ * @author toni.kalajainen
+ */
+public class ChartAndSubscriptionItemDialog extends Dialog {
+
+ private static final String MANUAL = "Manual";
+ private static final String AUTO = "Auto";
+
+ // UI
+ Label lChart, lRVI, lLabel, lDrawMode, lScale, lMin, lMax, lSubscription, lDeadband, lInterval, lGain, lBias, lUnit;
+ Text tRVI, tLabel, tDeadband, tInterval, tGain, tBias, tUnit;
+ Combo cSubscription;
+ Button saveAsPrefs;
+
+ // chart specific, not initialized, if includeChartSpecificProperties=false
+ Text tChart, tMin, tMax;
+ Combo cDrawMode, cScale;
+ Spinner sStrokeWidth;
+ ColorSelector colorSelector;
+
+ // Input error decorations
+ ControlDecoration tMinDecor;
+ ControlDecoration tMaxDecor;
+ ControlDecoration tDeadbandDecor;
+ ControlDecoration tIntervalDecor;
+ ControlDecoration tGainDecor;
+ ControlDecoration tBiasDecor;
+
+ //
+ ChartAndSubscriptionItemData baseData = new ChartAndSubscriptionItemData();
+ ChartAndSubscriptionItemData data;
+
+ final Runnable applyAction;
+
+ IEclipsePreferences chartnode; // chart specific, not initialized, if includeChartSpecificProperties=false
+ IEclipsePreferences subscriptionnode;
+ boolean includeChartSpecificProperties;
+
+ public ChartAndSubscriptionItemDialog(Shell parentShell, ChartAndSubscriptionItemData data, boolean includeChartSpecificProperties) {
+ this(parentShell, data, includeChartSpecificProperties, null);
+ }
+
+ public ChartAndSubscriptionItemDialog(Shell parentShell, ChartAndSubscriptionItemData data, boolean includeChartSpecificProperties, Runnable applyAction) {
+ super(parentShell);
+ this.data = data;
+ this.baseData.readFrom(data);
+ this.includeChartSpecificProperties = includeChartSpecificProperties;
+ this.applyAction = applyAction;
+
+ if(includeChartSpecificProperties)
+ chartnode = InstanceScope.INSTANCE.getNode( ChartPreferences.P_NODE );
+ subscriptionnode = InstanceScope.INSTANCE.getNode( SubscriptionPreferences.P_NODE );
+
+ setShellStyle(SWT.RESIZE | SWT.TITLE | SWT.CLOSE | SWT.BORDER);
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Control c = super.createContents(parent);
+ validate();
+ return c;
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ if (applyAction != null)
+ createButton(parent, ChartDialogConstants.APPLY_ID, ChartDialogConstants.APPLY_LABEL, true);
+ super.createButtonsForButtonBar(parent);
+ }
+
+ public void setInput(ChartAndSubscriptionItemData data) {
+ // TODO: implement so that this reinitializes the UI of the dialog according to the new specified data
+ }
+
+ protected void disposeDialogAreaContents() {
+ Composite area = (Composite) dialogArea;
+ for (Control child : area.getChildren())
+ child.dispose();
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite c = (Composite) super.createDialogArea(parent);
+ GridLayoutFactory.fillDefaults().margins(8, 8).numColumns(9).applyTo(c);
+ createDialogAreaContents(c);
+ return c;
+ }
+
+ protected void createDialogAreaContents(Composite c) {
+ GridDataFactory gd1 = GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(1, 1);
+ GridDataFactory gd2 = GridDataFactory.fillDefaults().grab(true, false).indent(5, 0).span(8, 1);
+
+ // 1st line - Chart: [chart name]
+ if(includeChartSpecificProperties) {
+ lChart = new Label(c, 0);
+ lChart.setText("Chart:");
+ gd1.applyTo(lChart);
+ tChart = new Text(c, SWT.BORDER | SWT.READ_ONLY);
+ //tChart.setEnabled( false );
+ if ( data.chartName != null ) tChart.setText( data.chartName );
+ gd2.applyTo(tChart);
+ }
+
+ // 2nd line - Variable Reference: [chart item label]
+ lRVI = new Label(c, 0);
+ lRVI.setText("Variable: ");
+ gd1.applyTo(lRVI);
+ tRVI = new Text(c, SWT.BORDER | SWT.READ_ONLY);
+ //tRVI.setEnabled(false);
+ if ( data.variableReference!=null ) tRVI.setText(URIStringUtils.unescape( data.variableReference ));
+ gd2.applyTo(tRVI);
+
+ // 3rd line - Label: [chart item label]
+ lLabel = new Label(c, 0);
+ lLabel.setText("&Label: ");
+ gd1.applyTo(lLabel);
+ tLabel = new Text(c, SWT.BORDER);
+ if ( data.label!=null ) tLabel.setText(data.label);
+ gd2.applyTo(tLabel);
+
+// if (!data.binaryMode) {
+// // 4th line - DrawMode: [ drop-down-list V ]
+// lDrawMode = new Label(c, 0);
+// lDrawMode.setText("DrawMode :");
+// gd1.applyTo(lDrawMode);
+// cDrawMode = new Combo(c, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);
+// for (DrawMode dm : DrawMode.values()) cDrawMode.add( dm.name() );
+// String _drawmode = data.drawmode!=null ? data.drawmode.toString() : chartnode.get( ChartPreferences.P_DRAWMODE, ChartPreferences.DEFAULT_DRAWMODE );
+// cDrawMode.setText( _drawmode );
+// gd2.applyTo(cDrawMode);
+// }
+
+ if (!data.binaryMode && includeChartSpecificProperties) {
+ // 5th line - Scale: [ Auto/Manual ] Min: [ ## ] Max: [ ## ]
+ lScale = new Label(c, 0);
+ lScale.setText("&Scale: ");
+ gd1.applyTo(lScale);
+
+ Composite scaleComposite = new Composite(c, 0);
+ gd2.applyTo(scaleComposite);
+ GridLayoutFactory.fillDefaults().numColumns(8).applyTo(scaleComposite);
+
+ cScale = new Combo(scaleComposite, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);
+ cScale.add(AUTO);
+ cScale.add(MANUAL);
+ String _scale = data.scale != null ? data.scale.toString() : chartnode.get( ChartPreferences.P_SCALEMODE, ChartPreferences.DEFAULT_SCALEMODE );
+ cScale.setText( _scale );
+ GridDataFactory.fillDefaults().span(2, 1).applyTo(cScale);
+
+ lMin = new Label(scaleComposite, 0);
+ lMin.setText("&Min: ");
+ GridDataFactory.fillDefaults().span(1, 1).align(SWT.FILL, SWT.CENTER).applyTo(lMin);
+ tMin = new Text(scaleComposite, SWT.BORDER);
+ Double _min = data.min;
+ if ( _min == null ) _min = chartnode.getDouble( ChartPreferences.P_SCALE_MIN, 0.0);
+ tMin.setText( Double.toString(_min) );
+ GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).indent(5, 0).grab(true, false).span(2, 1).applyTo(tMin);
+ tMin.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ data.min = parseDouble(tMin, false, 0.0);
+ if (data.min != null)
+ cScale.setText(MANUAL);
+ validate();
+ }
+ });
+
+ lMax = new Label(scaleComposite, 0);
+ lMax.setText("Ma&x: ");
+ GridDataFactory.fillDefaults().span(1, 1).align(SWT.FILL, SWT.CENTER).applyTo(lMax);
+ tMax = new Text(scaleComposite, SWT.BORDER);
+ Double _max = data.max;
+ if ( _max==null ) _max = chartnode.getDouble( ChartPreferences.P_SCALE_MAX, 100.0);
+ tMax.setText( Double.toString(_max) );
+ GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).indent(5, 0).grab(true, false).span(2, 1).applyTo(tMax);
+ tMax.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ data.max = parseDouble(tMax, false, 100.0);
+ if (data.max != null)
+ cScale.setText(MANUAL);
+ validate();
+ }
+ });
+ }
+
+ // 6th line - Subscription: [ Default / others ] [New]
+ lSubscription = new Label(c, 0);
+ lSubscription.setText("S&ubscription: ");
+ gd1.applyTo(lSubscription);
+ cSubscription = new Combo(c, SWT.BORDER);
+ for (String s : data.subscriptions) cSubscription.add(s);
+ gd2.applyTo(cSubscription);
+ String _subscription = data.subscription;
+ if ( _subscription == null ) _subscription = subscriptionnode.get( SubscriptionPreferences.P_SUBSCRIPTION_DEFAULT, data.subscriptions.length==0 ? "Default" : cSubscription.getItem(0) );
+ cSubscription.setText( _subscription );
+
+ if (!data.binaryMode) {
+ // 7th line - Deadband: [deadband] Interval: [interval]
+ lDeadband = new Label(c, 0);
+ lDeadband.setText("&Deadband: ");
+ gd1.applyTo(lDeadband);
+ tDeadband = new Text(c, SWT.BORDER);
+ Double _deadband = data.deadband;
+ if ( _deadband == null ) _deadband = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_DEADBAND, SubscriptionPreferences.DEFAULT_SUBSCRIPTION_DEADBAND );
+ tDeadband.setText( Double.toString(_deadband) );
+ tDeadband.setEditable(data.mutableCollectionSettings);
+ GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tDeadband);
+ tDeadband.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ data.deadband = parseDouble(tDeadband, false, 0.0);
+ validate();
+ }
+ });
+
+ lInterval = new Label(c, 0);
+ lInterval.setText("&Interval: ");
+ lInterval.setToolTipText("Sampling Interval");
+ GridDataFactory.fillDefaults().span(2, 1).applyTo(lInterval);
+ tInterval = new Text(c, SWT.BORDER);
+ Double _interval = data.interval;
+ if ( _interval == null ) _interval = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_INTERVAL, SubscriptionPreferences.DEFAULT_SUBSCRIPTION_INTERVAL );
+ tInterval.setText( Double.toString(_interval) );
+ tInterval.setEditable(data.mutableCollectionSettings);
+ GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tInterval);
+ tInterval.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ data.interval = parseDouble(tInterval, false, 0.0);
+ validate();
+ }
+ });
+ }
+
+ // 8th line - Gain: [gain] Bias: [bias]
+ if (!data.binaryMode) {
+ lGain = new Label(c, 0);
+ lGain.setText("&Gain: ");
+ gd1.applyTo(lGain);
+ tGain = new Text(c, SWT.BORDER);
+ Double _gain = data.gain;
+ if (_gain == null) _gain = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_GAIN, 1.0);
+ tGain.setText( Double.toString(_gain) );
+ GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tGain);
+ tGain.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ data.gain = parseDouble(tGain, false, 1.0);
+ validate();
+ }
+ });
+
+ lBias = new Label(c, 0);
+ lBias.setText("&Bias: ");
+ GridDataFactory.fillDefaults().span(2, 1).applyTo(lBias);
+ tBias = new Text(c, SWT.BORDER);
+ Double _bias = data.bias;
+ if (_bias == null) _bias = subscriptionnode.getDouble( SubscriptionPreferences.P_SUBSCRIPTION_BIAS, 0.0);
+ tBias.setText( Double.toString(_bias) );
+ GridDataFactory.fillDefaults().hint(110, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tBias);
+ tBias.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ data.bias = parseDouble(tBias, false, 0.0);
+ validate();
+ }
+ });
+ }
+
+ // 9th line - Unit: [unit]
+ if (!data.binaryMode) {
+ lUnit = new Label(c, 0);
+ lUnit.setText("U&nit: ");
+ gd1.applyTo(lUnit);
+ tUnit = new Text(c, SWT.BORDER);
+ String _unit = data.unit;
+ if (_unit==null) _unit = subscriptionnode.get( SubscriptionPreferences.P_SUBSCRIPTION_UNIT, "");
+ tUnit.setText( _unit );
+ GridDataFactory.fillDefaults().hint(100, SWT.DEFAULT).indent(5, 0).span(3, 1).applyTo(tUnit);
+ // Fill line
+ GridDataFactory.fillDefaults().span(5, 1).applyTo(new Label(c, 0));
+ }
+
+ // Disable fields that edit subscription item
+ if (!data.hasSubscriptionItem) {
+ tLabel.setEnabled( false );
+ cSubscription.setEnabled( false );
+ tDeadband.setEnabled( false );
+ tInterval.setEnabled( false );
+ tGain.setEnabled( false );
+ tBias.setEnabled( false );
+ tUnit.setEnabled( false );
+ }
+
+ // 10th line - Color stroke / color
+ if (includeChartSpecificProperties) {
+ createStrokeGroup(c);
+ }
+
+ saveAsPrefs = new Button(c, SWT.CHECK);
+ saveAsPrefs.setText("Sav&e as new defaults");
+ saveAsPrefs.setToolTipText("Sav&e these settings as new defaults");
+ // Always unchecked by default.
+ saveAsPrefs.setSelection(false);
+ GridDataFactory.fillDefaults().hint(100, SWT.DEFAULT).span(9, 1).applyTo(saveAsPrefs);
+
+ // Error decorations
+ Image image = FieldDecorationRegistry.getDefault()
+ .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR)
+ .getImage();
+
+ if (!data.binaryMode) {
+ if (includeChartSpecificProperties) {
+ tMinDecor = createDecoration(tMin, SWT.LEFT | SWT.CENTER, image);
+ tMaxDecor = createDecoration(tMax, SWT.LEFT | SWT.CENTER, image);
+ }
+ tDeadbandDecor = createDecoration(tDeadband, SWT.LEFT | SWT.CENTER, image);
+ tIntervalDecor = createDecoration(tInterval, SWT.LEFT | SWT.CENTER, image);
+ tGainDecor = createDecoration(tGain, SWT.LEFT | SWT.CENTER, image);
+ tBiasDecor = createDecoration(tBias, SWT.LEFT | SWT.CENTER, image);
+ }
+
+ // Ensure that the data structure contains all the values that were
+ // initialized into the UI.
+ parseUiToData();
+
+ tLabel.setFocus();
+ }
+
+ private void createStrokeGroup(Composite c) {
+ GridDataFactory gd1 = GridDataFactory.fillDefaults().indent(10, 0).align(SWT.FILL, SWT.CENTER).span(1, 1);
+
+ Group gStroke = new Group(c, 0);
+ gStroke.setText("Trend Line Stroke");
+ GridLayoutFactory.fillDefaults().margins(8, 8).spacing(10, 10).numColumns(5).applyTo(gStroke);
+ GridDataFactory.fillDefaults().span(9, 1).applyTo(gStroke);
+
+ if (!data.binaryMode) {
+ // Custom stroke
+ Label lStrokeWidth = new Label(gStroke, 0);
+ lStrokeWidth.setText("&Width:");
+ gd1.applyTo(lStrokeWidth);
+ sStrokeWidth = new Spinner(gStroke, SWT.BORDER);
+ sStrokeWidth.setDigits(1);
+ sStrokeWidth.setIncrement(5);
+ sStrokeWidth.setMinimum(10);
+ sStrokeWidth.setMaximum(50);
+ GridDataFactory.fillDefaults().indent(10, 0).grab(false, false).span(1, 1).applyTo(sStrokeWidth);
+
+ if (data.strokeWidth != null) {
+ sStrokeWidth.setSelection((int) (data.strokeWidth * 10));
+ }
+
+ sStrokeWidth.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ float newWidth = ((float) sStrokeWidth.getSelection()) * 0.1f;
+ data.strokeWidth = newWidth;
+ }
+ });
+ }
+
+ Label lColor = new Label(gStroke, 0);
+ lColor.setText("&Color: ");
+ gd1.applyTo(lColor);
+ colorSelector = new ColorSelector(gStroke);
+ GridDataFactory.fillDefaults().indent(10, 0).span(1, 1).grab(false, false).applyTo(colorSelector.getButton());
+ final RGB indexColor = toRGB(JarisPaints.getColor(data.index));
+ RGB customColor = data.color != null ? toRGB(data.color) : indexColor;
+ colorSelector.setColorValue(customColor);
+
+ final Button bResetColor = new Button(gStroke, SWT.PUSH);
+ bResetColor.setText("Reset Color");
+ bResetColor.setToolTipText("Reset Color to Item Index Default");
+ bResetColor.setEnabled(!indexColor.equals(customColor));
+
+ colorSelector.addListener(new IPropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ RGB rgb = colorSelector.getColorValue();
+ data.color = new Color(rgb.red, rgb.green, rgb.blue).getColorComponents(new float[4]);
+ data.color[3] = 1;
+ bResetColor.setEnabled(!indexColor.equals(rgb));
+ }
+ });
+
+ bResetColor.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ data.color = null;
+ colorSelector.setColorValue(toRGB(JarisPaints.getColor(data.index)));
+ bResetColor.setEnabled(false);
+ }
+ });
+ }
+
+ protected RGB toRGB(float[] color) {
+ float r = color[0];
+ float g = color[1];
+ float b = color[2];
+ return new RGB( (int) (r*255+0.5), (int) (g*255+0.5), (int) (b*255+0.5) );
+ }
+
+ protected RGB toRGB(Color color) {
+ return new RGB(color.getRed(), color.getGreen(), color.getBlue());
+ }
+
+ protected ControlDecoration createDecoration(Control control, int position, Image image) {
+ ControlDecoration d = new ControlDecoration(control, position);
+ d.setMarginWidth(2);
+ d.setImage(image);
+ d.hide();
+ return d;
+ }
+
+ protected Double parseDouble(Text text, boolean returnDefault, double defaultValue) {
+ if (text == null)
+ return null;
+ try {
+ String s = text.getText();
+ s = s.replace(',', '.');
+ return Double.valueOf(s);
+ } catch ( NumberFormatException nfe ) {
+ return returnDefault ? defaultValue : null;
+ }
+ }
+
+ protected void parseUiToData() {
+ data.label = tLabel.getText();
+ if (!data.binaryMode) {
+ if (includeChartSpecificProperties) {
+ data.min = parseDouble(tMin, true, 0.0);
+ data.max = parseDouble(tMax, true, 100.0);
+ }
+ data.interval = parseDouble(tInterval, true, 0.0);
+ data.deadband = parseDouble(tDeadband, true, 0.0);
+ data.gain = parseDouble(tGain, true, 1.0);
+ data.bias = parseDouble(tBias, true, 0.0);
+ data.unit = tUnit.getText();
+
+ if (includeChartSpecificProperties) {
+// data.drawmode = DrawMode.valueOf( cDrawMode.getText() );
+ data.drawmode = DrawMode.Line;
+
+ if (cScale.getText().equals("Manual")) {
+ data.scale = new Scale.Manual(data.min, data.max);
+ } else if (cScale.getText().equals("Auto")) {
+ data.scale = new Scale.Auto();
+ }
+ }
+ }
+ data.subscription = cSubscription.getText();
+ }
+
+ @Override
+ protected void buttonPressed(int buttonId) {
+ if (ChartDialogConstants.APPLY_ID == buttonId) {
+ applyPressed();
+ } else {
+ super.buttonPressed(buttonId);
+ }
+ }
+
+ private void applyPressed() {
+ if (applyAction != null) {
+ parseUiToData();
+ if (!baseData.equals(data)) {
+ baseData.readFrom(data);
+ applyAction.run();
+ }
+ }
+ }
+
+ @Override
+ protected void okPressed() {
+ boolean savePrefs = saveAsPrefs.getSelection();
+ parseUiToData();
+
+ if (!data.binaryMode && savePrefs) {
+ if (includeChartSpecificProperties) {
+ chartnode.put( ChartPreferences.P_DRAWMODE, data.drawmode.name() );
+ chartnode.put( ChartPreferences.P_SCALEMODE, data.scale instanceof Scale.Manual ? "Manual" : "Auto" );
+ chartnode.putDouble( ChartPreferences.P_SCALE_MIN, data.min );
+ chartnode.putDouble( ChartPreferences.P_SCALE_MAX, data.max );
+ }
+ subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_DEADBAND, data.deadband );
+ subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_INTERVAL, data.interval );
+ subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_GAIN, data.gain );
+ subscriptionnode.putDouble( SubscriptionPreferences.P_SUBSCRIPTION_BIAS, data.bias );
+ subscriptionnode.put( SubscriptionPreferences.P_SUBSCRIPTION_UNIT, data.unit );
+ }
+
+ if (savePrefs)
+ subscriptionnode.put( SubscriptionPreferences.P_SUBSCRIPTION_DEFAULT, data.subscription );
+
+ if (applyAction != null && !baseData.equals(data))
+ applyAction.run();
+ super.okPressed();
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(
+ includeChartSpecificProperties ? "Edit Chart Item"
+ : "Edit Subscription Item"
+ );
+ }
+
+ public void validate() {
+ boolean ok = true;
+ if (!data.binaryMode) {
+ if (includeChartSpecificProperties) {
+ setDecoration(tMinDecor, null);
+ setDecoration(tMaxDecor, null);
+ if (tMin != null && tMax != null) {
+ if (data.min == null || data.max == null) {
+ ok = false;
+ if (data.min == null)
+ setDecoration(tMinDecor, "Invalid non-numeric value");
+ if (data.max == null)
+ setDecoration(tMaxDecor, "Invalid non-numeric value");
+ } else {
+ if (data.min >= data.max) {
+ setDecoration(tMinDecor, "Minimum value must be smaller than maximum value");
+ setDecoration(tMaxDecor, "Maximum value must be larger than minimum value");
+ ok = false;
+ }
+ }
+ }
+ }
+
+ ok &= data.interval != null && data.deadband != null && data.bias != null && data.gain != null;
+ setDecoration(tIntervalDecor, data.interval == null ? "Invalid non-numeric value" : null);
+ if (data.interval != null && data.interval < 0)
+ setDecoration(tIntervalDecor, "Sampling interval cannot be negative");
+ setDecoration(tDeadbandDecor, data.deadband == null ? "Invalid non-numeric value" : null);
+ if (data.deadband != null && data.deadband < 0)
+ setDecoration(tDeadbandDecor, "Deadband cannot be negative");
+ setDecoration(tGainDecor, data.gain == null ? "Invalid non-numeric value" : null);
+ setDecoration(tBiasDecor, data.bias == null ? "Invalid non-numeric value" : null);
+ }
+ setFinishable(ok);
+ }
+
+ private void setDecoration(ControlDecoration decor, String desc) {
+ if (decor == null)
+ return;
+ if (desc != null) {
+ decor.setDescriptionText(desc);
+ decor.show();
+ } else {
+ decor.hide();
+ }
+ }
+
+ protected void setFinishable(boolean ok) {
+ getButton(OK).setEnabled(ok);
+ }
+
+}