From: miettinen Date: Fri, 25 Oct 2013 06:25:53 +0000 (+0000) Subject: Export model and export model as... buttons to Sysdyn (refs #4487). X-Git-Tag: 1.8.1~223 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=23478ecdd6598109a162539a96003d6302504aab;p=simantics%2Fsysdyn.git Export model and export model as... buttons to Sysdyn (refs #4487). git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@28117 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.ontology/graph.tg b/org.simantics.sysdyn.ontology/graph.tg index 0ee27c2d..17eab9a3 100644 Binary files a/org.simantics.sysdyn.ontology/graph.tg and b/org.simantics.sysdyn.ontology/graph.tg differ diff --git a/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph b/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph index f180d4f1..fa30152a 100644 --- a/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph +++ b/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph @@ -47,6 +47,8 @@ SYSDYN.SysdynModel -- SYSDYN.SysdynModel.variableFilter --> L0.String -- SYSDYN.SysdynModel.fmuFile --> L0.ByteArray -- SYSDYN.SysdynModel.timeUnit --> L0.String -- SYSDYN.SysdynModel.lastExportFileName --> L0.String -- SYSDYN.SysdynModel.lastExportFilePath --> L0.String -- SYSDYN.SysdynModel.exeFile --> L0.ByteArray + name="System Dynamic Diagram Viewer"> + name="Modelica Code Viewer"> + name="System Dynamics"> + name="Playback Experiment"> + name="Game Experiment"> + name="Sensitivity Analysis Experiment"> + + + + + + + icon="platform:/plugin/com.famfamfam.silk/icons/table_save.png" + id="org.simantics.sysdyn.ui.save.button" + label="Save Results"> @@ -334,7 +348,7 @@ hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_play_blue.png" icon="platform:/plugin/com.famfamfam.silk/icons/control_play.png" id="org.simantics.sysdyn.ui.playback.button" - label="Start playback" + label="Start Playback" style="pulldown" tooltip="Start playback"> @@ -550,7 +564,7 @@ + name="Export To PNG"> + name="Export To SVG"> + name="Paste Special"> + name="Show In Charts"> + name="Show In Charts"> + name="Export Model"> + name="Import Model"> + + + + @@ -1655,6 +1677,7 @@ + - - + + + + @@ -1854,6 +1879,46 @@ class="org.simantics.sysdyn.ui.handlers.FindReplaceHandler" commandId="org.eclipse.ui.edit.findReplace"> + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2276,6 +2341,13 @@ properties="nodeClass" type="org.eclipse.jface.viewers.IStructuredSelection"> + + @@ -2286,12 +2358,12 @@ --> @@ -2369,7 +2441,7 @@ + label="System Dynamics Ontology Dependencies"> + name="Import Vensim Model (.mdl)"> a = AdaptionUtils.adaptToCollection(receiver, AbstractNode.class); + if (a.size() > 1) // Multiple selections. + return false; + if (a.size() == 1) + inputResource = (Resource)a.iterator().next().data; + } + if (inputResource == null) { + DiagramEditor editor = null; + IWorkbench workbench = PlatformUI.getWorkbench(); + IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); + // To ask for the active window doesn't work, so browse through all + // windows and when an active editor is found, use that + for (IWorkbenchWindow window : windows) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + try { + editor = (DiagramEditor)page.getActiveEditor(); + if (editor != null) + // Found one + break; + } catch (ClassCastException e) { + continue; + } + } + } + if (editor != null) { + if (editor instanceof DiagramEditor) { + inputResource = editor.getInputResource(); + } + } else { + return false; + } + } + final Resource resource = inputResource; + + Session session = SimanticsUI.peekSession(); + if (session == null) + return false; + + if (DatabaseJob.inProgress()) + return false; + + // Check if we can get the model of the resource. + try { + return session.syncRequest(new Read() { + @Override + public Boolean perform(ReadGraph g) throws DatabaseException { + if (g.sync(new PossibleModel(resource)) != null) { + return true; + } + return false; + } + }); + } catch (DatabaseException e) { + // Purposefully not logging these exceptions, there might be way too + // many even under normal circumstances. + // TODO: add debug tracing options controlling the printing of these exceptions + return false; + } + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java new file mode 100644 index 00000000..57a6cb42 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 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.sysdyn.ui.handlers.exports; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.db.Resource; + +/** + * Exports a selected model asking the location. + * Model determination is based on any resource of the model. + * + * @author Tuomas Miettinen + * + */ +public class ExportModelAsButtonHandler extends ExportModelButtonHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + final Resource model = determineModel(event); + if (model == null) + return null; + + String selected = getAbsolutePath(model, event, true); + + if (selected != null) + createFile(model, selected); + + return null; + } + +} + diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java new file mode 100644 index 00000000..bb6388ca --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2010 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.sysdyn.ui.handlers.exports; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.platform.PropertyPageView; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.db.request.Read; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Exports a selected model without asking the location. + * Model determination is based on any resource of the model. + * + * @author Tuomas Miettinen + * + */ +public class ExportModelButtonHandler extends ExportModelHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + final Resource model = determineModel(event); + if (model == null) + return null; + + String selected = getAbsolutePath(model, event, false); + + if (selected != null) + createFile(model, selected); + + return null; + } + + @Override + protected Resource determineModel(ExecutionEvent event) { + ISelection sel = HandlerUtil.getCurrentSelection(event); + if (sel == null) { + // No selection, this is true e.g. in PropertyPageView + IWorkbenchPart activePart = HandlerUtil.getActivePart(event); + // In such a case get the selection the PropertyPageView point to. + if (activePart instanceof PropertyPageView) + sel = ((PropertyPageView)activePart).getLastSelection(); + } + + // Get the Resource of the selection + Resource inputResource = ResourceAdaptionUtils.toSingleResource(sel); + if (inputResource == null) { + // Coner case for when export is called when some folder in model browser is selected. + if (sel instanceof IStructuredSelection) { + IStructuredSelection iss = (IStructuredSelection) sel; + if (iss.size() == 1) { + Object element = iss.getFirstElement(); + AbstractNode a = AdaptionUtils.adaptToSingle(element, AbstractNode.class); + if (a != null) + inputResource = (Resource)a.data; + } + } + } + + // When the selection doesn't have a resource, use the currently active diagram. + if (inputResource == null) { + DiagramEditor editor = null; + IWorkbench workbench = PlatformUI.getWorkbench(); + IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); + // To ask for the active window doesn't work, so browse through all + // windows and when an active editor is found, use that + for (IWorkbenchWindow window : windows) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + try { + editor = (DiagramEditor)page.getActiveEditor(); + if (editor != null) + // Found one + break; + } catch (ClassCastException e) { + continue; + } + } + } + if (editor != null && editor instanceof DiagramEditor) { + inputResource = editor.getInputResource(); + } else { + return null; + } + } + + // Now that we finally have determined which Resource is selected, we just need + // to get the model of that Resource. + Resource model; + final Resource resource = inputResource; + try { + model = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return graph.sync(new PossibleModel(resource)); + } + + }); + if(model == null) return null; + } catch (DatabaseException e1) { + e1.printStackTrace(); + return null; + } + return model; + } + +} + diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java index 8d2ec6d2..ee0efbb9 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java @@ -26,8 +26,10 @@ import org.eclipse.ui.handlers.HandlerUtil; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; import org.simantics.db.common.primitiverequest.PossibleRelatedValue; import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus; import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest; @@ -36,6 +38,7 @@ import org.simantics.db.request.Read; import org.simantics.graph.db.TransferableGraphSource; import org.simantics.graph.db.TransferableGraphs; import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.ui.Activator; import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; import org.simantics.ui.SimanticsUI; @@ -43,6 +46,7 @@ import org.simantics.ui.utils.ResourceAdaptionUtils; /** * Exports a selected model + * Model determination is based on the very Resource of the model. * * @author Teemu Lempinen * @author Tuomas Miettinen @@ -52,51 +56,26 @@ public class ExportModelHandler extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection sel = HandlerUtil.getCurrentSelection(event); - final Resource model = ResourceAdaptionUtils.toSingleResource(sel); - if(model == null) return null; - - // FIXME: Model browser doesn't change its selection even if the selected object is removed, - // so you can try to export a removed model - String name = null; - try { - name = SimanticsUI.getSession().syncRequest(new Read() { - @Override - public String perform(ReadGraph graph) throws DatabaseException { - if (!graph.hasStatement(model, Layer0.getInstance(graph).PartOf)) - return null; - Layer0 l0 = Layer0.getInstance(graph); - String name = graph.syncRequest(new PossibleRelatedValue(model, l0.HasName, Bindings.STRING )); - return name; - - } - - }); - } catch (DatabaseException e1) { - e1.printStackTrace(); - } - // Do not export if the resource has no name - if(name == null) return null; - - // Find a location (and name) for the exported library using FileDialog - Shell shell = HandlerUtil.getActiveShellChecked(event); - FileDialog fd = new FileDialog(shell, SWT.SAVE); - fd.setText("Export Model"); - fd.setFileName(name); - String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH); - if(path.isEmpty() || !(new File(path).exists())) - path = Platform.getLocation().toOSString(); - fd.setFilterPath(path); - String[] filterExt = {"*.tg"}; - fd.setFilterExtensions(filterExt); - fd.setOverwrite(true); - final String selected = fd.open(); - if(selected == null) return null; + final Resource model = determineModel(event); + if (model == null) + return null; + + String selected = getAbsolutePath(model, event, true); + + if (selected != null) + createFile(model, selected); - // Save location to preference store - Activator.getDefault().getPreferenceStore().setValue(ImportUtilsUI.IMPORTMODELTPATH, (new File(selected)).getParent()); + return null; + } + /** + * Create the export file. + * @param model Model which is exported. + * @param fileName Full name of the file. + */ + protected void createFile(final Resource model, final String fileName) { + // Asynchronously create the file using transferable graph SimanticsUI.getSession().asyncRequest(new ReadRequest() { @@ -116,14 +95,145 @@ public class ExportModelHandler extends AbstractHandler { TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf)); try { - TransferableGraphs.writeTransferableGraph(graph, "sysdynModel", 1, s,new File(selected)); + TransferableGraphs.writeTransferableGraph(graph, "sysdynModel", 1, s,new File(fileName)); } catch (Exception e) { e.printStackTrace(); } } }); - - return null; } + + /** + * Get the model Resource based on the event. + * @param event + * @return model Resource which the event refers to. + */ + protected Resource determineModel(ExecutionEvent event) { + // Just get the selected model. + ISelection sel = HandlerUtil.getCurrentSelection(event); + final Resource model = ResourceAdaptionUtils.toSingleResource(sel); + return model; + } + + /** + * Get the absolute save path for the export file and save it to the database. + * @param model Model Resource which is exported. + * @param event + * @param saveAs true if save as... functionality is used; otherwise save + * functionality is used. + * @return The full path name of the exported model. + * @throws ExecutionException + */ + protected String getAbsolutePath(final Resource model, ExecutionEvent event, boolean saveAs) throws ExecutionException { + + // Determine the default path. + String path = null; + try { + //If the model has been exported earlier, use that path. + path = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + if (!graph.hasStatement(model, Layer0.getInstance(graph).PartOf)) + return null; + SysdynResource SR = SysdynResource.getInstance(graph); + String path = graph.syncRequest(new PossibleRelatedValue(model, SR.SysdynModel_lastExportFilePath, Bindings.STRING )); + return path; + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + // If this is the initial save: + if (path == null) { + if (saveAs == false) { + // Save == Save as... when there has been no earlier save. + return getAbsolutePath(model, event, true); + } + // Use import default path. + path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH); + } + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + + // Determine the default name + // FIXME: Model browser doesn't change its selection even if the selected object is removed, + // so you can try to export a removed model + String name = null; + try { + name = SimanticsUI.getSession().syncRequest(new Read() { + @Override + public String perform(ReadGraph graph) throws DatabaseException { + if (!graph.hasStatement(model, Layer0.getInstance(graph).PartOf)) + return null; + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + // If the model has been exported earlier, use that name. + // When mere Save has progressed here, there is always be the name in the database. + String name = graph.syncRequest(new PossibleRelatedValue(model, SR.SysdynModel_lastExportFileName, Bindings.STRING )); + if (name == null) { + // If not, use the model name. + name = graph.syncRequest(new PossibleRelatedValue(model, l0.HasName, Bindings.STRING )); + } + return name; + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + // Do not export if the resource has no name + if(name == null) return null; + + final String selected; + String fullPath = null; + if (saveAs == true) { + // Find a location (and name) for the exported library using FileDialog + Shell shell = HandlerUtil.getActiveShellChecked(event); + FileDialog fd = new FileDialog(shell, SWT.SAVE); + fd.setText("Export Model"); + fd.setFileName(name); + + fd.setFilterPath(path); + String[] filterExt = {"*.tg"}; + fd.setFilterExtensions(filterExt); + fd.setOverwrite(true); + fullPath = fd.open(); + } + else { + // Save to the earlier location. + fullPath = path; + if (path.charAt(path.length() - 1) != '\\') + fullPath += "\\"; // Saving to C:\ would otherwise add excess backslashes. + fullPath += name; + } + selected = fullPath; + + if(selected == null) return null; + + // Save location to preference store + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + graph.deny(model, SR.SysdynModel_lastExportFilePath); + graph.deny(model, SR.SysdynModel_lastExportFileName); + graph.addLiteral(model, SR.SysdynModel_lastExportFilePath, SR.SysdynModel_lastExportFilePath_Inverse, l0.String, new File(selected).getParent(), Bindings.STRING); + graph.addLiteral(model, SR.SysdynModel_lastExportFileName, SR.SysdynModel_lastExportFilePath_Inverse, l0.String, new File(selected).getName(), Bindings.STRING); + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + return selected; + + } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java index 744e6316..3b516bbb 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java @@ -79,6 +79,8 @@ public class ResourceSelectionProcessor implements SelectionProcessor)selection) { Resource r = AdaptionUtils.adaptToSingle(o, Resource.class); + if (r == null) + continue; Resource component = backend.getPossibleObject(r, mr.ElementToComponent); if (component != null) { r = component;