1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.spreadsheet.graph;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Collection;
\r
16 import java.util.Collections;
\r
17 import java.util.List;
\r
18 import java.util.Map;
\r
19 import java.util.function.Consumer;
\r
21 import org.eclipse.e4.core.contexts.IEclipseContext;
\r
22 import org.eclipse.e4.ui.di.UISynchronize;
\r
23 import org.eclipse.jface.dialogs.Dialog;
\r
24 import org.eclipse.ui.PlatformUI;
\r
25 import org.simantics.Simantics;
\r
26 import org.simantics.databoard.Bindings;
\r
27 import org.simantics.databoard.binding.Binding;
\r
28 import org.simantics.databoard.binding.mutable.MutableVariant;
\r
29 import org.simantics.databoard.binding.mutable.Variant;
\r
30 import org.simantics.db.AsyncReadGraph;
\r
31 import org.simantics.db.ReadGraph;
\r
32 import org.simantics.db.RequestProcessor;
\r
33 import org.simantics.db.Resource;
\r
34 import org.simantics.db.WriteGraph;
\r
35 import org.simantics.db.common.procedure.adapter.AsyncListenerSupport;
\r
36 import org.simantics.db.common.procedure.adapter.ListenerSupport;
\r
37 import org.simantics.db.common.procedure.adapter.SyncListenerSupport;
\r
38 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
\r
39 import org.simantics.db.common.procedure.single.SingleSetSyncListenerDelegate;
\r
40 import org.simantics.db.common.request.ReadRequest;
\r
41 import org.simantics.db.common.request.ResourceRead;
\r
42 import org.simantics.db.common.request.UnaryRead;
\r
43 import org.simantics.db.common.request.UniqueRead;
\r
44 import org.simantics.db.common.request.WriteRequest;
\r
45 import org.simantics.db.common.request.WriteResultRequest;
\r
46 import org.simantics.db.common.session.SessionEventListenerAdapter;
\r
47 import org.simantics.db.exception.DatabaseException;
\r
48 import org.simantics.db.layer0.StandardRealm;
\r
49 import org.simantics.db.layer0.request.PossibleURIVariable;
\r
50 import org.simantics.db.layer0.request.VariableName;
\r
51 import org.simantics.db.layer0.request.VariableRead;
\r
52 import org.simantics.db.layer0.variable.ProxyVariables;
\r
53 import org.simantics.db.layer0.variable.Variable;
\r
54 import org.simantics.db.layer0.variable.Variables;
\r
55 import org.simantics.db.procedure.SyncListener;
\r
56 import org.simantics.db.request.Write;
\r
57 import org.simantics.db.service.SessionEventSupport;
\r
58 import org.simantics.layer0.Layer0;
\r
59 import org.simantics.spreadsheet.Adaptable;
\r
60 import org.simantics.spreadsheet.CellEditor;
\r
61 import org.simantics.spreadsheet.ClientModel;
\r
62 import org.simantics.spreadsheet.ClientModel.OperationMode;
\r
63 import org.simantics.spreadsheet.SheetCommands;
\r
64 import org.simantics.spreadsheet.common.logging.Logger;
\r
65 import org.simantics.spreadsheet.event.model.RemoveCellHandler;
\r
66 import org.simantics.spreadsheet.resource.SpreadsheetResource;
\r
67 import org.simantics.ui.selection.WorkbenchSelectionUtils;
\r
68 import org.simantics.utils.datastructures.Pair;
\r
69 import org.simantics.utils.strings.AlphanumComparator;
\r
70 import org.simantics.utils.threads.logger.ITask;
\r
71 import org.simantics.utils.threads.logger.ThreadLogger;
\r
73 import gnu.trove.map.hash.THashMap;
\r
74 import gnu.trove.map.hash.TObjectIntHashMap;
\r
76 class FilteredVariableProperties extends UnaryRead<Variable, Collection<Pair<String,Variable>>> {
\r
78 final static String CLASSIFICATION = SpreadsheetResource.URIs.Attribute;
\r
80 public FilteredVariableProperties(Variable variable) {
\r
85 public Collection<Pair<String,Variable>> perform(ReadGraph graph) throws DatabaseException {
\r
86 ArrayList<Pair<String,Variable>> result = new ArrayList<Pair<String,Variable>>();
\r
87 for(Variable var : parameter.getProperties(graph, CLASSIFICATION)) {
\r
88 String name = var.getName(graph);
\r
89 String uri = var.getURI(graph);
\r
90 result.add(Pair.make(name, var));
\r
91 Variable expression = var.getPossibleProperty(graph, "expression");
\r
92 if(expression != null)
\r
93 result.add(Pair.make(name + "#expression", expression));
\r
94 Variable editable = var.getPossibleProperty(graph, "editable");
\r
95 if(editable != null)
\r
96 result.add(Pair.make(name + "#editable", editable));
\r
103 public class GraphUI implements Adaptable, ListenerSupport, AsyncListenerSupport, SyncListenerSupport {
\r
105 final public static boolean DEBUG = false;
\r
107 final private RequestProcessor processor;
\r
109 private CellEditor<Write> cellEditor;
\r
111 private Variable run;
\r
112 private ClientModel client;
\r
114 private Map<String, PropertyListener> listenerCache = new THashMap<>();
\r
116 public GraphUI(RequestProcessor processor) {
\r
117 this.processor = processor;
\r
120 public void addCell(ReadGraph graph, Pair<String, Variable> child, final ClientModel client) throws DatabaseException {
\r
122 if(DEBUG) System.out.println("GraphUI adds cell " + child.second.getURI(graph));
\r
124 final String childName = child.second.getName(graph);
\r
125 Boolean immutable = child.second.getPossiblePropertyValue(graph, "immutable", Bindings.BOOLEAN);
\r
126 if(immutable != null && immutable) {
\r
127 Collection<Variable> properties = child.second.getProperties(graph, FilteredVariableProperties.CLASSIFICATION);
\r
128 addProperties(graph, properties, client, childName);
\r
130 PropertyListener listener = listenerCache.get(child.first);
\r
131 if (listener == null) {
\r
132 listener = propertyListener(client, childName);
\r
133 listenerCache.put(child.first, listener);
\r
135 graph.asyncRequest(new FilteredVariableProperties(child.second), listener);
\r
140 public void removeCell(ReadGraph graph, Pair<String, Variable> child, final ClientModel client) throws DatabaseException {
\r
142 if(DEBUG) System.out.println("GraphUI removed cell " + child.first);
\r
144 client.clear(child.first);
\r
145 PropertyListener listener = listenerCache.remove(child.first);
\r
146 if (listener != null)
\r
147 listener.dispose();
\r
151 public void loadCells(ReadGraph graph, Variable container, boolean immutable, final ClientModel client) throws DatabaseException {
\r
153 if(DEBUG) System.out.println("GraphUI loads cells from " + container.getURI(graph));
\r
156 for(Pair<String, Variable> cell : graph.syncRequest(new Cells(container), TransientCacheAsyncListener.<Collection<Pair<String, Variable>>>instance())) {
\r
157 addCell(graph, cell, client);
\r
160 graph.syncRequest(new Cells(container), new SingleSetSyncListenerDelegate<Pair<String, Variable>>(GraphUI.this) {
\r
163 public void add(ReadGraph graph, final Pair<String, Variable> child) throws DatabaseException {
\r
164 addCell(graph, child, client);
\r
168 public void remove(ReadGraph graph, final Pair<String, Variable> child) throws DatabaseException {
\r
169 removeCell(graph, child, client);
\r
176 private SessionEventListenerAdapter listener;
\r
178 private String currentSource;
\r
180 private boolean disposed;
\r
182 public Resource load(final Variable variable, final ClientModel client) throws DatabaseException {
\r
184 // for (PropertyListener listener : listenerCache.values())
\r
185 // listener.dispose();
\r
187 // listenerCache.clear();
\r
191 assert(variable != null);
\r
193 this.run = variable;
\r
194 this.client = client;
\r
196 SessionEventSupport support = processor.getService(SessionEventSupport.class);
\r
198 for (PropertyListener listener : listenerCache.values()) {
\r
199 listener.dispose();
\r
201 listenerCache.clear();
\r
203 if(listener != null)
\r
204 support.removeListener(listener);
\r
206 listener = new SessionEventListenerAdapter() {
\r
209 public void writeTransactionFinished() {
\r
215 support.addListener(listener);
\r
217 this.cellEditor = processor.sync(new VariableRead<CellEditor>(variable) {
\r
220 public CellEditor perform(ReadGraph graph) throws DatabaseException {
\r
221 SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);
\r
222 return variable.getPropertyValue(graph, SHEET.cellEditor);
\r
227 final ITask task = ThreadLogger.getInstance().begin("GraphUI.init");
\r
231 Map<String,Variable> sources = processor.syncRequest(new Sources(variable));
\r
233 List<String> sheetList = processor.syncRequest(new Sheets(variable));
\r
234 String currentSheet = processor.syncRequest(new VariableName(variable));
\r
236 Map<String, Resource> stateList = processor.syncRequest(new SpreadsheetStates(variable));
\r
238 if(currentSource == null) currentSource = "Sheet";
\r
240 ArrayList<String> sourceList = new ArrayList<String>(sources.keySet());
\r
242 Collections.sort(sourceList, AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);
\r
243 if(!sourceList.contains(currentSource)) sourceList.add(currentSource);
\r
245 client.setProperty(ClientModel.SOURCES, ClientModel.SOURCES_AVAILABLE, sourceList.toArray(new String[sourceList.size()]));
\r
246 client.setProperty(ClientModel.SOURCES, ClientModel.SOURCES_CURRENT, currentSource);
\r
248 client.setProperty(ClientModel.SHEETS, ClientModel.SHEETS_AVAILABLE, sheetList.toArray(new String[sheetList.size()]));
\r
249 client.setProperty(ClientModel.SHEETS, ClientModel.SHEETS_CURRENT, currentSheet);
\r
251 client.setProperty(ClientModel.STATES, ClientModel.STATES_AVAILABLE, stateList.keySet().toArray(new String[stateList.size()]));
\r
253 client.setProperty(ClientModel.CONTEXT, ClientModel.CONTEXT_CURRENT, variable);
\r
255 client.setProperty(ClientModel.MODE, ClientModel.MODE_CURRENT, OperationMode.OPERATION);
\r
257 String currentState = processor.syncRequest(new UniqueRead<String>() {
\r
260 public String perform(ReadGraph graph) throws DatabaseException {
\r
261 Resource book = variable.getParent(graph).getRepresents(graph);
\r
262 Resource ic = graph.getPossibleObject(book, SpreadsheetResource.getInstance(graph).Book_HasDefaultInitialCondition);
\r
265 return graph.getRelatedValue2(ic, Layer0.getInstance(graph).HasName, Bindings.STRING);
\r
269 client.setProperty(ClientModel.STATES, ClientModel.STATES_CURRENT, currentState);
\r
271 processor.syncRequest(new ReadRequest() {
\r
274 public void run(ReadGraph graph) throws DatabaseException {
\r
276 loadCells(graph, variable, false, client);
\r
278 graph.syncRequest(new Ranges(variable), new SingleSetSyncListenerDelegate<Variable>(GraphUI.this) {
\r
281 public void add(ReadGraph graph, final Variable range) throws DatabaseException {
\r
283 if(DEBUG) System.out.println("GraphUI adds range " + range.getURI(graph));
\r
285 Boolean immutable = range.getPossiblePropertyValue(graph, "immutable", Bindings.BOOLEAN);
\r
286 loadCells(graph, range, immutable != null && immutable, client);
\r
291 public void remove(ReadGraph graph, final Variable range) throws DatabaseException {
\r
298 graph.syncRequest(new SheetLines(variable), new SingleSetSyncListenerDelegate<Variable>(GraphUI.this) {
\r
301 public void add(ReadGraph graph, final Variable range) throws DatabaseException {
\r
303 if(DEBUG) System.out.println("GraphUI adds line " + range.getURI(graph));
\r
305 Boolean immutable = range.getPossiblePropertyValue(graph, "immutable", Bindings.BOOLEAN);
\r
306 loadCells(graph, range, immutable != null && immutable, client);
\r
311 public void remove(ReadGraph graph, final Variable range) throws DatabaseException {
\r
319 // public void remove(ReadGraph graph, Variable child) throws DatabaseException {
\r
321 // String location = locations.get(cellResource);
\r
322 // assert(location != null);
\r
324 // client.setProperty(location, "Label", null);
\r
325 // client.setProperty(location, "Expression", null);
\r
339 private static class PropertyListener extends SingleSetSyncListenerDelegate<Pair<String,Variable>> {
\r
341 private ClientModel client;
\r
342 private String childName;
\r
343 private boolean listenerDisposed;
\r
345 public PropertyListener(AsyncListenerSupport support, ClientModel client, String childName) {
\r
347 this.client = client;
\r
348 this.childName = childName;
\r
352 public void add(ReadGraph graph, final Pair<String,Variable> property) throws DatabaseException {
\r
355 System.out.println("GraphUI adds property " + property.second.getURI(graph));
\r
357 graph.asyncRequest(new CellValue(property.second), new SyncListener<Object>() {
\r
360 public void execute(ReadGraph graph, final Object value) throws DatabaseException {
\r
362 String propertyName = property.first;
\r
365 System.out.println("GraphUI detected content change(1) at " + childName + " - " + propertyName + " -> " + value);
\r
366 client.setProperty(childName, propertyName, value);
\r
371 public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {
\r
373 Logger.defaultLogError(throwable);
\r
375 String propertyName = property.first;
\r
376 if("content".equals(propertyName)) {
\r
377 if(throwable == null) throwable = new Exception();
\r
378 String message = throwable.getMessage();
\r
379 if(message == null) message = throwable.toString();
\r
380 client.setProperty(childName, propertyName, Variant.ofInstance(message));
\r
382 client.setProperty(childName, propertyName, null);
\r
388 public boolean isDisposed() {
\r
389 return listenerDisposed;
\r
395 public void dispose() {
\r
396 listenerDisposed = true;
\r
400 public String toString() {
\r
401 return super.toString() + ":" + childName;
\r
406 private PropertyListener propertyListener(final ClientModel client, final String childName) {
\r
407 return new PropertyListener(this, client, childName);
\r
410 private void addProperties(ReadGraph graph, final Collection<Variable> properties, final ClientModel client, final String childName) throws DatabaseException {
\r
412 for(Variable property : properties) {
\r
414 if(DEBUG) System.out.println("GraphUI adds immutable property " + property.getURI(graph));
\r
416 final String propertyName = property.getName(graph);
\r
418 Object value = property.getValue(graph);
\r
420 if(DEBUG) System.out.println("GraphUI detected change at " + childName + " - " + propertyName + " -> " + value);
\r
421 client.setProperty(childName, propertyName, value);
\r
423 String expression = property.getPossiblePropertyValue(graph, "expression", Bindings.STRING);
\r
424 if(expression != null) {
\r
425 if(DEBUG) System.out.println("GraphUI detected change at " + childName + " - " + (propertyName + "#expression") + " -> " + value);
\r
426 client.setProperty(childName, propertyName + "#expression", expression);
\r
429 Boolean editable = property.getPossiblePropertyValue(graph, "editable", Bindings.STRING);
\r
430 if(editable != null) {
\r
431 if(DEBUG) System.out.println("GraphUI detected change at " + childName + " - " + (propertyName + "#editable") + " -> " + value);
\r
432 client.setProperty(childName, propertyName + "#editable", editable);
\r
439 @SuppressWarnings("unchecked")
\r
441 public <T> T getAdapter(Class<T> clazz) {
\r
443 if(Variable.class == clazz) {
\r
447 } else if(RemoveCellHandler.class == clazz) {
\r
449 return (T) new RemoveCellHandler() {
\r
452 public void handle(final String location) {
\r
454 processor.asyncRequest(new ReadRequest() {
\r
457 public void run(ReadGraph graph) throws DatabaseException {
\r
459 Variable cellVariable = run.getPossibleChild(graph, location);
\r
460 if(cellVariable != null) {
\r
461 final Resource config = cellVariable.getPossiblePropertyValue(graph, "Represents");
\r
462 if(config != null) {
\r
464 graph.asyncRequest(new WriteRequest() {
\r
467 public void perform(WriteGraph graph) throws DatabaseException {
\r
469 Layer0 l0 = Layer0.getInstance(graph);
\r
470 // SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);
\r
471 graph.deny(config, l0.PartOf);
\r
472 // graph.deny(config, sr.RowOf);
\r
473 // graph.deny(config, sr.ColumnOf);
\r
490 } else if(CellEditor.class == clazz) {
\r
492 return (T)new CellEditor<Write>() {
\r
495 public <T> void edit(Transaction<Write> transaction, String location, String property, T value, Binding binding, Consumer<?> callback) {
\r
497 if (ClientModel.ITERATION_ENABLED.equals(location)) {
\r
498 Simantics.getSession().asyncRequest(new ReadRequest() {
\r
500 public void run(ReadGraph graph) throws DatabaseException {
\r
501 getBook(graph).setIterationEnabled((boolean)value);
\r
507 if (ClientModel.MODE.equals(location)) {
\r
508 if (ClientModel.MODE_CURRENT.equals(property)) {
\r
509 client.setProperty(location, property, value);
\r
515 if (ClientModel.CONTEXT.equals(location)) {
\r
516 if(ClientModel.CONTEXT_CURRENT.equals(property)) {
\r
517 if(value instanceof String) {
\r
519 Variable newContext = processor.syncRequest(new UnaryRead<String, Variable>((String)value) {
\r
522 public Variable perform(ReadGraph graph) throws DatabaseException {
\r
524 String sheetName = run.getName(graph);
\r
526 Variable book = Variables.getContext(graph, run);
\r
527 Resource bookResource = book.getRepresents(graph);
\r
529 Variable input = Variables.getVariable(graph, parameter);
\r
530 Variable proxy = ProxyVariables.makeProxyVariable(graph, Variables.getVariable(graph, bookResource), input);
\r
532 return proxy.getChild(graph, sheetName);
\r
534 // return variable.getParent(graph).getChild(graph, parameter);
\r
539 load(newContext, client);
\r
541 } catch (DatabaseException e) {
\r
542 Logger.defaultLogError(e);
\r
548 if(ClientModel.SHEETS.equals(location)) {
\r
549 if(ClientModel.SHEETS_CURRENT.equals(property)) {
\r
551 if(value instanceof String) {
\r
555 Variable newInput = processor.syncRequest(new UnaryRead<String, Variable>((String)value) {
\r
558 public Variable perform(ReadGraph graph) throws DatabaseException {
\r
559 return run.getParent(graph).getChild(graph, parameter);
\r
564 load(newInput, client);
\r
566 } catch (DatabaseException e) {
\r
567 Logger.defaultLogError(e);
\r
573 if(ClientModel.STATES.equals(location)) {
\r
574 if(ClientModel.STATES_CURRENT.equals(property)) {
\r
575 if(value instanceof String) {
\r
576 final String parameter = (String) value;
\r
579 String uri = processor.syncRequest(new WriteResultRequest<String>() {
\r
582 public String perform(WriteGraph graph) throws DatabaseException {
\r
584 Map<String, Resource> states = graph.syncRequest(new SpreadsheetStates(run));
\r
586 Resource state = null;
\r
587 for (Map.Entry<String, Resource> entry : states.entrySet()) {
\r
588 if (entry.getKey().equals(parameter)) {
\r
589 state = entry.getValue();
\r
593 if (state != null) {
\r
594 Variable context = Variables.getContext(graph, run);
\r
595 Resource bookResource = context.getRepresents(graph);
\r
596 SpreadsheetGraphUtils.setDefaultInitialConditionForBook(graph, bookResource, state);
\r
598 String contextURI = context.getURI(graph);
\r
600 String sessionName = context.getParent(graph).getURI(graph);
\r
601 SpreadsheetSessionManager.getInstance().removeRealm(sessionName);
\r
602 SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
\r
605 return run.getURI(graph);
\r
608 Variable newInput = processor.syncRequest(new PossibleURIVariable(uri));
\r
609 load(newInput, client);
\r
610 // fullSynchronize();
\r
612 } catch (DatabaseException e) {
\r
613 Logger.defaultLogError(e);
\r
619 if(ClientModel.SOURCES.equals(location)) {
\r
620 if(ClientModel.SOURCES_CURRENT.equals(property)) {
\r
622 Resource res = WorkbenchSelectionUtils.getPossibleResource(value);
\r
625 Variable newInput = processor.syncRequest(new ResourceRead<Variable>(res) {
\r
628 public Variable perform(ReadGraph graph) throws DatabaseException {
\r
629 Variable base = ProxyVariables.proxyVariableBase(graph, run);
\r
630 Variable in = Variables.getVariable(graph, resource);
\r
631 currentSource = in.getURI(graph);
\r
632 return ProxyVariables.makeProxyVariable(graph, base, in);
\r
637 load(newInput, client);
\r
641 } else if(value instanceof String) {
\r
643 Variable newInput = processor.syncRequest(new UnaryRead<String, Variable>((String)value) {
\r
646 public Variable perform(ReadGraph graph) throws DatabaseException {
\r
648 Variable base = ProxyVariables.proxyVariableBase(graph, run);
\r
649 Map<String,Variable> sources = graph.syncRequest(new Sources(base));
\r
651 Variable found = sources.get(parameter);
\r
652 if(found == null) return null;
\r
654 currentSource = parameter;
\r
656 return ProxyVariables.makeProxyVariable(graph, base, found);
\r
662 load(newInput, client);
\r
666 } catch (DatabaseException e) {
\r
667 Logger.defaultLogError(e);
\r
672 boolean needsCommit = false;
\r
673 if (transaction == null) {
\r
674 OperationMode mode = client.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
\r
675 transaction = startTransaction(mode);
\r
676 // if (mode.equals(OperationMode.OPERATION))
\r
677 transaction.setContext(run);
\r
678 needsCommit = true;
\r
680 final Transaction<Write> finalTransaction = transaction;
\r
681 cellEditor.edit(transaction, location, property, value, binding, new Consumer<Object>() {
\r
684 public void accept(Object param) {
\r
685 if (finalTransaction.needSynchronization() != null)
\r
686 synchronize(finalTransaction.needSynchronization());
\r
690 transaction.commit();
\r
694 public void edit(Transaction<Write> transaction, String location, Variant variant, Consumer<?> callback) {
\r
695 boolean needsCommit = false;
\r
696 if (transaction == null) {
\r
697 OperationMode mode = client.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
\r
698 transaction = startTransaction(mode);
\r
699 // if (mode.equals(OperationMode.OPERATION))
\r
700 transaction.setContext(run);
\r
701 needsCommit = true;
\r
703 final Transaction<Write> finalTransaction = transaction;
\r
704 cellEditor.edit(transaction, location, variant, new Consumer<Object>() {
\r
707 public void accept(Object param) {
\r
708 if (finalTransaction.needSynchronization() != null)
\r
709 synchronize(finalTransaction.needSynchronization());
\r
713 transaction.commit();
\r
717 public void copy(final Transaction<Write> transaction, String location, MutableVariant variant, Consumer<?> callback) {
\r
718 cellEditor.edit(transaction, location, variant, new Consumer<Object>() {
\r
721 public void accept(Object param) {
\r
722 if (transaction.needSynchronization() != null)
\r
723 synchronize(transaction.needSynchronization());
\r
729 public Transaction<Write> startTransaction(OperationMode mode) {
\r
730 return cellEditor.startTransaction(mode);
\r
735 } else if (SheetCommands.class == clazz ) {
\r
737 return (T) new SheetCommands() {
\r
740 public void saveState() {
\r
742 Simantics.getSession().asyncRequest(new ReadRequest() {
\r
745 public void run(ReadGraph graph) throws DatabaseException {
\r
746 IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
\r
748 Resource uiContextResource = run.getRepresents(graph);
\r
749 Resource bookResource = Variables.getContext(graph, run).getRepresents(graph);
\r
750 Layer0 L0 = Layer0.getInstance(graph);
\r
751 String uiContextName = graph.getRelatedValue2(uiContextResource, L0.HasName, Bindings.STRING);
\r
752 String bookName = graph.getRelatedValue2(bookResource, L0.HasName, Bindings.STRING);
\r
754 UISynchronize synchronizer = context.get(UISynchronize.class);
\r
755 synchronizer.asyncExec(() -> {
\r
756 Pair<String, Resource>[] pairs = new Pair[] {Pair.make(uiContextName, uiContextResource), Pair.make(bookName, bookResource) };
\r
757 SaveSpreadsheetStateDialog dialog = new SaveSpreadsheetStateDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getSite(), "Save Spreadsheet state", pairs);
\r
758 if (dialog.open() == Dialog.OK) {
\r
759 Object[] result = dialog.getSelection();
\r
760 if (result != null) {
\r
761 Pair<Resource, String> p = (Pair<Resource, String>) result[0];
\r
762 Simantics.getSession().asyncRequest(new WriteRequest() {
\r
765 public void perform(WriteGraph graph) throws DatabaseException {
\r
767 Variable parent = run.getParent(graph);
\r
768 Variable base = ProxyVariables.proxyVariableBase(graph, parent);
\r
769 SpreadsheetGraphUtils.saveInitialCondition(graph, parent, p.first, p.second);
\r
788 public void exception(Throwable t) {
\r
789 t.printStackTrace();
\r
793 public boolean isDisposed() {
\r
798 public void exception(AsyncReadGraph graph, Throwable t) {
\r
799 Logger.defaultLogError("Failed to read properties.", t);
\r
803 public void exception(ReadGraph graph, Throwable t) {
\r
804 Logger.defaultLogError("Failed to read properties.", t);
\r
807 public void dispose() {
\r
808 for (PropertyListener listener : listenerCache.values())
\r
809 listener.dispose();
\r
811 listenerCache.clear();
\r
812 SessionEventSupport support = processor.getService(SessionEventSupport.class);
\r
813 support.removeListener(listener);
\r
817 private void synchronize(List<Object> list) {
\r
818 Simantics.getSession().asyncRequest(new FullSynchronizeBook(run, list));
\r
821 public static class FullSynchronizeBook extends ReadRequest {
\r
823 private final Variable run;
\r
824 private final List<Object> location;
\r
826 public FullSynchronizeBook(Variable run, List<Object> cellLocation) {
\r
828 this.location = cellLocation;
\r
832 public void run(ReadGraph graph) throws DatabaseException {
\r
833 String uri = run.getURI(graph);
\r
834 String parentUri = run.getParent(graph).getURI(graph);
\r
835 System.err.println("Full sync for book " + parentUri);
\r
837 Resource sheetResource = run.getRepresents(graph);
\r
838 Variable sheetVariable = Variables.getVariable(graph, sheetResource);
\r
840 TObjectIntHashMap<Variable> changes = null;
\r
841 if (location != null) {
\r
842 changes = new TObjectIntHashMap<>(location.size());
\r
843 for (Object loc : location) {
\r
844 Variable var = (Variable) loc;
\r
845 changes.put(var, 1);
\r
848 SpreadsheetGraphUtils.partialSynchronization(graph, run.getParent(graph), changes);
\r
853 private SpreadsheetBook getBook(ReadGraph graph) throws DatabaseException {
\r
854 String sessionName = run.getParent(graph).getParent(graph).getURI(graph);
\r
855 StandardRealm<SheetNode, SpreadsheetBook> realm = SpreadsheetSessionManager.getInstance().getOrCreateRealm(graph, sessionName);
\r
856 SpreadsheetBook book = realm.getEngine();
\r