X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.charts%2Fsrc%2Forg%2Fsimantics%2Fcharts%2Fui%2FChartAndSubscriptionItemDialog.java;fp=bundles%2Forg.simantics.charts%2Fsrc%2Forg%2Fsimantics%2Fcharts%2Fui%2FChartAndSubscriptionItemDialog.java;h=8bb8163455687825feca20161c86d06887bc655f;hp=e7b11047eab74cb8839c1a2147d05e5579c30127;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartAndSubscriptionItemDialog.java b/bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartAndSubscriptionItemDialog.java index e7b11047e..8bb816345 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartAndSubscriptionItemDialog.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartAndSubscriptionItemDialog.java @@ -1,629 +1,629 @@ -/******************************************************************************* - * 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); - } - -} +/******************************************************************************* + * 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); + } + +}