]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.charts/src/org/simantics/charts/ui/AddVariableToChartAction.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.charts / src / org / simantics / charts / ui / AddVariableToChartAction.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.charts.ui;
13
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
17
18 import org.eclipse.jface.dialogs.Dialog;
19 import org.eclipse.swt.widgets.Display;
20 import org.eclipse.swt.widgets.Shell;
21 import org.eclipse.ui.PlatformUI;
22 import org.simantics.Simantics;
23 import org.simantics.charts.query.AddChartItem;
24 import org.simantics.charts.query.ChartAndSubscriptionItemData;
25 import org.simantics.charts.query.ChartItemDescriptor;
26 import org.simantics.charts.query.NextChartItemIndexQuery;
27 import org.simantics.databoard.Bindings;
28 import org.simantics.databoard.type.BooleanType;
29 import org.simantics.db.ReadGraph;
30 import org.simantics.db.Resource;
31 import org.simantics.db.common.request.ReadRequest;
32 import org.simantics.db.exception.DatabaseException;
33 import org.simantics.db.layer0.request.PossibleModel;
34 import org.simantics.db.layer0.variable.Variable;
35 import org.simantics.db.layer0.variable.VariableReference;
36 import org.simantics.db.layer0.variable.Variables;
37 import org.simantics.layer0.Layer0;
38 import org.simantics.modeling.subscription.NewSubscription;
39 import org.simantics.modeling.subscription.NewSubscriptionItem;
40 import org.simantics.modeling.subscription.SubscriptionsQuery;
41 import org.simantics.modeling.subscription.SubscriptionsQuery.SubscriptionsResult;
42 import org.simantics.trend.configuration.TrendItem.Renderer;
43 import org.simantics.utils.ui.dialogs.ShowError;
44
45 public class AddVariableToChartAction implements Runnable {
46
47         Resource chart;
48         Resource subscription;
49         Resource model;
50         
51         String chartName;
52         String subscriptionName;
53         SubscriptionsResult subscriptions;
54         List<VariableReference> refs;
55         List<String> variableReferences; // String references
56         
57         public AddVariableToChartAction( Resource chart, Resource subscription, List<VariableReference> refs ) {
58                 this.refs = refs;
59                 this.chart = chart;
60                 this.subscription = subscription;
61         }
62         
63         /**
64          * Reads necessary data from session.
65          * 
66          * @throws DatabaseException
67          */
68         public AddVariableToChartAction init() throws DatabaseException 
69         {
70         Simantics.getSession().sync( new ReadRequest() {
71                         @Override
72                         public void run(ReadGraph g) throws DatabaseException {
73                                 init(g);
74                         }
75                 } );
76         return this;
77         }
78
79         /**
80          * Reads necessary data from session.
81          * 
82          * @throws DatabaseException
83          */
84         public AddVariableToChartAction init( ReadGraph g ) throws DatabaseException 
85         {
86         Layer0 L0 = Layer0.getInstance(g);
87         if(chart != null) {
88             chartName = g.getPossibleRelatedValue(chart, L0.HasName, Bindings.STRING);
89             model = g.syncRequest(new PossibleModel(chart));
90         }
91         else
92             model = g.syncRequest(new PossibleModel(subscription));
93         if (model == null) throw new DatabaseException("Model was not found");
94
95                 Variable configuration = Variables.getConfigurationContext(g, model);
96         
97                 subscriptions = g.sync( new SubscriptionsQuery(model) );
98                 if(subscription != null)
99                     subscriptionName = g.getPossibleRelatedValue(subscription, L0.HasLabel, Bindings.STRING);
100                 variableReferences = new ArrayList<String>();
101                 
102                 for (VariableReference var : refs) {
103                         if ( var.label == null ) {
104                                 variableReferences.add( var.getVariableId().toPossibleString(g, configuration) );
105                         }
106                 }
107
108                 return this;
109         }
110         
111         /**
112          * Opens dialog, if clicked OK, writes to graph async.
113          * 
114          * Remember to run this in SWT Thread.
115          */
116         public void runInSwt() {
117                                 
118             final Display display = Display.getCurrent();
119         final Shell shell = display.getActiveShell();
120
121         Simantics.getSession().markUndoPoint();
122
123                 for (int i=0; i<refs.size(); i++) {
124                         VariableReference var = refs.get(i);
125                         String varStrRef = variableReferences.get(i);
126
127                 try {
128                 ChartAndSubscriptionItemData data = new ChartAndSubscriptionItemData();
129                 data.index = chart != null ? Simantics.sync(new NextChartItemIndexQuery(chart)) : -1;
130                 data.mutableCollectionSettings = true;
131                 data.chartName = chartName;
132                 data.hasSubscriptionItem = true;
133                 data.subscriptions = subscriptions.toNames();
134                 data.subscription = subscriptionName;
135                 data.binaryMode = var.getDatatype() instanceof BooleanType;
136                 data.variableReference = varStrRef;             
137                                 ChartAndSubscriptionItemDialog d = new ChartAndSubscriptionItemDialog(shell, data, chart != null); 
138                                 
139                         if ( d.open() == Dialog.OK ) {
140                                 
141                                 // (New) Subscription
142                                 int j = subscriptions.names.indexOf( data.subscription );
143                                 Resource subscription;
144                                 if (j<0) {
145                                         // Create new subscription
146                                         NewSubscription ns = new NewSubscription(model, data.subscription);
147                                                 Simantics.getSession().sync( ns );
148                                         subscription = ns.subscription;
149                                 } else {
150                                         subscription = subscriptions.resources.get(j);
151                                 }                       
152                                 if ( subscription == null ) continue;
153                                 
154                                 
155                                 // New Subscription Item
156                                 NewSubscriptionItem ns = new NewSubscriptionItem(
157                                                 subscription,
158                                                 data.interval,
159                                                 data.deadband,
160                                                 data.gain,
161                                                 data.bias,
162                                                 data.unit,
163                                                 data.label,
164                                                 var.getVariableId(),
165                                                 var.getDatatype()
166                                                 );
167                                 
168                                 Simantics.getSession().sync( ns );
169                                 if (ns.subscriptionItem == null) continue;
170                                                         
171                                 // New Chart Item
172                                 if(chart != null) {
173                                 ChartItemDescriptor cid = new ChartItemDescriptor();
174                                 cid.drawMode = data.drawmode;
175                                 cid.renderer = var.getDatatype() instanceof BooleanType ? Renderer.Binary : Renderer.Analog;
176                                 cid.scale = data.scale;
177                                 cid.min = data.min;
178                                 cid.max = data.max;
179                                 cid.subscriptionItem = ns.subscriptionItem;
180                                 cid.color = data.color;
181                                 cid.strokeWidth = data.strokeWidth;
182                                 AddChartItem ci = new AddChartItem(     chart, Collections.singletonList( cid ) );
183                                 Simantics.getSession().sync( ci );
184                                 }
185                         }
186                         } catch (DatabaseException e) {
187                                 ShowError.showError(e.getClass().getName(), e.getLocalizedMessage(), e);
188                         }
189                         
190                 }
191                                 
192         }
193         
194         /**
195          * Executes run in SWT Thread
196          */
197         public void run() {
198             Display display = PlatformUI.getWorkbench().getDisplay();
199                 if ( display.getThread() == Thread.currentThread() ) {
200                         runInSwt();
201                 } else {
202                         display.asyncExec( new Runnable() {
203                                 @Override
204                                 public void run() {
205                                         runInSwt();
206                                 }} );
207                 }
208         }
209         
210 }
211