+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 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.editor.e4;
-
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.StringSelection;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.charset.Charset;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.inject.Named;
-
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.e4.core.di.annotations.CanExecute;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.preferences.ScopedPreferenceStore;
-import org.simantics.charts.ui.CSVProgressMonitor;
-import org.simantics.databoard.binding.error.BindingException;
-import org.simantics.databoard.parser.StringEscapeUtils;
-import org.simantics.databoard.util.Bean;
-import org.simantics.databoard.util.StreamUtil;
-import org.simantics.history.HistoryException;
-import org.simantics.history.ItemManager;
-import org.simantics.history.csv.CSVFormatter;
-import org.simantics.history.csv.ColumnSeparator;
-import org.simantics.history.csv.DecimalSeparator;
-import org.simantics.history.csv.ExportInterpolation;
-import org.simantics.history.util.subscription.SamplingFormat;
-import org.simantics.modeling.preferences.CSVPreferences;
-import org.simantics.trend.configuration.TrendItem;
-import org.simantics.trend.impl.TrendNode;
-import org.simantics.utils.format.FormattingUtils;
-import org.simantics.utils.ui.ErrorLogger;
-import org.simantics.utils.ui.workbench.WorkbenchUtils;
-
-/**
- * @author Tuukka Lehtonen
- */
-public class ChartCopyHandler {
-
- String lastFile;
-
- @CanExecute
- public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART) MPart part) {
- if (part == null)
- return false;
- if (part.getObject() instanceof TimeSeriesEditor == false)
- return false;
- return true;
- }
-
- @Execute
- public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, @Named(IServiceConstants.ACTIVE_SHELL) Shell shell) throws ExecutionException {
- if (part.getObject() instanceof TimeSeriesEditor == false)
- return;
- TimeSeriesEditor editor = (TimeSeriesEditor) part.getObject();
- final TrendNode trendNode = editor.trendNode;
- IWorkbenchPart wbpart = WorkbenchUtils.getActiveWorkbenchPart();
- IStatusLineManager status = WorkbenchUtils.getStatusLine(wbpart);
-
- final AtomicBoolean result = new AtomicBoolean(false);
- try {
- PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
- @Override
- public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
- result.set( copyDataToClipboard(monitor, trendNode, Format.JOINED_TIME, shell) );
- }
- });
- if (!result.get()) {
- status.setMessage("No data to copy");
- } else {
- status.setMessage("Copied chart data to clipboard");
- }
- status.setErrorMessage(null);
- } catch (InvocationTargetException e) {
- ErrorLogger.defaultLogError(e.getCause());
- } catch (InterruptedException e) {
- ErrorLogger.defaultLogError(e);
- }
- }
-
- static enum Format {
- TIME_VALUE_PAIRS,
- JOINED_TIME
- }
-
- public boolean copyDataToClipboard(IProgressMonitor monitor, TrendNode t, Format format, final Shell shell) {
- Charset UTF8 = Charset.forName("UTF-8");
- try {
- // String builder can be really slow when it is extended many times over.
- // Instead stream to file with buffering
-// StringBuilder sb = new StringBuilder();
- IPreferenceStore csvnode = new ScopedPreferenceStore( InstanceScope.INSTANCE, CSVPreferences.P_NODE );
- String ext = csvnode.getString(CSVPreferences.P_CSV_FILE_EXTENSION);
- File tmpFile = File.createTempFile("clipboard", ext);
- tmpFile.deleteOnExit();
- FileOutputStream fos = new FileOutputStream(tmpFile);
- BufferedWriter w = new BufferedWriter(new OutputStreamWriter(fos, UTF8));
- try {
- ItemManager im = new ItemManager( t.historian.getItems() );
- CSVFormatter formatter = new CSVFormatter();
- formatter.setTimeRange(t.horizRuler.from, t.horizRuler.end);
-
- // Write preferences
- formatter.setStartTime( csvnode.getDouble(CSVPreferences.P_CSV_START_TIME) );
- formatter.setTimeStep( csvnode.getDouble(CSVPreferences.P_CSV_TIME_STEP) );
- formatter.setDecimalSeparator( DecimalSeparator.fromPreference(csvnode.getString(CSVPreferences.P_CSV_DECIMAL_SEPARATOR) ) );
- formatter.setColumnSeparator( ColumnSeparator.fromPreference(StringEscapeUtils.unescape( csvnode.getString(CSVPreferences.P_CSV_COLUMN_SEPARATOR) ) ) );
- formatter.setResample( csvnode.getBoolean(CSVPreferences.P_CSV_RESAMPLE) );
- formatter.setNumberInterpolation( ExportInterpolation.fromPreference (csvnode.getString(CSVPreferences.P_CSV_SAMPLING_MODE) ) );
- formatter.setTimeFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_TIME_DIGITS) ) );
- formatter.setFloatFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_FLOAT_DIGITS) ) );
- formatter.setNumberFormat( FormattingUtils.significantDigitFormat( csvnode.getInt(CSVPreferences.P_CSV_DOUBLE_DIGITS) ) );
-
- for (TrendItem i : t.spec.items) {
- if (i.hidden) continue;
- List<Bean> items = im.search("variableId", i.variableId);
- Collections.sort(items, SamplingFormat.INTERVAL_COMPARATOR);
- if (items.isEmpty()) continue;
- Bean config = items.get(0);
- String historyId = (String) config.getFieldUnchecked("id");
- formatter.addItem( t.historian, historyId, i.simpleLabel, i.variableReference, i.unit);
- }
- formatter.sort();
- switch (format) {
- case TIME_VALUE_PAIRS:
-// formatter.formulate1(new CSVProgressMonitor(monitor), w);
- break;
- case JOINED_TIME:
- formatter.formulate2(new CSVProgressMonitor(monitor), w);
- break;
- default:
- throw new UnsupportedOperationException("unsupported format " + format);
- }
- w.flush();
-
- if (tmpFile.length()==0) return false;
-
- Toolkit toolkit = Toolkit.getDefaultToolkit();
- Clipboard clipboard = toolkit.getSystemClipboard();
- w.flush();
- fos.close();
- fos = null;
-
- System.out.println("Exported to "+tmpFile+" size: "+tmpFile.length());
- if ( tmpFile.length() > 10*1024*1024 ) {
-// String msg = "The data has been written to temporary file:\n"+tmpFile.getCanonicalPath();
-// ShowMessage.showInformation( shell.getDisplay(), "Too much data for clipboard.", msg);
- final File csvFile = tmpFile;
- tmpFile = null;
- shell.getDisplay().asyncExec( new Runnable() {
- @Override
- public void run() {
- FileDialog fd = new FileDialog(shell, SWT.SAVE);
- fd.setText("Write CSV to File");
- fd.setFileName( lastFile!=null ? lastFile : csvFile.getAbsolutePath() );
- String newFile = fd.open();
- if ( newFile != null ) {
- lastFile = newFile;
- File ff = new File( newFile );
- ff.delete();
- csvFile.renameTo( ff );
- } else {
- csvFile.delete();
- }
- }} );
- } else {
- String str = StreamUtil.readString(tmpFile, UTF8);
-
- StringSelection strSel = new StringSelection(str);
- clipboard.setContents(strSel, null);
- }
-
- } catch (BindingException e1) {
- ErrorLogger.defaultLogError(e1);
- return false;
- } catch (IOException e) {
- ErrorLogger.defaultLogError(e);
- } finally {
- if ( fos != null ) try { fos.close(); } catch (IOException e) { ErrorLogger.defaultLogError(e); }
- if ( tmpFile != null ) tmpFile.delete();
- }
-
- return true;
- } catch (HistoryException e) {
- ErrorLogger.defaultLogError(e);
- } catch (IOException e) {
- ErrorLogger.defaultLogError(e);
- }
- return false;
- }
-
-}
+++ /dev/null
-/*******************************************************************************
- * 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.editor.e4;
-
-import java.awt.geom.Point2D;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.inject.Inject;
-
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.e4.ui.model.application.MApplication;
-import org.eclipse.e4.ui.model.application.MApplicationElement;
-import org.eclipse.e4.ui.model.application.ui.MUIElement;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
-import org.eclipse.e4.ui.services.EContextService;
-import org.eclipse.e4.ui.workbench.modeling.EModelService;
-import org.eclipse.e4.ui.workbench.modeling.ISelectionListener;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.simantics.Simantics;
-import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;
-import org.simantics.charts.Activator;
-import org.simantics.charts.ITrendSupport;
-import org.simantics.charts.editor.ActiveRunQuery;
-import org.simantics.charts.editor.ChartData;
-import org.simantics.charts.editor.ChartKeyBindings;
-import org.simantics.charts.editor.ChartKeys;
-import org.simantics.charts.editor.ChartPasteHandler2;
-import org.simantics.charts.editor.HideItemsAction;
-import org.simantics.charts.editor.MoveHairlineAction;
-import org.simantics.charts.editor.PropertiesAction;
-import org.simantics.charts.editor.SendCommandAction;
-import org.simantics.charts.editor.SubscriptionDropParticipant;
-import org.simantics.charts.editor.TrackExperimentTimeAction;
-import org.simantics.charts.ontology.ChartResource;
-import org.simantics.charts.preference.ChartPreferences;
-import org.simantics.charts.query.FindChartItemForTrendItem;
-import org.simantics.charts.query.MilestoneSpecQuery;
-import org.simantics.charts.query.SetProperty;
-import org.simantics.charts.query.TrendSpecQuery;
-import org.simantics.charts.ui.ChartLinkData;
-import org.simantics.databoard.Bindings;
-import org.simantics.databoard.util.ObjectUtils;
-import org.simantics.db.AsyncReadGraph;
-import org.simantics.db.ReadGraph;
-import org.simantics.db.Resource;
-import org.simantics.db.Session;
-import org.simantics.db.common.request.ParametrizedRead;
-import org.simantics.db.common.request.UniqueRead;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.request.combinations.Combinators;
-import org.simantics.db.layer0.variable.RVI;
-import org.simantics.db.layer0.variable.RVIBuilder;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.db.layer0.variable.Variables;
-import org.simantics.db.layer0.variable.Variables.Role;
-import org.simantics.db.procedure.AsyncListener;
-import org.simantics.db.procedure.SyncListener;
-import org.simantics.diagram.participant.SGFocusParticipant;
-import org.simantics.diagram.participant.e4.ContextUtil;
-import org.simantics.g2d.canvas.ICanvasContext;
-import org.simantics.g2d.canvas.impl.CanvasContext;
-import org.simantics.g2d.chassis.AWTChassis;
-import org.simantics.g2d.chassis.ICanvasChassis;
-import org.simantics.g2d.chassis.IChassisListener;
-import org.simantics.g2d.chassis.SWTChassis;
-import org.simantics.g2d.participant.KeyToCommand;
-import org.simantics.g2d.participant.TimeParticipant;
-import org.simantics.g2d.utils.CanvasUtils;
-import org.simantics.history.Collector;
-import org.simantics.history.HistoryManager;
-import org.simantics.history.impl.FileHistory;
-import org.simantics.project.IProject;
-import org.simantics.scenegraph.INode;
-import org.simantics.scenegraph.g2d.events.Event;
-import org.simantics.scenegraph.g2d.events.EventTypes;
-import org.simantics.scenegraph.g2d.events.IEventHandler;
-import org.simantics.scenegraph.g2d.events.MouseEvent;
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
-import org.simantics.scenegraph.g2d.events.command.Commands;
-import org.simantics.selectionview.StandardPropertyPage;
-import org.simantics.simulation.data.Datasource;
-import org.simantics.simulation.experiment.ExperimentState;
-import org.simantics.simulation.experiment.IExperiment;
-import org.simantics.simulation.experiment.IExperimentListener;
-import org.simantics.simulation.ontology.SimulationResource;
-import org.simantics.trend.TrendInitializer;
-import org.simantics.trend.TrendInitializer.StepListener;
-import org.simantics.trend.configuration.ItemPlacement;
-import org.simantics.trend.configuration.LineQuality;
-import org.simantics.trend.configuration.TimeFormat;
-import org.simantics.trend.configuration.TrendSpec;
-import org.simantics.trend.impl.HorizRuler;
-import org.simantics.trend.impl.ItemNode;
-import org.simantics.trend.impl.MilestoneSpec;
-import org.simantics.trend.impl.TrendNode;
-import org.simantics.trend.impl.TrendParticipant;
-import org.simantics.ui.workbench.IPropertyPage;
-import org.simantics.ui.workbench.IResourceEditorInput;
-import org.simantics.ui.workbench.ResourceEditorInput;
-import org.simantics.ui.workbench.action.PerformDefaultAction;
-import org.simantics.ui.workbench.e4.E4ResourceEditorBase;
-import org.simantics.ui.workbench.editor.input.InputValidationCombinators;
-import org.simantics.utils.datastructures.hints.HintListenerAdapter;
-import org.simantics.utils.datastructures.hints.IHintContext;
-import org.simantics.utils.datastructures.hints.IHintContext.Key;
-import org.simantics.utils.datastructures.hints.IHintObservable;
-import org.simantics.utils.format.ValueFormat;
-import org.simantics.utils.threads.AWTThread;
-import org.simantics.utils.threads.IThreadWorkQueue;
-import org.simantics.utils.threads.SWTThread;
-import org.simantics.utils.threads.ThreadUtils;
-import org.simantics.utils.ui.BundleUtils;
-import org.simantics.utils.ui.ErrorLogger;
-import org.simantics.utils.ui.ExceptionUtils;
-import org.simantics.utils.ui.SWTUtils;
-import org.simantics.utils.ui.dialogs.ShowMessage;
-import org.simantics.utils.ui.jface.ActiveSelectionProvider;
-
-/**
- * TimeSeriesEditor is an interactive part that draws a time series chart.
- *
- * The configuration model is {@link TrendSpec} which is read through
- * {@link TrendSpecQuery}. In Simantics Environment the
- * editor input is {@link ResourceEditorInput}.
- *
- * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
- * @author Tuukka Lehtonen
- */
-public class TimeSeriesEditor extends E4ResourceEditorBase implements IAdaptable {
-
- ParametrizedRead<IResourceEditorInput, Boolean> INPUT_VALIDATOR =
- Combinators.compose(
- InputValidationCombinators.hasURI(),
- InputValidationCombinators.extractInputResource()
- );
-
- protected ParametrizedRead<IResourceEditorInput, Boolean> getInputValidator() {
- return INPUT_VALIDATOR;
- }
-
- /**
- * The root property browse context of the time series editor. A transitive
- * closure is calculated for this context.
- */
- private static String ROOT_PROPERTY_BROWSE_CONTEXT = ChartResource.URIs.ChartBrowseContext;
-
- /**
- * ID of the this editor part extension.
- */
- public static final String ID = "org.simantics.charts.editor.timeseries";
-
- public static final String CONTRIBUTION_URI = "bundleclass://org.simantics.charts/org.simantics.charts.editor.e4.TimeSeriesEditor";
-
- private static final String CONTEXT_MENU_ID = "#timeSeriesChart";
-
- private IEclipsePreferences chartPreferenceNode;
-
- private final ImageDescriptor IMG_ZOOM_TO_FIT = BundleUtils.getImageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/horizAndVert16.png");
- private final ImageDescriptor IMG_ZOOM_TO_FIT_HORIZ = BundleUtils.getImageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/horiz16.png");
- private final ImageDescriptor IMG_ZOOM_TO_FIT_VERT = BundleUtils.getImageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/vert16.png");
- private final ImageDescriptor IMG_AUTOSCALE = BundleUtils.getImageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/autoscale16.png");
-
- IPreferenceChangeListener preferenceListener = new IPreferenceChangeListener() {
-
- @Override
- public void preferenceChange(PreferenceChangeEvent event) {
- if (isDisposed()) {
- System.err.println("Warning: pref change to disposed TimeSeriesEditor");
- return;
- }
-
- if ( event.getKey().equals(ChartPreferences.P_REDRAW_INTERVAL ) ||
- event.getKey().equals(ChartPreferences.P_AUTOSCALE_INTERVAL )) {
- long redraw_interval = chartPreferenceNode.getLong(ChartPreferences.P_REDRAW_INTERVAL, ChartPreferences.DEFAULT_REDRAW_INTERVAL);
- long autoscale_interval = chartPreferenceNode.getLong(ChartPreferences.P_AUTOSCALE_INTERVAL, ChartPreferences.DEFAULT_AUTOSCALE_INTERVAL);
- setInterval( redraw_interval, autoscale_interval );
- }
- if ( event.getKey().equals(ChartPreferences.P_DRAW_SAMPLES )) {
- boolean draw_samples = chartPreferenceNode.getBoolean(ChartPreferences.P_DRAW_SAMPLES, ChartPreferences.DEFAULT_DRAW_SAMPLES);
- setDrawSamples( draw_samples );
- }
- if ( event.getKey().equals(ChartPreferences.P_TIMEFORMAT ) ) {
- String s = chartPreferenceNode.get(ChartPreferences.P_TIMEFORMAT, ChartPreferences.DEFAULT_TIMEFORMAT);
- TimeFormat tf = TimeFormat.valueOf( s );
- if (tf!=null) setTimeFormat( tf );
- }
- if ( event.getKey().equals(ChartPreferences.P_VALUEFORMAT ) ) {
- String s = chartPreferenceNode.get(ChartPreferences.P_VALUEFORMAT, ChartPreferences.DEFAULT_VALUEFORMAT);
- ValueFormat vf = ValueFormat.valueOf( s );
- if (vf!=null) setValueFormat( vf );
- }
- if ( event.getKey().equals(ChartPreferences.P_ITEMPLACEMENT)) {
- String s = chartPreferenceNode.get(ChartPreferences.P_ITEMPLACEMENT, ChartPreferences.DEFAULT_ITEMPLACEMENT);
- ItemPlacement ip = ItemPlacement.valueOf(s);
- if (trendNode!=null) trendNode.itemPlacement = ip;
- }
- if ( event.getKey().equals(ChartPreferences.P_TEXTQUALITY) || event.getKey().equals(ChartPreferences.P_LINEQUALITY) ) {
- String s1 = chartPreferenceNode.get(ChartPreferences.P_TEXTQUALITY, ChartPreferences.DEFAULT_TEXTQUALITY);
- String s2 = chartPreferenceNode.get(ChartPreferences.P_LINEQUALITY, ChartPreferences.DEFAULT_LINEQUALITY);
- LineQuality q1 = LineQuality.valueOf(s1);
- LineQuality q2 = LineQuality.valueOf(s2);
- if (trendNode!=null) trendNode.quality.textQuality = q1;
- if (trendNode!=null) trendNode.quality.lineQuality = q2;
- }
-
- }
- };
-
- /**
- * The project which this editor is listening to for changes to
- * {@link ChartKeys.ChartSourceKey keys}.
- */
- IProject project;
-
- /**
- * The text widget shown only if there is no IProject available at the time
- * of editor part creation.
- */
- Text errorText;
-
- /**
- * A unique key for making DB requests chart editor specific without binding
- * the requests to the editor object itself.
- */
- UUID uniqueChartEditorId = UUID.randomUUID();
- Logger log;
- Display display;
- SWTChassis canvas;
- CanvasContext cvsCtx;
- TrendParticipant tp;
- TrendNode trendNode;
- StepListener stepListener;
- MilestoneSpecListener milestoneListener;
- MilestoneSpecQuery milestoneQuery;
-
- /**
- * The ChartData instance used by this editor for sourcing data at any given
- * moment. Project hint instances are copied into this instance.
- */
- final ChartData chartData = new ChartData(null, null, null, null, null, null);
-
- /**
- * The ChartSourceKey to match the model this editor was opened for.
- * @see #model
- * @see #init(IEditorSite, IEditorInput)
- */
- ChartKeys.ChartSourceKey chartDataKey;
-
-
- /**
- * Context management utils
- */
- protected IThreadWorkQueue swt;
- protected ContextUtil contextUtil;
-
- class ExperimentStateListener implements IExperimentListener {
- @Override
- public void stateChanged(ExperimentState state) {
- TrendSpec spec = trendNode.getTrendSpec();
- spec.experimentIsRunning = state == ExperimentState.RUNNING;
- if (spec.experimentIsRunning && spec.viewProfile.trackExperimentTime) {
- TrendParticipant t = tp;
- if (t != null)
- t.setDirty();
- }
- }
- }
-
- ExperimentStateListener experimentStateListener = new ExperimentStateListener();
-
- class ChartDataListener extends HintListenerAdapter implements Runnable {
- @Override
- public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
- if (key.equals(chartDataKey)) {
- // @Thread any
- if (!cvsCtx.isDisposed() && cvsCtx.isAlive()) {
- cvsCtx.getThreadAccess().asyncExec(this);
- }
- }
- }
- @Override
- public void run() {
- // @Thread AWT
- if (cvsCtx.isDisposed() || !cvsCtx.isAlive()) return;
- ChartData data = Simantics.getProject().getHint(chartDataKey);
- setInput( data, trendNode.getTrendSpec() );
- }
- }
-
- ChartDataListener chartDataListener = new ChartDataListener();
-
- class ValueTipBoxPositionListener extends HintListenerAdapter {
- @Override
- public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
- if (key.equals(TrendParticipant.KEY_VALUE_TIP_BOX_RELATIVE_POS) && newValue != null) {
- Session s = Simantics.getSession();
- ChartResource CHART = s.getService(ChartResource.class);
- Point2D p = (Point2D) newValue;
- double[] value = { p.getX(), p.getY() };
- s.asyncRequest(new SetProperty(getInputResource(), CHART.Chart_valueViewPosition, value, Bindings.DOUBLE_ARRAY));
- }
- }
- }
-
- ValueTipBoxPositionListener valueTipBoxPositionListener = new ValueTipBoxPositionListener();
-
-
- private void handleLinkDataChange() {
- final ChartLinkData newData = linkData;
- trendNode.autoscaletime = newData == null || newData.sender == TimeSeriesEditor.this;
-
- if ( newData == null || newData.sender==TimeSeriesEditor.this ) return;
- TrendNode tn = trendNode;
- HorizRuler hr = tn!=null ? tn.horizRuler : null;
-
- ChartLinkData oldData = new ChartLinkData();
- getFromEnd(oldData);
-
- if ( hr != null && !ObjectUtils.objectEquals(tn.valueTipTime, newData.valueTipTime)) {
- tn.valueTipTime = newData.valueTipTime;
- tp.setDirty();
- }
-
- if ( hr != null && (oldData.from!=newData.from || oldData.sx!=newData.sx)) {
-
- cvsCtx.getThreadAccess().asyncExec( new Runnable() {
- @Override
- public void run() {
- boolean b = trendNode.horizRuler.setFromScale(newData.from, newData.sx);
- trendNode.horizRuler.autoscroll = false;
- if (b) {
- trendNode.layout();
- tp.setDirty();
- }
- }});
- }
- }
-
- // Link-Time
-// State linkTimeState;
-// IStateListener linkTimeStateListener = new IStateListener() {
-// @Override
-// public void handleStateChange(State state, Object oldValue) {
-//
-//
-// }
-// };
-
- HorizRuler.TimeWindowListener horizRulerListener = new HorizRuler.TimeWindowListener() {
- @Override
- public void onNewWindow(double from, double end, double scalex) {
- final ChartLinkData oldData = linkData;
- if (oldData != null) {
- ChartLinkData data = new ChartLinkData(TimeSeriesEditor.this, from, end, scalex);
- data.valueTipTime = trendNode.valueTipTime;
- linkData = data;
- handleLinkDataChange();
- }
- }
- };
-
- class ChassisListener implements IChassisListener {
- @Override
- public void chassisClosed(ICanvasChassis sender) {
- // Prevent deadlock while disposing which using syncExec would result in.
- final ICanvasContext ctx = cvsCtx;
- ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {
- @Override
- public void run() {
- if (ctx != null) {
- AWTChassis awt = canvas.getAWTComponent();
- if (awt != null)
- awt.setCanvasContext(null);
- ctx.dispose();
- }
- }
- });
- canvas.removeChassisListener(ChassisListener.this);
- }
- }
-
- ActiveSelectionProvider selectionProvider = new ActiveSelectionProvider();
- MenuManager menuManager;
-
- @Inject
- EContextService contextService;
-
- private ChartLinkData linkData;
-
- public TimeSeriesEditor() {
- log = Logger.getLogger( this.getClass().getName() );
- }
-
- @Override
- public void initImpl(MPart part) {
- EModelService modelService = getContext().get(EModelService.class);
- MApplication app = getContext().get(MApplication.class);
- MUIElement element = modelService.cloneSnippet(app, "org.simantics.charts.toolbar.default.snippet", null);
- if (element != null) {
- element.setVisible(true);
- element.setToBeRendered(true);
- part.setToolbar((MToolBar)element);
- }
-
-// MBindingContext dialogAndWindowContext = findMAppElementById(app.getRootContext(), "org.eclipse.ui.contexts.dialogAndWindow");
-// MBindingContext windowContext = findMAppElementById(dialogAndWindowContext.getChildren(), "org.eclipse.ui.contexts.window");
-// MBindingContext chartContext = findMAppElementById(windowContext.getChildren(), "org.simantics.charts.editor.context");
-// if (chartContext == null) {
-// chartContext = MCommandsFactory.INSTANCE.createBindingContext();
-// chartContext.setContributorURI("bundle://test.uri");
-// chartContext.setElementId("org.simantics.charts.editor.context");
-// chartContext.setName("In Chart Editor");
-// chartContext.setDescription("Chart Editor Binding Context");
-// windowContext.getChildren().add(chartContext);
-// }
-// MBindingTable chartBindingTable = findMAppElementById(app.getBindingTables(), "org.simantics.charts.editor.context");
-// if (chartBindingTable == null) {
-// chartBindingTable = MCommandsFactory.INSTANCE.createBindingTable();
-// chartBindingTable.setContributorURI("bundle://test.test.uri");
-// chartBindingTable.setElementId("org.simantics.charts.editor.context");
-// chartBindingTable.setBindingContext(chartContext);
-//
-// for (MCommand command : app.getCommands()) {
-// if (command.getElementId().equals("org.simantics.chart.canvasCommandDelegateCommand")) {
-//
-// MParameter param = MCommandsFactory.INSTANCE.createParameter();
-// param.setElementId("id");
-// param.setName("org.simantics.charts.commandparameter.canvasCommandDelegateParameter");
-// param.setValue("zoomToFit");
-// MKeyBinding keyBinding = MCommandsFactory.INSTANCE.createKeyBinding();
-// keyBinding.setKeySequence("1");
-// keyBinding.setCommand(command);
-// keyBinding.getParameters().add(param);
-// chartBindingTable.getBindings().add(keyBinding);
-//
-// break;
-// }
-// }
-//
-// app.getBindingTables().add(chartBindingTable);
-// }
-// if (!part.getBindingContexts().contains(chartContext))
-// part.getBindingContexts().add(chartContext);
- }
-
- private <T extends MApplicationElement> T findMAppElementById(List<T> appElements, String elementId) {
- for (T element : appElements) {
- if (element.getElementId() != null && element.getElementId().equals(elementId)) {
- return element;
- }
- }
- return null;
- }
-
-
- /**
- * Invoke this only from the AWT thread.
- * @param context
- */
- protected void setCanvasContext(final SWTChassis chassis, final ICanvasContext context) {
- // Cannot directly invoke SWTChassis.setCanvasContext only because it
- // needs to be invoked in the SWT thread and AWTChassis.setCanvasContext in the
- // AWT thread, but directly invoking SWTChassis.setCanvasContext would call both
- // in the SWT thread which would cause synchronous scheduling of AWT
- // runnables which is always a potential source of deadlocks.
- chassis.getAWTComponent().setCanvasContext(context);
- SWTUtils.asyncExec(chassis, new Runnable() {
- @Override
- public void run() {
- if (!chassis.isDisposed())
- // For AWT, this is a no-operation.
- chassis.setCanvasContext(context);
- }
- });
- }
-
- @Override
- public void createPartControl(Composite parent) {
- this.chartDataKey = ChartKeys.chartSourceKey(assertInputModelResource());
- display = parent.getDisplay();
- swt = SWTThread.getThreadAccess(display);
-
- // Must have a project to attach to, otherwise the editor is useless.
- project = Simantics.peekProject();
- if (project == null) {
- errorText = new Text(parent, SWT.NONE);
- errorText.setText("No project is open.");
- errorText.setEditable(false);
- return;
- }
-
- // Create the canvas context here before finishing createPartControl
- // to give anybody requiring access to this editor's ICanvasContext
- // a chance to do their work.
- // The context can be created in SWT thread without scheduling
- // to the context thread and having potential deadlocks.
- // The context is locked here and unlocked after it has been
- // initialized in the AWT thread.
- IThreadWorkQueue thread = AWTThread.getThreadAccess();
- cvsCtx = new CanvasContext(thread);
- cvsCtx.setLocked(true);
-
- canvas = new SWTChassis(parent, SWT.NONE);
- canvas.populate(parameter -> {
- if (!isDisposed()) {
- canvas.addChassisListener(new ChassisListener());
- initializeCanvas(canvas, cvsCtx);
- }
- });
-
- // Link time
-// ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
-// Command command = service.getCommand( LinkTimeHandler.COMMAND_ID );
-// linkTimeState = command.getState( LinkTimeHandler.STATE_ID );
-// if ( linkTimeState != null ) linkTimeState.addListener( linkTimeStateListener );
-
- // TODO: Link time E4 way!
-
-
- linkData = new ChartLinkData();
-
- addPopupMenu();
-
- // Start tracking editor input validity.
- activateValidation();
-
- // Provide input as selection for property page.
-// selectionProvider.setSelection( new StructuredSelection(getInputResource()) );
-
- getSelectionService().setSelection(new StructuredSelection(getInputResource()));
- getSelectionService().addSelectionListener(getPart().getElementId(), new ISelectionListener() {
-
- @Override
- public void selectionChanged(MPart part, Object selection) {
- System.out.println("selection changed!");
- }
- });
-
-// getSite().setSelectionProvider( selectionProvider );
- }
-
- protected void initializeCanvas(final SWTChassis chassis, CanvasContext cvsCtx) {
- // Initialize canvas context
- TrendSpec nodata = new TrendSpec();
- nodata.init();
- cvsCtx = TrendInitializer.defaultInitializeCanvas(cvsCtx, null, null, null, nodata);
-
- tp = cvsCtx.getAtMostOneItemOfClass(TrendParticipant.class);
-
-
-// IContextService contextService = (IContextService) getSite().getService(IContextService.class);
- contextUtil = new ContextUtil(contextService, swt);
-
-
- cvsCtx.add( new SubscriptionDropParticipant( getInputResource() ) );
- cvsCtx.add( new KeyToCommand( ChartKeyBindings.DEFAULT_BINDINGS ) );
- cvsCtx.add( new ChartPasteHandler2(getInputResource()) );
- cvsCtx.add(contextUtil);
-
- // Context management
- cvsCtx.add(new SGFocusParticipant(canvas, "org.simantics.charts.editor.context"));
-
- stepListener = new StepListener( tp );
- trendNode = tp.getTrend();
- trendNode.titleNode.remove();
- trendNode.titleNode = null;
-
- // Link time
- trendNode.horizRuler.listener = horizRulerListener;
-
- final ChartLinkData linkTime = linkData;
- if (linkTime!=null) trendNode.horizRuler.setFromEnd(linkTime.from, linkTime.sx);
-
- // Handle mouse moved event after TrendParticipant.
- // This handler forwards trend.mouseHoverTime to linkTimeState
- cvsCtx.getEventHandlerStack().add( new IEventHandler() {
-
- @Override
- public int getEventMask() {
- return EventTypes.MouseMovedMask | EventTypes.MouseClickMask | EventTypes.CommandMask | EventTypes.KeyPressed;
- }
-
- @Override
- public boolean handleEvent(Event e) {
-
-// System.out.println("LinkEventHandler: "+e);
- ChartLinkData oldData = linkData;
- if (oldData!=null) {
- ChartLinkData newData = new ChartLinkData();
- getFromEnd(newData);
- if (!newData.equals(oldData)) {
-// System.out.println("Sending new link-data");
- linkData = newData;
- handleLinkDataChange();
- }
- }
- return false;
- }}, -1);
-
- // Canvas context is initialized, unlock it now to allow rendering.
- cvsCtx.setLocked(false);
-
- setCanvasContext(chassis, cvsCtx);
-
- cvsCtx.getEventHandlerStack().add(new IEventHandler() {
- @Override
- public boolean handleEvent(Event e) {
- MouseButtonReleasedEvent event = (MouseButtonReleasedEvent) e;
- if (event.button != MouseEvent.RIGHT_BUTTON)
- return false;
-
- final Point p = new Point((int) event.screenPosition.getX(), (int) event.screenPosition.getY());
- SWTUtils.asyncExec(chassis, new Runnable() {
- @Override
- public void run() {
- if (!canvas.isDisposed())
- showPopup(p);
- }
- });
- return true;
- }
- @Override
- public int getEventMask() {
- return EventTypes.MouseButtonReleasedMask;
- }
- }, 1000000);
-
- // Track data source and preinitialize chartData
- project.addHintListener(chartDataListener);
- chartData.readFrom( (ChartData) project.getHint( chartDataKey ) );
-
- if (chartData.run != null) {
- milestoneListener = new MilestoneSpecListener();
- milestoneQuery = new MilestoneSpecQuery( chartData.run );
- Simantics.getSession().asyncRequest( milestoneQuery, milestoneListener );
- }
-
- // IMPORTANT: Only after preinitializing chartData, start tracking chart configuration
- trackChartConfiguration();
- trackPreferences();
-
- // Write changes to TrendSpec.viewProfile.valueViewPosition[XY]
- // back to the graph database.
- cvsCtx.getHintStack().addHintListener(valueTipBoxPositionListener);
- }
-
- private void addPopupMenu() {
-
-// #TODO: FINISH THIS WHEN E4 WORKBENCH
-// MPopupMenu popupMenu = MMenuFactory.INSTANCE.createPopupMenu();
-// popupMenu.setLabel("Time Series Editor");
-// popupMenu.setElementId(CONTEXT_MENU_ID);
-//
-// for (MCommand command : getPart().getContext().get(MApplication.class).getCommands()) {
-// if (command.getElementId().equals("org.simantics.chart.canvasCommandDelegateCommand")) {
-// MParameter param = MCommandsFactory.INSTANCE.createParameter();
-// param.setElementId("id");
-// param.setName("org.simantics.charts.commandparameter.canvasCommandDelegateParameter");
-// param.setValue("zoomToFit");
-// MHandledMenuItem mmenuItem = MMenuFactory.INSTANCE.createHandledMenuItem();
-// mmenuItem.setLabel("Zoom to Fit");
-// mmenuItem.setCommand(command);
-// mmenuItem.getParameters().add(param);
-// }
-// }
-//
-// getPart().getContext().get(EMenuService.class).registerContextMenu(canvas, CONTEXT_MENU_ID);
-
-
-
- menuManager = new MenuManager("Time Series Editor", CONTEXT_MENU_ID);
- menuManager.setRemoveAllWhenShown(true);
- Menu menu = menuManager.createContextMenu(canvas);
- canvas.setMenu(menu);
- // TODO: link to modeled menu in E4 way
-// getEditorSite().registerContextMenu(menuManager.getId(), menuManager, selectionProvider);
-
- // Add support for some built-in actions in the context menu.
- menuManager.addMenuListener(new IMenuListener() {
- @Override
- public void menuAboutToShow(IMenuManager manager) {
- // Not initialized yet, prevent NPE.
- TrendNode trendNode = TimeSeriesEditor.this.trendNode;
- TrendParticipant tp = TimeSeriesEditor.this.tp;
- if (trendNode == null || tp == null)
- return;
-
- TrendSpec trendSpec = trendNode.getTrendSpec();
- ItemNode hoverItem = tp.hoveringItem;
- if (hoverItem != null && hoverItem.item != null) {
- Resource component = resolveReferencedComponent(hoverItem.item.variableId);
- if (component != null) {
- manager.add(new PerformDefaultAction("Show Referenced Component", canvas, component));
- }
-
- Resource chart = TimeSeriesEditor.this.getInputResource();
- if ( chart != null ) {
- try {
- Resource chartItem = Simantics.getSession().sync( new FindChartItemForTrendItem(chart, hoverItem.item) );
- if (chartItem != null) {
- manager.add(new HideItemsAction("Hide Item", true, Collections.singletonList(chartItem)));
- manager.add(new Separator());
- manager.add(new PropertiesAction("Item Properties", canvas, chartItem));
- manager.add(new PropertiesAction("Chart Properties", canvas, chart));
- }
- } catch (DatabaseException e) {
- Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to resolve context menu items.", e));
- }
- }
- } else {
- boolean hairlineMovementAllowed =
- !(trendSpec.experimentIsRunning &&
- trendSpec.viewProfile.trackExperimentTime);
-
- Resource chart = TimeSeriesEditor.this.getInputResource();
- manager.add(new Separator());
- manager.add(new MoveHairlineAction(
- "Move Hairline Here",
- chart,
- hairlineMovementAllowed,
- trendNode,
- trendNode.mouseHoverTime
- ));
- manager.add(new MoveHairlineAction(
- "Move Hairline To Current Time",
- chart,
- hairlineMovementAllowed,
- trendNode,
- trendNode.horizRuler.getItemEndTime(),
- Boolean.FALSE
- ));
- manager.add(new TrackExperimentTimeAction(
- "Hairline Tracks Current Time",
- chart,
- trendSpec.viewProfile.trackExperimentTime));
- manager.add(new Separator());
- manager.add(new SendCommandAction("Zoom to Fit", IMG_ZOOM_TO_FIT, cvsCtx, Commands.ZOOM_TO_FIT));
- manager.add(new SendCommandAction("Zoom to Fit Horizontally", IMG_ZOOM_TO_FIT_HORIZ, cvsCtx, Commands.ZOOM_TO_FIT_HORIZ));
- manager.add(new SendCommandAction("Zoom to Fit Vertically", IMG_ZOOM_TO_FIT_VERT, cvsCtx, Commands.ZOOM_TO_FIT_VERT));
- manager.add(new SendCommandAction("Autoscale Chart", IMG_AUTOSCALE, cvsCtx, Commands.AUTOSCALE));
- manager.add(new Separator());
- manager.add(new PropertiesAction("Chart Properties", canvas, chart));
- }
- }
- });
- }
-
- protected Resource resolveReferencedComponent(final String variableId) {
- try {
- return Simantics.getSession().sync(new UniqueRead<Resource>() {
- @Override
- public Resource perform(ReadGraph graph) throws DatabaseException {
- Variable configuration = Variables.getConfigurationContext(graph, getInputResource());
- RVI rvi = RVI.fromResourceFormat(graph, variableId);
- rvi = new RVIBuilder(rvi).removeFromFirstRole(Role.PROPERTY).toRVI();
- if (rvi.isEmpty())
- return null;
- Variable var = rvi.resolve(graph, configuration);
- return var.getPossibleRepresents(graph);
- }
- });
- } catch (DatabaseException e) {
- ErrorLogger.defaultLogError(e);
- }
- return null;
- }
-
- private void showPopup(Point p) {
- menuManager.getMenu().setLocation(p);
- menuManager.getMenu().setVisible(true);
- }
-
- private void trackChartConfiguration() {
- Simantics.getSession().asyncRequest(new TrendSpecQuery( uniqueChartEditorId, getInputResource() ), new TrendSpecListener());
- Simantics.getSession().asyncRequest(new ActiveRunQuery( uniqueChartEditorId, getInputResource() ), new ActiveRunListener());
- }
-
- @Override
- public void setFocus() {
- if (errorText != null)
- errorText.setFocus();
- else
- canvas.setFocus();
- }
-
- @Override
- public void dispose() {
- if (isDisposed() == true) return;
-
- if (trendNode!=null && trendNode.horizRuler!=null) {
- trendNode.horizRuler.listener = null;
- }
-
-// if ( linkTimeState != null ) linkTimeState.removeListener( linkTimeStateListener );
-
- canvas.getHintContext().removeHint( SWTChassis.KEY_EDITORPART );
- canvas.getHintContext().removeHint( SWTChassis.KEY_WORKBENCHPAGE );
- canvas.getHintContext().removeHint( SWTChassis.KEY_WORKBENCHWINDOW );
-
- if ( chartPreferenceNode!= null ) {
- chartPreferenceNode.removePreferenceChangeListener( preferenceListener );
- }
-
- MilestoneSpecListener ml = milestoneListener;
- if (ml!=null) ml.dispose();
-
- if (project != null) {
- project.removeHintListener(chartDataListener);
- }
-
- if (chartData != null) {
- if (chartData.datasource!=null)
- chartData.datasource.removeListener( stepListener );
- if (chartData.experiment!=null)
- chartData.experiment.removeListener( experimentStateListener );
- chartData.readFrom( null );
- }
- }
-
- /**
- * @param data new data or null
- * @param newSpec new spec or null
- * @thread AWT
- */
- @SuppressWarnings("unused")
- public void setInput(ChartData data, TrendSpec newSpec) {
- boolean doLayout = false;
-
- // Disregard input if it is not for this chart's containing model.
- if (data != null && data.model != null && !data.model.equals(assertInputModelResource()))
- data = null;
-
- // Accommodate Datasource changes
- Datasource: {
- Datasource oldDatasource = chartData==null?null:chartData.datasource;
- Datasource newDatasource = data==null?null:data.datasource;
- //if ( !ObjectUtils.objectEquals(oldDatasource, newDatasource) )
- {
- if (oldDatasource!=null) oldDatasource.removeListener( stepListener );
- if (newDatasource!=null) newDatasource.addListener( stepListener );
- }
- }
-
- Experiment: {
- IExperiment oldExperiment = chartData==null?null:chartData.experiment;
- IExperiment newExperiment = data==null?null:data.experiment;
- //if ( !ObjectUtils.objectEquals(oldExperiment, newExperiment) )
- {
- if (oldExperiment!=null) oldExperiment.removeListener( experimentStateListener );
- if (newExperiment!=null) newExperiment.addListener( experimentStateListener );
- }
- }
-
- // Accommodate Historian changes
- Historian: {
- HistoryManager oldHistorian = trendNode.historian==null?null:trendNode.historian;
- HistoryManager newHistorian = data==null?null:data.history;
- Collector newCollector = data==null?null:data.collector;
- // if ( !ObjectUtils.objectEquals(oldHistorian, newHistorian) )
- {
- if (newHistorian instanceof FileHistory) {
- FileHistory fh = (FileHistory) newHistorian;
- System.out.println("History = "+fh.getWorkarea());
- }
- trendNode.setHistorian( newHistorian, newCollector );
- doLayout |= trendNode.autoscale(true, true) | !ObjectUtils.objectEquals(oldHistorian, newHistorian);
- }
-
- // Accommodate TrendSpec changes
- TrendSpec oldSpec = trendNode.getTrendSpec();
- if ( !newSpec.equals(oldSpec) ) {
- trendNode.setTrendSpec( newSpec==null?TrendSpec.EMPTY:newSpec );
- doLayout = true;
- }
-
- }
-
- Resource newExperimentResource = data==null ? null : data.run;
- Resource oldExperimentResource = this.chartData == null ? null : this.chartData.run;
-
- // Track milestones
- Milestones: {
- if (!ObjectUtils.objectEquals(oldExperimentResource, newExperimentResource)) {
-
- // Dispose old listener & Query
- if (milestoneListener!=null) {
- milestoneListener.dispose();
- milestoneListener = null;
- }
- if (milestoneQuery!=null) {
- milestoneQuery = null;
- }
-
- trendNode.setMilestones( MilestoneSpec.EMPTY );
-
- if (newExperimentResource != null) {
- milestoneListener = new MilestoneSpecListener();
- milestoneQuery = new MilestoneSpecQuery( newExperimentResource );
- Simantics.getSession().asyncRequest( milestoneQuery, milestoneListener );
- }
- }
-
- }
-
- if (doLayout) trendNode.layout();
- this.chartData.readFrom( data );
- tp.setDirty();
-
- if (!ObjectUtils.objectEquals(oldExperimentResource, newExperimentResource)) {
- resetViewAfterDataChange();
- }
-
- }
-
- class ActiveRunListener implements SyncListener<Resource> {
- @Override
- public void exception(ReadGraph graph, Throwable throwable) {
- ErrorLogger.defaultLogError(throwable);
- ShowMessage.showError(throwable.getClass().getSimpleName(), throwable.getMessage());
- }
- @Override
- public void execute(ReadGraph graph, final Resource run) throws DatabaseException {
- if(run != null) {
- SimulationResource SIMU = SimulationResource.getInstance(graph);
- Variable var = Variables.getVariable(graph, run);
- IExperiment exp = var.getPossiblePropertyValue(graph, SIMU.Run_iExperiment);
- ITrendSupport ts = exp.getService(ITrendSupport.class);
- ts.setChartData(graph);
- }
- }
- @Override
- public boolean isDisposed() {
- return TimeSeriesEditor.this.isDisposed();
- }
- }
-
- class TrendSpecListener implements AsyncListener<TrendSpec> {
- @Override
- public void exception(AsyncReadGraph graph, Throwable throwable) {
-
- ErrorLogger.defaultLogError(throwable);
- ShowMessage.showError(throwable.getClass().getSimpleName(), throwable.getMessage());
- }
- @Override
- public void execute(AsyncReadGraph graph, final TrendSpec result) {
- if (result == null) {
- log.log(Level.INFO, "Chart configuration removed");
- } else {
- log.log(Level.INFO, "Chart configuration updated: " + result);
- }
-
- // Reload chart in AWT Thread
- AWTThread.getThreadAccess().asyncExec(new Runnable() {
- @Override
- public void run() {
- if (!isDisposed())
- setInput( chartData, result );
- }
- });
- }
- @Override
- public boolean isDisposed() {
- return TimeSeriesEditor.this.isDisposed();
- }
- }
-
- class MilestoneSpecListener implements AsyncListener<MilestoneSpec> {
- boolean disposed = false;
- @Override
- public void execute(AsyncReadGraph graph, final MilestoneSpec result) {
- AWTThread.INSTANCE.asyncExec(new Runnable() {
- public void run() {
- trendNode.setMilestones(result);
- }});
- }
-
- @Override
- public void exception(AsyncReadGraph graph, Throwable throwable) {
-
- }
-
- @Override
- public boolean isDisposed() {
- return disposed;
- }
-
- public void dispose() {
- disposed = true;
- }
-
- }
-
- private void trackPreferences() {
- chartPreferenceNode = InstanceScope.INSTANCE.getNode( "org.simantics.charts" );
- chartPreferenceNode.addPreferenceChangeListener( preferenceListener );
- long redrawInterval = chartPreferenceNode.getLong(ChartPreferences.P_REDRAW_INTERVAL, ChartPreferences.DEFAULT_REDRAW_INTERVAL);
- long autoscaleInterval = chartPreferenceNode.getLong(ChartPreferences.P_AUTOSCALE_INTERVAL, ChartPreferences.DEFAULT_AUTOSCALE_INTERVAL);
- setInterval(redrawInterval, autoscaleInterval);
-
- String timeFormat = chartPreferenceNode.get(ChartPreferences.P_TIMEFORMAT, ChartPreferences.DEFAULT_TIMEFORMAT);
- TimeFormat tf = TimeFormat.valueOf( timeFormat );
- if (tf!=null) setTimeFormat( tf );
-
- Boolean drawSamples = chartPreferenceNode.getBoolean(ChartPreferences.P_DRAW_SAMPLES, ChartPreferences.DEFAULT_DRAW_SAMPLES);
- setDrawSamples(drawSamples);
-
- String valueFormat = chartPreferenceNode.get(ChartPreferences.P_VALUEFORMAT, ChartPreferences.DEFAULT_VALUEFORMAT);
- ValueFormat vf = ValueFormat.valueOf( valueFormat );
- if (vf!=null) setValueFormat( vf );
-
- String s = chartPreferenceNode.get(ChartPreferences.P_ITEMPLACEMENT, ChartPreferences.DEFAULT_ITEMPLACEMENT);
- ItemPlacement ip = ItemPlacement.valueOf(s);
- if (trendNode!=null) trendNode.itemPlacement = ip;
-
- String s1 = chartPreferenceNode.get(ChartPreferences.P_TEXTQUALITY, ChartPreferences.DEFAULT_TEXTQUALITY);
- String s2 = chartPreferenceNode.get(ChartPreferences.P_LINEQUALITY, ChartPreferences.DEFAULT_LINEQUALITY);
- LineQuality q1 = LineQuality.valueOf(s1);
- LineQuality q2 = LineQuality.valueOf(s2);
- if (trendNode!=null) trendNode.quality.textQuality = q1;
- if (trendNode!=null) trendNode.quality.lineQuality = q2;
-
- }
-
- private void setInterval(long redrawInterval, long autoscaleInterval) {
- redrawInterval = Math.max(1, redrawInterval);
- long pulse = Math.min(50, redrawInterval);
- pulse = Math.min(pulse, autoscaleInterval);
- IHintContext h = canvas.getCanvasContext().getDefaultHintContext();
- h.setHint(TimeParticipant.KEY_TIME_PULSE_INTERVAL, pulse);
- h.setHint(TrendParticipant.KEY_TREND_DRAW_INTERVAL, redrawInterval);
- h.setHint(TrendParticipant.KEY_TREND_AUTOSCALE_INTERVAL, autoscaleInterval);
- }
-
- private void setDrawSamples(boolean value) {
- trendNode.drawSamples = value;
- trendNode.layout();
- tp.setDirty();
- }
-
- private void setTimeFormat( TimeFormat tf ) {
- if (trendNode.timeFormat == tf) return;
- trendNode.timeFormat = tf;
- trendNode.layout();
- tp.setDirty();
- }
-
- private void setValueFormat( ValueFormat vf ) {
- if (trendNode.valueFormat == vf) return;
- trendNode.valueFormat = vf;
- trendNode.layout();
- tp.setDirty();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T> T getAdapter(Class<T> adapter) {
- if (adapter == INode.class) {
- ICanvasContext ctx = cvsCtx;
- if (ctx != null)
- return (T) ctx.getSceneGraph();
- }
- if (adapter == IPropertyPage.class)
- // TODO: pure e4 property page without sites
- return (T) new StandardPropertyPage(null, getPropertyPageContexts());
- if (adapter == ICanvasContext.class)
- return (T) cvsCtx;
- return null;
- }
-
- protected Set<String> getPropertyPageContexts() {
- try {
- return BrowseContext.getBrowseContextClosure(Simantics.getSession(), Collections.singleton(ROOT_PROPERTY_BROWSE_CONTEXT));
- } catch (DatabaseException e) {
- ExceptionUtils.logAndShowError("Failed to load modeled browse contexts for property page, see exception for details.", e);
- return Collections.singleton(ROOT_PROPERTY_BROWSE_CONTEXT);
- }
- }
-
- /**
- * Add from, end, (scale x) to argument array
- * @param fromEnd array of 2 or 3
- */
- public void getFromEnd(ChartLinkData data) {
- data.sender = this;
- TrendNode tn = trendNode;
- data.valueTipTime = tn.valueTipTime;
- HorizRuler hr = tn!=null ? tn.horizRuler : null;
- if ( hr != null ) {
- data.from = hr.from;
- data.end = hr.end;
- double len = hr.end-hr.from;
- double wid = tn.plot.getWidth();
- if ( wid==0.0 ) wid = 0.1;
- data.sx = len/wid;
- }
- }
-
- @SuppressWarnings("unused")
- private static boolean doubleEquals(double a, double b) {
- if (Double.isNaN(a) && Double.isNaN(b)) return true;
- return a==b;
- }
-
- protected void resetViewAfterDataChange() {
-
- CanvasUtils.sendCommand(cvsCtx, Commands.CANCEL);
- CanvasUtils.sendCommand(cvsCtx, Commands.AUTOSCALE);
-
- }
-
-// private Resource getInputResource() {
-// return resource;
-// }
-}