]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
refs #4953
authorjsimomaa <jsimomaa@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 17 Jun 2014 08:48:33 +0000 (08:48 +0000)
committerjsimomaa <jsimomaa@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 17 Jun 2014 08:48:33 +0000 (08:48 +0000)
Enabling File - Export / Import contributions for Sysdyn and adding new Model Export / Import wizards

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@29624 ac1ea38d-2e2b-0410-8846-a27921b304fc

15 files changed:
org.simantics.sysdyn.ui/plugin.xml
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/Preferences.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynExportModel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynImportModel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportWizard.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportWizard.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ExportWizardModel.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ImportWizardModel.java
org.simantics.sysdyn/META-INF/MANIFEST.MF
org.simantics.sysdyn/src/org/simantics/sysdyn/modelExport/ExportConstants.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/modelExport/SysdynModelExporter.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/ImportUtils.java

index e6c366275194717f3cb9b6985abb611483f57158..ee0afef0f083552eb0e557341bfd5ecafee3a695 100644 (file)
    </extension>\r
    <extension\r
          point="org.eclipse.ui.menus">\r
+      <menuContribution\r
+            locationURI="menu:sFile?after=import.ext">\r
+         <command commandId="org.eclipse.ui.file.import" />\r
+         <command commandId="org.eclipse.ui.file.export" />\r
+      </menuContribution>\r
       <menuContribution\r
             locationURI="toolbar:org.eclipse.ui.main.toolbar">\r
          <toolbar\r
          </activeWhen>\r
       </handler>      \r
    </extension>\r
+   \r
    <extension\r
          point="org.eclipse.ui.importWizards">\r
-      <wizard\r
+         \r
+      <category\r
+           id="org.simantics.sysdyn.import"\r
+           name="Sysdyn">\r
+      </category>\r
+<!--      <wizard\r
+            category="org.simantics.sysdyn.import"\r
             class="org.simantics.sysdyn.ui.wizards.models.ImportWizardModel"\r
             icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
             id="org.simantics.sysdyn.ui.wizards.modelImport"\r
-            name="Import Model">\r
-      </wizard>\r
+            name="Import Sysdyn Model">\r
+      </wizard> -->\r
       <wizard\r
+            category="org.simantics.sysdyn.import"\r
+            class="org.simantics.sysdyn.ui.wizards.model.SysdynModelImportWizard"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.import.model2"\r
+            name="Import Sysdyn Model">\r
+      </wizard>\r
+<!--      <wizard\r
+            category="org.simantics.sysdyn.import"\r
             class="org.simantics.sysdyn.ui.wizards.modules.ImportWizardModule"\r
             icon="platform:/plugin/com.famfamfam.silk/icons/bricks.png"\r
             id="org.simantics.sysdyn.ui.wizards.moduleImport"\r
-            name="Import Module">\r
+            name="Import Sysdyn Module">\r
       </wizard>\r
       <wizard\r
+            category="org.simantics.sysdyn.import"\r
             class="org.simantics.sysdyn.ui.wizards.functions.ImportWizardFunction"\r
             icon="platform:/plugin/com.famfamfam.silk/icons/brick.png"\r
             id="org.simantics.sysdyn.ui.wizards.functionImport"\r
-            name="Import Function Library">\r
+            name="Import Sysdyn Function Library">\r
       </wizard>\r
       <wizard\r
+            category="org.simantics.sysdyn.import"\r
             class="org.simantics.sysdyn.ui.wizards.mdl.ImportWizardMdl"\r
             icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
             id="org.simantics.sysdyn.ui.wizards.mdlImport"\r
             name="Import Vensim Model (.mdl)">\r
-      </wizard>\r
+      </wizard> -->\r
    </extension>\r
+   \r
    <extension\r
          point="org.eclipse.ui.exportWizards">\r
-      <wizard\r
+         \r
+      <category\r
+           id="org.simantics.sysdyn.export"\r
+           name="Sysdyn">\r
+      </category>\r
+<!--     <wizard\r
+            category="org.simantics.sysdyn.export"\r
             class="org.simantics.sysdyn.ui.wizards.models.ExportWizardModel"\r
             icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
-            id="org.simantics.sysdyn.ui.wizard1"\r
-            name="Export Model">\r
+            id="org.simantics.sysdyn.export.model"\r
+            name="Export Sysdyn Model">\r
+      </wizard> -->\r
+        <wizard\r
+            category="org.simantics.sysdyn.export"\r
+            class="org.simantics.sysdyn.ui.wizards.model.SysdynModelExportWizard"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.export.model2"\r
+            name="Export Sysdyn Model">\r
       </wizard>\r
-      <wizard\r
+<!--      <wizard\r
+            category="org.simantics.sysdyn.export"\r
             class="org.simantics.sysdyn.ui.wizards.modules.ExportWizardModule"\r
             icon="platform:/plugin/com.famfamfam.silk/icons/bricks.png"\r
-            id="org.simantics.sysdyn.ui.wizard2"\r
-            name="Export Module">\r
-      </wizard>\r
+            id="org.simantics.sysdyn.export.module"\r
+            name="Export Sysdyn Module">\r
+      </wizard> \r
       <wizard\r
+            category="org.simantics.sysdyn.export"\r
             class="org.simantics.sysdyn.ui.wizards.functions.ExportWizardFunction"\r
             icon="platform:/plugin/com.famfamfam.silk/icons/brick.png"\r
-            id="org.simantics.sysdyn.ui.wizard3"\r
-            name="Export Function Library">\r
-      </wizard>\r
+            id="org.simantics.sysdyn.export.function"\r
+            name="Export Sysdyn Function Library">\r
+      </wizard> -->\r
    </extension>\r
+   \r
    <extension\r
          point="org.eclipse.core.expressions.propertyTesters">\r
       <propertyTester\r
index 01af5b2ea54f8be6575456ca1de6511f7d171028..78e893d2d2bea1800fcaa6e9b33c600a7d81f99b 100644 (file)
 package org.simantics.sysdyn.ui.handlers.exports;\r
 \r
 import java.io.File;\r
-import java.util.HashMap;\r
+import java.lang.reflect.InvocationTargetException;\r
 \r
 import org.eclipse.core.commands.AbstractHandler;\r
 import org.eclipse.core.commands.ExecutionEvent;\r
 import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
 import org.eclipse.core.runtime.Platform;\r
 import org.eclipse.jface.action.IStatusLineManager;\r
 import org.eclipse.jface.viewers.ISelection;\r
@@ -29,17 +30,12 @@ import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;\r
 import org.simantics.db.WriteGraph;\r
 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
-import org.simantics.db.common.request.ReadRequest;\r
 import org.simantics.db.common.request.WriteRequest;\r
 import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;\r
-import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
-import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
 import org.simantics.db.request.Read;\r
-import org.simantics.graph.db.TransferableGraphSource;\r
-import org.simantics.graph.db.TransferableGraphs;\r
 import org.simantics.layer0.Layer0;\r
 import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.modelExport.SysdynModelExporter;\r
 import org.simantics.sysdyn.ui.Activator;\r
 import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
 import org.simantics.ui.SimanticsUI;\r
@@ -101,7 +97,6 @@ public class ExportModelHandler extends AbstractHandler {
                                setStatus("Saved model \"" + modelName + "\" to " + fileName);\r
                \r
                } catch (DatabaseException e) {\r
-                       // TODO Auto-generated catch block\r
                        e.printStackTrace();\r
                }\r
        }\r
@@ -112,36 +107,42 @@ public class ExportModelHandler extends AbstractHandler {
         * @param fileName Full name of the file.\r
         */\r
        protected void createFile(final Resource model, final String fileName) {\r
-               \r
-               // Asynchronously create the file using transferable graph\r
-               SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+               File exportLocation = new File(fileName);\r
+               try {\r
+            SysdynModelExporter.exportModel(new NullProgressMonitor(), model, exportLocation, "", false);\r
+        } catch (InvocationTargetException e1) {\r
+            ExceptionUtils.logAndShowError("Model Export Failed", "Sysdyn model export failed, see exception for details", e1);\r
+        }\r
 \r
-                   @Override\r
-                   public void run(ReadGraph graph) throws DatabaseException {\r
-                       HashMap<Resource, ExtentStatus> map = new HashMap<Resource, ExtentStatus>();\r
-                       \r
-                       Resource relation = graph.getPossibleResource("http://www.simantics.org/Documentation-1.1/createdBy");\r
-                       if(relation != null) {\r
-                           Resource createdBy = graph.getPossibleObject(model, relation);\r
-                           if(createdBy != null)\r
-                               map.put(createdBy, ExtentStatus.EXCLUDED);\r
-                       }\r
-                       \r
-                       TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model);\r
-                       conf.preStatus.putAll(map);\r
-                       \r
-                       TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));\r
-                       try {\r
-                           TransferableGraphs.writeTransferableGraph(graph, "sysdynModel", 1, s,new File(fileName));\r
-                       } catch (Exception e) {\r
-                           ExceptionUtils.logAndShowError("Model Export Failed", "Sysdyn model export failed, see exception for details", e);\r
-                           \r
-                           File modelFile = new File(fileName);\r
-                           if (modelFile.exists())\r
-                               modelFile.delete();\r
-                       }\r
-                       }\r
-               });\r
+//             // Asynchronously create the file using transferable graph\r
+//             SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+//\r
+//                 @Override\r
+//                 public void run(ReadGraph graph) throws DatabaseException {\r
+//                     HashMap<Resource, ExtentStatus> map = new HashMap<Resource, ExtentStatus>();\r
+//                     \r
+//                     Resource relation = graph.getPossibleResource("http://www.simantics.org/Documentation-1.1/createdBy");\r
+//                     if(relation != null) {\r
+//                         Resource createdBy = graph.getPossibleObject(model, relation);\r
+//                         if(createdBy != null)\r
+//                             map.put(createdBy, ExtentStatus.EXCLUDED);\r
+//                     }\r
+//                     \r
+//                     TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model);\r
+//                     conf.preStatus.putAll(map);\r
+//                     \r
+//                     TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));\r
+//                     try {\r
+//                         TransferableGraphs.writeTransferableGraph(graph, "sysdynModel", 1, s,new File(fileName));\r
+//                     } catch (Exception e) {\r
+//                         ExceptionUtils.logAndShowError("Model Export Failed", "Sysdyn model export failed, see exception for details", e);\r
+//                         \r
+//                         File modelFile = new File(fileName);\r
+//                         if (modelFile.exists())\r
+//                             modelFile.delete();\r
+//                     }\r
+//                     }\r
+//             });\r
        }\r
        \r
        /**\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/Preferences.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/Preferences.java
new file mode 100644 (file)
index 0000000..f75c970
--- /dev/null
@@ -0,0 +1,55 @@
+package org.simantics.sysdyn.ui.wizards;\r
+\r
+import java.util.Deque;\r
+import java.util.Iterator;\r
+import java.util.LinkedList;\r
+import java.util.Set;\r
+import java.util.TreeSet;\r
+\r
+import org.eclipse.ui.IMemento;\r
+import org.simantics.utils.ui.workbench.StringMemento;\r
+\r
+public final class Preferences {\r
+\r
+    public static final String  RECENT_MODEL_IMPORT_LOCATIONS = "RECENT_MODEL_IMPORT_LOCATIONS";\r
+    public static final String  RECENT_MODEL_EXPORT_LOCATIONS = "RECENT_MODEL_EXPORT_LOCATIONS";\r
+    public static final String  MODEL_EXPORT_OVERWRITE = "MODEL_EXPORT_OVERWRITE";\r
+\r
+    private static final String TAG_PATH                = "path";\r
+    private static final String ATTR_NAME               = "name";\r
+\r
+    public static Deque<String> decodePaths(String recentPathsPref) {\r
+        Deque<String> result = new LinkedList<String>();\r
+        try {\r
+            StringMemento sm = new StringMemento(recentPathsPref);\r
+            for (IMemento m : sm.getChildren(TAG_PATH)) {\r
+                String name = m.getString(ATTR_NAME);\r
+                if (name != null && !name.isEmpty())\r
+                    result.add(name);\r
+            }\r
+        } catch (IllegalArgumentException e) {\r
+        }\r
+        return result;\r
+    }\r
+\r
+    public static String encodePaths(Deque<String> recentPaths) {\r
+        StringMemento sm = new StringMemento();\r
+        for (String path : recentPaths) {\r
+            IMemento m = sm.createChild(TAG_PATH);\r
+            m.putString(ATTR_NAME, path);\r
+        }\r
+        return sm.toString();\r
+    }\r
+\r
+    public static <T> void removeDuplicates(Iterable<String> iter) {\r
+        // Remove duplicates\r
+        Set<String> dups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);\r
+        for (Iterator<String> it = iter.iterator(); it.hasNext();) {\r
+            String path = it.next();\r
+            if (!dups.add(path)) {\r
+                it.remove();\r
+            }\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynExportModel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynExportModel.java
new file mode 100644 (file)
index 0000000..593bec5
--- /dev/null
@@ -0,0 +1,100 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+\r
+import org.simantics.db.common.NamedResource;\r
+\r
+public class SysdynExportModel {\r
+    \r
+    private Object              selection;\r
+    private File                exportLocation;\r
+    private String              description;\r
+    private boolean             overwrite;\r
+    private NamedResource       model;\r
+    private boolean             dependencies;\r
+    \r
+    public SysdynExportModel(Object selection, boolean overwrite) {\r
+        this.selection = selection;\r
+        this.description = "";\r
+        this.overwrite = overwrite;\r
+    }\r
+\r
+    /**\r
+     * @return the overwrite\r
+     */\r
+    public boolean getOverwrite() {\r
+        return overwrite;\r
+    }\r
+\r
+    /**\r
+     * @param overwrite the overwrite to set\r
+     */\r
+    public void setOverwrite(boolean overwrite) {\r
+        this.overwrite = overwrite;\r
+    }\r
+\r
+    /**\r
+     * @return the selection\r
+     */\r
+    public Object getSelection() {\r
+        return selection;\r
+    }\r
+\r
+    /**\r
+     * @param selection the selection to set\r
+     */\r
+    public void setSelection(Object selection) {\r
+        this.selection = selection;\r
+    }\r
+\r
+    /**\r
+     * @return the description\r
+     */\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /**\r
+     * @param description the description to set\r
+     */\r
+    public void setDescription(String description) {\r
+        this.description = description;\r
+    }\r
+\r
+    /**\r
+     * @return the exportLocation\r
+     */\r
+    public File getExportLocation() {\r
+        return exportLocation;\r
+    }\r
+\r
+    /**\r
+     * @param exportLocation the exportLocation to set\r
+     */\r
+    public void setExportLocation(File exportLocation) {\r
+        this.exportLocation = exportLocation;\r
+    }\r
+\r
+    public void setModel(NamedResource model) {\r
+        this.model = model;\r
+    }\r
+    \r
+    public NamedResource getModel() {\r
+        return this.model;\r
+    }\r
+\r
+    /**\r
+     * @return the dependencies\r
+     */\r
+    public boolean getDependencies() {\r
+        return dependencies;\r
+    }\r
+\r
+    /**\r
+     * @param dependencies the dependencies to set\r
+     */\r
+    public void setDependencies(boolean dependencies) {\r
+        this.dependencies = dependencies;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynImportModel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynImportModel.java
new file mode 100644 (file)
index 0000000..b6e8ee9
--- /dev/null
@@ -0,0 +1,58 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+import java.util.Deque;\r
+\r
+public class SysdynImportModel {\r
+\r
+    private Object          selection;\r
+    private Deque<String>   recentLocations;\r
+    private File            importLocation;\r
+\r
+    public SysdynImportModel(Deque<String> recentImportPaths) {\r
+        this.recentLocations = recentImportPaths;\r
+    }\r
+\r
+    /**\r
+     * @return the selection\r
+     */\r
+    public Object getSelection() {\r
+        return selection;\r
+    }\r
+\r
+    /**\r
+     * @param selection the selection to set\r
+     */\r
+    public void setSelection(Object selection) {\r
+        this.selection = selection;\r
+    }\r
+\r
+    /**\r
+     * @return the recentLocations\r
+     */\r
+    public Deque<String> getRecentLocations() {\r
+        return recentLocations;\r
+    }\r
+\r
+    /**\r
+     * @param recentLocations the recentLocations to set\r
+     */\r
+    public void setRecentLocations(Deque<String> recentLocations) {\r
+        this.recentLocations = recentLocations;\r
+    }\r
+\r
+    /**\r
+     * @return the importLocation\r
+     */\r
+    public File getImportLocation() {\r
+        return importLocation;\r
+    }\r
+\r
+    /**\r
+     * @param importLocation the importLocation to set\r
+     */\r
+    public void setImportLocation(File importLocation) {\r
+        this.importLocation = importLocation;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportPage.java
new file mode 100644 (file)
index 0000000..27b196d
--- /dev/null
@@ -0,0 +1,257 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CCombo;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.NamedResource;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.modelExport.ExportConstants;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class SysdynModelExportPage extends WizardPage {\r
+\r
+    private SysdynExportModel           exportModel;\r
+    private CCombo                      exportLocation;\r
+    private CCombo                      model;\r
+    //private Composite                   draft;\r
+    private Text                        description;\r
+    private Button                      overwrite;\r
+    private List<NamedResource>         models;\r
+    private Button                      dependencies;\r
+    private Button                      browseFileButton;\r
+    \r
+    protected SysdynModelExportPage(SysdynExportModel exportModel) {\r
+        super("Export Sysdyn Model", "Define Export location", null);\r
+        this.exportModel = exportModel;\r
+    }\r
+\r
+    @Override\r
+    public void createControl(Composite parent) {\r
+        Composite container = new Composite(parent, SWT.NONE);\r
+        GridLayout layout = new GridLayout();\r
+        layout.horizontalSpacing = 20;\r
+        layout.verticalSpacing = 10;\r
+        layout.numColumns = 3;\r
+        container.setLayout(layout);\r
+        \r
+//        draft = new Composite(container, SWT.NONE);\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(draft);\r
+//        draft.setBackground(draft.getDisplay().getSystemColor(SWT.COLOR_RED));\r
+//        GridLayoutFactory.swtDefaults().spacing(5, 5).applyTo(draft);\r
+//        \r
+//        Composite draft2 = new Composite(draft, SWT.NONE);\r
+//        GridLayoutFactory.swtDefaults().applyTo(draft2);\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(draft2);\r
+//        new Label(draft2, SWT.NONE).setText("The model contains unpublished dependencies. The model can only be saved with draft status.");\r
+//        \r
+        new Label(container, SWT.NONE).setText("Exported model:");\r
+        model = new CCombo(container, SWT.BORDER);\r
+        model.setEditable(false);\r
+        model.setText("");\r
+        model.setToolTipText("Selects the model to export a state from.");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(model);\r
+        model.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                \r
+                for (NamedResource nr : models) {\r
+                    if (model.getText().equals(nr.getName())) {\r
+                            exportModel.setModel(nr);\r
+                            break;\r
+                    }\r
+                }\r
+                browseFileButton.setFocus();\r
+                validatePage();\r
+            }\r
+        });\r
+        \r
+        new Label(container, SWT.NONE).setText("&Target file:");\r
+        exportLocation = new CCombo(container, SWT.BORDER);\r
+        exportLocation.setText("");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(exportLocation);\r
+        exportLocation.addModifyListener(new ModifyListener() {\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                validatePage();\r
+            }\r
+        });\r
+        browseFileButton = new Button(container, SWT.PUSH);\r
+        browseFileButton.setText("Brows&e...");\r
+        browseFileButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
+        browseFileButton.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);\r
+                dialog.setText("Choose Export Target File");\r
+                String loc = exportLocation.getText();\r
+                //if (exportModel.model != null)\r
+                 //   dialog.setFileName(exportModel.model.get().getName());\r
+                dialog.setFilterPath(loc);\r
+                dialog.setFilterExtensions(new String[] { "*" + ExportConstants.MODEL_FILE_EXTENSION });\r
+                dialog.setFilterNames(new String[] { "Sysdyn Model (*" + ExportConstants.MODEL_FILE_EXTENSION + ")" });\r
+                dialog.setOverwrite(false);\r
+                String file = dialog.open();\r
+                if (file == null)\r
+                    return;\r
+                exportLocation.setText(file);\r
+                validatePage();\r
+            }\r
+        });\r
+        \r
+        new Label(container, SWT.NONE).setText("Notes:");\r
+\r
+        description = new Text(container, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 150).grab(true, true).span(3, 1).applyTo(description);\r
+        description.addModifyListener(new ModifyListener() {\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                exportModel.setDescription(description.getText());\r
+            }\r
+        });\r
+        \r
+        Label horizRule = new Label(container, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 0).grab(true, false).span(3, 1).applyTo(horizRule);\r
+\r
+        overwrite = new Button(container, SWT.CHECK);\r
+        overwrite.setText("&Overwrite existing files without warning");\r
+        overwrite.setSelection(exportModel.getOverwrite());\r
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(overwrite);\r
+        overwrite.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                validatePage();\r
+            }\r
+        });\r
+        \r
+        dependencies = new Button(container, SWT.CHECK);\r
+        dependencies.setText("&Include Shared Libraries in exported file");\r
+        dependencies.setSelection(exportModel.getDependencies());\r
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(dependencies);\r
+        dependencies.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                validatePage();\r
+            }\r
+        });\r
+        \r
+        try {\r
+            initializeData();\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        \r
+        setControl(container);\r
+        browseFileButton.setFocus();\r
+        validatePage();\r
+    }\r
+\r
+    private void initializeData() throws DatabaseException {\r
+        final Resource selection = ResourceAdaptionUtils.toSingleResource(exportModel.getSelection());\r
+\r
+        models = getModels();\r
+        Collections.sort(models);\r
+        int i = 0;\r
+        for (NamedResource namedResource : models) {\r
+            model.add(namedResource.getName());\r
+            if (selection != null && selection.equals(namedResource.getResource())) {\r
+                model.select(i);\r
+                exportModel.setModel(namedResource);\r
+            } else {\r
+                model.select(0);\r
+                for (NamedResource nr : models) {\r
+                    if (model.getItem(0).equals(nr.getName()))\r
+                        exportModel.setModel(nr);\r
+                }\r
+                \r
+            }\r
+            i++;\r
+        }\r
+    }\r
+\r
+    private List<NamedResource> getModels() throws DatabaseException {\r
+        return Simantics.getSession().sync(new UniqueRead<List<NamedResource>>() {\r
+\r
+            @Override\r
+            public List<NamedResource> perform(ReadGraph graph) throws DatabaseException {\r
+                Layer0 L0 = Layer0.getInstance(graph);\r
+                SysdynResource SYSDYN = SysdynResource.getInstance(graph);\r
+                ArrayList<NamedResource> models = new ArrayList<NamedResource>();\r
+                Resource currentProject = Simantics.getProjectResource();\r
+                Collection<Resource> consistsOfs = graph.getObjects(currentProject, L0.ConsistsOf);\r
+                for (Resource resource : consistsOfs) {\r
+                    if (graph.isInstanceOf(resource, SYSDYN.SysdynModel)) {\r
+                        String modelName = graph.getRelatedValue2(resource, L0.HasName, Bindings.STRING);\r
+                        models.add(new NamedResource(modelName, resource));\r
+                    }\r
+                }\r
+                return models;\r
+            }\r
+        });\r
+    }\r
+\r
+    protected void validatePage() {\r
+        if (model.getItemCount() == 0){\r
+            setErrorMessage("There are no exportable Sysdyn models in your workspace.");\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        String exportLoc = exportLocation.getText();\r
+        if (exportLoc.isEmpty()) {\r
+            setMessage("Select target file.");\r
+            setErrorMessage(null);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        if (!exportLoc.endsWith(ExportConstants.MODEL_FILE_EXTENSION)) {\r
+            setErrorMessage("Wrong file extension! Correct is " + ExportConstants.MODEL_FILE_EXTENSION);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        File file = new File(exportLoc);\r
+        if (file.isDirectory()) {\r
+            setErrorMessage("The target must be a file, an existing directory was given.");\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        File parent = file.getParentFile();\r
+        if (parent == null || !parent.isDirectory()) {\r
+            setErrorMessage("The target directory does not exist.");\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        \r
+        exportModel.setExportLocation(file);\r
+        exportModel.setOverwrite(overwrite.getSelection());\r
+        exportModel.setDependencies(dependencies.getSelection());\r
+        exportModel.setDescription(description.getText());\r
+        \r
+        setErrorMessage(null);\r
+        setMessage("Export selected model.");\r
+        setPageComplete(true);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportWizard.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportWizard.java
new file mode 100644 (file)
index 0000000..baaea7f
--- /dev/null
@@ -0,0 +1,123 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.Deque;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.preferences.InstanceScope;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.operation.IRunnableWithProgress;\r
+import org.eclipse.jface.preference.IPersistentPreferenceStore;\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.ui.IExportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.preferences.ScopedPreferenceStore;\r
+import org.simantics.modeling.ui.utils.NoProjectPage;\r
+import org.simantics.sysdyn.modelExport.SysdynModelExporter;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.wizards.Preferences;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SysdynModelExportWizard extends Wizard implements IExportWizard {\r
+\r
+    private static final int MAX_RECENT_EXPORT_PATHS = 10;\r
+    \r
+    private SysdynExportModel   exportModel;\r
+    private Deque<String>       recentExportPaths;\r
+    private boolean             overwrite;\r
+    \r
+    public SysdynModelExportWizard() {\r
+        setWindowTitle("Export Sysdyn Model");\r
+        setNeedsProgressMonitor(true);\r
+    }\r
+\r
+    @Override\r
+    public void init(IWorkbench workbench, IStructuredSelection selection) {\r
+        readPreferences();\r
+        exportModel = new SysdynExportModel(selection.getFirstElement(), overwrite);\r
+    }\r
+    \r
+    @Override\r
+    public void addPages() {\r
+        super.addPages();\r
+        if (exportModel != null)\r
+            addPage(new SysdynModelExportPage(exportModel));\r
+        else\r
+            addPage(new NoProjectPage("Export Sysdyn Model"));\r
+    }\r
+\r
+    @Override\r
+    public boolean performFinish() {\r
+        try {\r
+            recentExportPaths.addFirst(exportModel.getExportLocation().getAbsolutePath());\r
+            Preferences.removeDuplicates(recentExportPaths);\r
+            if (recentExportPaths.size() > MAX_RECENT_EXPORT_PATHS)\r
+                recentExportPaths.pollLast();\r
+\r
+            writePreferences();\r
+        } catch (IOException e) {\r
+            ErrorLogger.defaultLogError("Failed to write preferences", e);\r
+        }\r
+\r
+        final File output = exportModel.getExportLocation();\r
+        if (output.exists()) {\r
+            if (!exportModel.getOverwrite()) {\r
+                boolean ok = MessageDialog.openConfirm(getShell(), "Overwrite", "A file by the name " + output.getAbsolutePath() + " already exists.\n\nDo you want to overwrite?");\r
+                if (!ok) {\r
+                    return false;\r
+                }\r
+            }\r
+            if (!output.delete()) {\r
+                MessageDialog.openError(getShell(), "Delete Problem", "Could not overwrite previously existing file " + output);\r
+                return false;\r
+            }\r
+        }\r
+        try {\r
+            getContainer().run(true, true, new IRunnableWithProgress() {\r
+                @Override\r
+                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\r
+                    SysdynModelExporter.exportModel(monitor, exportModel.getModel().getResource(), exportModel.getExportLocation(), exportModel.getDescription(), exportModel.getDependencies());\r
+                }\r
+            });\r
+        } catch (InvocationTargetException e) {\r
+            Throwable t = e.getTargetException();\r
+            WizardPage cp = (WizardPage) getContainer().getCurrentPage();\r
+            if (t instanceof IOException) {\r
+                ErrorLogger.defaultLogError("An I/O problem occurred while exporting the model. See exception for details.", t);\r
+                cp.setErrorMessage("An I/O problem occurred while exporting the model.\nMessage: " + t.getMessage());\r
+            } else {\r
+                ErrorLogger.defaultLogError("Unexpected exception while exporting the model. See exception for details.", t);\r
+                cp.setErrorMessage("Unexpected exception while exporting the model. See error log for details.\nMessage: " + t.getMessage());\r
+            }\r
+            return false;\r
+        } catch (InterruptedException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+            return false;\r
+        }\r
+\r
+        return true;\r
+    }\r
+\r
+    private void readPreferences() {\r
+        \r
+        IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
+        String recentPathsPref = store.getString(Preferences.RECENT_MODEL_EXPORT_LOCATIONS);\r
+        recentExportPaths = Preferences.decodePaths(recentPathsPref);\r
+        overwrite = store.getBoolean(Preferences.MODEL_EXPORT_OVERWRITE);\r
+    }\r
+    \r
+    private void writePreferences() throws IOException {\r
+        \r
+        IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
+        store.putValue(Preferences.RECENT_MODEL_EXPORT_LOCATIONS, Preferences.encodePaths(recentExportPaths));\r
+        store.setValue(Preferences.MODEL_EXPORT_OVERWRITE, exportModel.getOverwrite());\r
+        if (store.needsSaving())\r
+            store.save();\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportPage.java
new file mode 100644 (file)
index 0000000..3ab66cd
--- /dev/null
@@ -0,0 +1,219 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.concurrent.atomic.AtomicReference;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CCombo;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.container.DataContainer;\r
+import org.simantics.databoard.container.DataContainers;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.modelExport.ExportConstants;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+\r
+public class SysdynModelImportPage extends WizardPage {\r
+\r
+    private SysdynImportModel       importModel;\r
+    private Text                    importTarget;\r
+    private CCombo                  importLocation;\r
+    private Label                   creation;\r
+    //private Label                   version;\r
+    private Text                    description;\r
+    private Text                    status;\r
+\r
+    protected SysdynModelImportPage(SysdynImportModel importModel) {\r
+        super("Import Sysdyn Model", "Define import location", null);\r
+        this.importModel = importModel;\r
+    }\r
+\r
+    @Override\r
+    public void createControl(Composite parent) {\r
+        Composite container = new Composite(parent, SWT.NONE);\r
+        GridLayoutFactory.swtDefaults().spacing(20, 10).numColumns(3).applyTo(container);\r
+\r
+//        draft = new Composite(container, SWT.NONE);\r
+//        draft.setBackground(draft.getDisplay().getSystemColor(SWT.COLOR_RED));\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(draft);\r
+//        GridLayoutFactory.swtDefaults().numColumns(0).margins(0, 0).applyTo(draft);\r
+//        \r
+//        Composite draft2 = new Composite(draft, SWT.NONE);\r
+//        GridLayoutFactory.swtDefaults().applyTo(draft2);\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(draft2);\r
+//        new Label(draft2, SWT.NONE).setText("This model draft was exported with unpublished dependencies.");\r
+        \r
+        new Label(container, SWT.NONE).setText("Import target:");\r
+        importTarget = new Text(container, SWT.BORDER);\r
+        importTarget.setEditable(false);\r
+        importTarget.setText("");\r
+        importTarget.setToolTipText("Shows the target of the import.");\r
+        importTarget.setEnabled(false);\r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(importTarget);\r
+\r
+        new Label(container, SWT.NONE).setText("&Model file:");\r
+        importLocation = new CCombo(container, SWT.BORDER);\r
+        importLocation.setText("");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(importLocation);\r
+        importLocation.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                validatePage();\r
+            }\r
+        });\r
+        Button browseFileButton = new Button(container, SWT.PUSH);\r
+        browseFileButton.setText("Br&owse...");\r
+        browseFileButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
+        browseFileButton.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);\r
+                dialog.setText("Choose Model to Import");\r
+                File lastFile = new File(importLocation.getText());\r
+                dialog.setFilterPath(lastFile.getParent());\r
+                dialog.setFilterExtensions(new String[] { "*.sysdyn" });\r
+                dialog.setFilterNames(new String[] { "Sysdyn Model (*.sysdyn)" });\r
+                String file = dialog.open();\r
+                if (file == null)\r
+                    return;\r
+                importLocation.setText(file);\r
+                //setDump(false, false);\r
+                validatePage();\r
+            }\r
+        });\r
+\r
+        Label horizRule = new Label(container, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 0).grab(true, false).span(3, 1).applyTo(horizRule);\r
+\r
+        creation = new Label(container, SWT.NONE);\r
+        creation.setText("");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(creation);\r
+//        version = new Label(container, SWT.NONE);\r
+//        version.setText("");\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(version);\r
+\r
+        Label notes = new Label(container, SWT.NONE);\r
+        notes.setText("Notes:");\r
+        GridDataFactory.fillDefaults().grab(false, false).span(3, 1).applyTo(notes);\r
+\r
+        description = new Text(container, SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.BORDER | SWT.FLAT);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 150).grab(true, true).span(3, 1).applyTo(description);\r
+\r
+        status = new Text(container, SWT.MULTI | SWT.READ_ONLY);\r
+        status.setText("");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(status);\r
+\r
+        Label horizRule2 = new Label(container, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 0).grab(true, false).span(3, 1).applyTo(horizRule2);\r
+        \r
+        try {\r
+            initializeData();\r
+        } catch (DatabaseException e) {\r
+            ErrorLogger.defaultLogError(e);\r
+        }\r
+        \r
+        setControl(container);\r
+        validatePage();\r
+    }\r
+\r
+    private void initializeData() throws DatabaseException {\r
+        final AtomicReference<String> projectName = new AtomicReference<String>();\r
+\r
+        Simantics.getSession().syncRequest(new ReadRequest() {\r
+            @Override\r
+            public void run(ReadGraph graph) throws DatabaseException {\r
+                projectName.set( NameUtils.getSafeName(graph, Simantics.getProjectResource()) );\r
+            }\r
+        });\r
+\r
+        importTarget.setText(projectName.get());\r
+\r
+        for (String path : importModel.getRecentLocations()) {\r
+            importLocation.add(path);\r
+        }\r
+        if (importLocation.getItemCount() > 0)\r
+            importLocation.select(0);\r
+        \r
+    }\r
+\r
+    protected void validatePage() {\r
+        String importLoc = importLocation.getText();\r
+        if (importLoc.isEmpty()) {\r
+            setMessage("Select file to import.");\r
+            setErrorMessage(null);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        File file = new File(importLoc);\r
+        if (!file.exists() || !file.isFile()) {\r
+            setErrorMessage("Selected file is invalid.");\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        \r
+        try {\r
+            importModel.setImportLocation(file);\r
+            \r
+            DataContainer container = DataContainers.readHeader(file);\r
+            \r
+            Variant dateVariant = container.metadata.get("date");\r
+            String dateText = dateVariant != null ? dateVariant.getValue().toString() : "Unknown date";\r
+            \r
+            Variant authorVariant = container.metadata.get("author");\r
+            String authorText = authorVariant != null ? authorVariant.getValue().toString() : "Unknown author";\r
+            \r
+            Variant descriptionVariant = container.metadata.get("description");\r
+            String descriptionText = descriptionVariant != null ? descriptionVariant.getValue().toString() : "";\r
+            \r
+            String creationText = "Created by " + authorText + " on " + dateText; \r
+            \r
+            creation.setText(creationText);\r
+            description.setText(descriptionText);\r
+            \r
+            \r
+            String statusText = "This model can be imported.";\r
+            if (container.version == ExportConstants.CURRENT_MODEL_EXPORT_VERSION) {\r
+//            } else if(container.version >= ExportConstants.SMALLEST_MIGRATED_MODEL_EXPORT_VERSION) {\r
+//                statusText = "This model can be migrated.";\r
+            } else {\r
+                status.setText("This model cannot be imported.");\r
+                setErrorMessage("This model cannot be imported");\r
+                setPageComplete(false);\r
+                return;\r
+            }\r
+            status.setText(statusText);\r
+            creation.getParent().layout();\r
+            \r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+            creation.setText("");\r
+//            version.setText("");\r
+            description.setText("");\r
+            status.setText("This model cannot be imported.");\r
+            setErrorMessage("Could not read header information from " + file.getAbsolutePath());\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        setErrorMessage(null);\r
+        setMessage("Import " + file.getName() + "");\r
+        setPageComplete(true);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportWizard.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportWizard.java
new file mode 100644 (file)
index 0000000..fad9cf9
--- /dev/null
@@ -0,0 +1,130 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.IOException;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.Deque;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.OperationCanceledException;\r
+import org.eclipse.core.runtime.preferences.InstanceScope;\r
+import org.eclipse.jface.operation.IRunnableWithProgress;\r
+import org.eclipse.jface.preference.IPersistentPreferenceStore;\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.preferences.ScopedPreferenceStore;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.graph.db.MissingDependencyException;\r
+import org.simantics.modeling.ui.utils.NoProjectPage;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.sysdyn.ui.wizards.Preferences;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SysdynModelImportWizard extends Wizard implements IImportWizard {\r
+\r
+    private static final int MAX_RECENT_IMPORT_PATHS = 10;\r
+    \r
+    private SysdynImportModel importModel;\r
+\r
+    public SysdynModelImportWizard() {\r
+        setWindowTitle("Import Sysdyn Model");\r
+        setNeedsProgressMonitor(true);\r
+    }\r
+    \r
+    @Override\r
+    public void init(IWorkbench workbench, IStructuredSelection selection) {\r
+        readPreferences(selection);\r
+        \r
+\r
+    }\r
+    \r
+    @Override\r
+    public void addPages() {\r
+        super.addPages();\r
+        if (importModel != null)\r
+            addPage(new SysdynModelImportPage(importModel));\r
+        else\r
+            addPage(new NoProjectPage("Import Sysdyn Model"));\r
+    }\r
+\r
+    @Override\r
+    public boolean performFinish() {\r
+        try {\r
+            importModel.getRecentLocations().addFirst(importModel.getImportLocation().getAbsolutePath());\r
+            Preferences.removeDuplicates(importModel.getRecentLocations());\r
+            if (importModel.getRecentLocations().size() > MAX_RECENT_IMPORT_PATHS)\r
+                importModel.getRecentLocations().pollLast();\r
+\r
+            writePreferences();\r
+        } catch (IOException e) {\r
+            ErrorLogger.defaultLogError("Failed to write preferences", e);\r
+        }\r
+        \r
+        try {\r
+            getContainer().run(true, true, new IRunnableWithProgress() {\r
+                @Override\r
+                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\r
+                    try {\r
+                        ImportUtilsUI.importModelFile(importModel.getImportLocation().getAbsolutePath(), monitor);\r
+                        //SysdynModelImporter.importModel(monitor, importModel.getImportLocation());\r
+                    } catch (Exception e) {\r
+                        throw new InvocationTargetException(e);\r
+                    } finally {\r
+                        monitor.done();\r
+                    }\r
+                }\r
+            });\r
+        } catch (InvocationTargetException e) {\r
+            Throwable t = e.getTargetException();\r
+            if (t instanceof OperationCanceledException)\r
+                return false;\r
+\r
+            WizardPage cp = (WizardPage) getContainer().getCurrentPage();\r
+            ErrorLogger.defaultLogError(t);\r
+            if (t instanceof IOException) {\r
+                cp.setErrorMessage("An I/O problem occurred while importing Sysdyn model.\n\nMessage: " + e.getMessage());\r
+            } else if (t instanceof MissingDependencyException) {\r
+                cp.setErrorMessage("The import target project is missing required dependencies from database.");\r
+                ExceptionUtils.logAndShowError(t.getMessage(), t);\r
+            } else {\r
+                cp.setErrorMessage("An unknown problem occurred while importing Sysdyn model.\n\nMessage: " + e.getMessage());\r
+            }\r
+            return false;\r
+        } catch (InterruptedException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+    \r
+    private void readPreferences(IStructuredSelection selection) {\r
+        IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
+\r
+        String recentPathsPref = store.getString(Preferences.RECENT_MODEL_IMPORT_LOCATIONS);\r
+        Deque<String> recentImportPaths = Preferences.decodePaths(recentPathsPref);\r
+\r
+        ISessionContext ctx = Simantics.getSessionContext();\r
+        if (ctx == null)\r
+            return;\r
+//        IProject project = ctx.getHint(ProjectKeys.KEY_PROJECT);\r
+//        if (project == null)\r
+//            return;\r
+//        \r
+        importModel = new SysdynImportModel(recentImportPaths);\r
+        //importModel.project = project;\r
+        importModel.setSelection(selection.getFirstElement());\r
+    }\r
+\r
+    private void writePreferences() throws IOException {\r
+        IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
+        store.putValue(Preferences.RECENT_MODEL_IMPORT_LOCATIONS, Preferences.encodePaths(importModel.getRecentLocations()));\r
+        if (store.needsSaving())\r
+            store.save();\r
+    }\r
+}\r
index ac82056117dc2fcbba50d3cdeed3811b9cf5ff26..5288762d8d5b899e4eb6425c9169170224472979 100644 (file)
@@ -8,6 +8,7 @@ import org.eclipse.ui.IWorkbench;
 import org.simantics.db.Resource;\r
 import org.simantics.utils.ui.AdaptionUtils;\r
 \r
+@Deprecated\r
 public class ExportWizardModel extends Wizard implements IImportWizard {\r
        \r
        private WizardModelsExportPage mainPage;\r
index e743d75055341aa373a72d52a990a2a4cfca8dcb..c1a87261af9f017db03d581f28c49ec5cfac5ca1 100644 (file)
@@ -5,7 +5,7 @@ import org.eclipse.jface.wizard.Wizard;
 import org.eclipse.ui.IImportWizard;\r
 import org.eclipse.ui.IWorkbench;\r
 \r
-\r
+@Deprecated\r
 public class ImportWizardModel extends Wizard implements IImportWizard {\r
        \r
        private WizardModelsImportPage mainPage;\r
index af0bfe79d727d02fea766b2e11d71338db37e336..886074f727cd706c01f152204aad26b8c22fe94f 100644 (file)
@@ -40,6 +40,7 @@ Export-Package: org.simantics.sysdyn,
  org.simantics.sysdyn.elementaryCycles,
  org.simantics.sysdyn.expressionParser,
  org.simantics.sysdyn.manager,
+ org.simantics.sysdyn.modelExport,
  org.simantics.sysdyn.modelImport,
  org.simantics.sysdyn.modelImport.model,
  org.simantics.sysdyn.modelParser,
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelExport/ExportConstants.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelExport/ExportConstants.java
new file mode 100644 (file)
index 0000000..19695ff
--- /dev/null
@@ -0,0 +1,10 @@
+package org.simantics.sysdyn.modelExport;\r
+\r
+public class ExportConstants {\r
+\r
+    public static final String MODEL_FILE_EXTENSION = ".sysdyn";\r
+    public static final String CURRENT_MODEL_EXPORT_FORMAT = ".sysdyn";\r
+    public static final int CURRENT_MODEL_EXPORT_VERSION = 1;\r
+    //public static final int SMALLEST_MIGRATED_MODEL_EXPORT_VERSION = 0;\r
+\r
+}\r
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelExport/SysdynModelExporter.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelExport/SysdynModelExporter.java
new file mode 100644 (file)
index 0000000..333a654
--- /dev/null
@@ -0,0 +1,133 @@
+package org.simantics.sysdyn.modelExport;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+import java.io.File;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.text.DateFormat;\r
+import java.util.Date;\r
+import java.util.LinkedList;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.TreeMap;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.SubMonitor;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.CopyHandler;\r
+import org.simantics.db.layer0.util.ClipboardUtils;\r
+import org.simantics.db.layer0.util.ModelDependenciesBean;\r
+import org.simantics.db.layer0.util.ModelDependency;\r
+import org.simantics.db.layer0.util.ModelTransferableGraphSource;\r
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
+import org.simantics.db.layer0.util.SimanticsClipboard.Representation;\r
+import org.simantics.db.layer0.util.SimanticsClipboardImpl;\r
+import org.simantics.db.layer0.util.SimanticsKeys;\r
+import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
+import org.simantics.graph.db.TransferableGraphs;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+\r
+public class SysdynModelExporter {\r
+\r
+    private SysdynModelExporter() {\r
+    }\r
+    \r
+    \r
+    public static void exportModel(IProgressMonitor monitor, final Resource model, File exportLocation, String description, boolean dependencies) throws InvocationTargetException {\r
+        try {\r
+            final SubMonitor mon = SubMonitor.convert(monitor, 100);\r
+            mon.beginTask("Exporting Sysdyn Model...", 100);\r
+            final Map<String, Variant> tgExtensions = new THashMap<String, Variant>();\r
+            Session session = Simantics.getSession();\r
+            if (dependencies) {\r
+                session.syncRequest(new ReadRequest() {\r
+                    \r
+                    @Override\r
+                    public void run(ReadGraph graph) throws DatabaseException {\r
+                        mon.setTaskName("Scanning model dependencies..");\r
+                        mon.worked(10);\r
+                        LinkedList<ModelDependency> modelDependencies = new LinkedList<ModelDependency>();\r
+                        scanDependencies(graph, model, modelDependencies);\r
+                        if (!modelDependencies.isEmpty())\r
+                            tgExtensions.put(ModelDependenciesBean.EXTENSION_KEY, new Variant(ModelDependenciesBean.BINDING, new ModelDependenciesBean(modelDependencies.toArray(new ModelDependency[modelDependencies.size()]))));\r
+                    }\r
+\r
+                    private void scanDependencies(ReadGraph graph, Resource resource, LinkedList<ModelDependency> modelDependencies) throws DatabaseException {\r
+                        Layer0 L0 = Layer0.getInstance(graph);\r
+                        ModelingResources MOD = ModelingResources.getInstance(graph);\r
+                        for(Resource library : graph.syncRequest(new ObjectsWithType(resource, L0.IsLinkedTo, MOD.SharedOntology))) {\r
+                            String uri = graph.getPossibleURI(library);\r
+                            if(uri == null) continue;\r
+                            CopyHandler ch = graph.adapt(library, CopyHandler.class);\r
+                            SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();\r
+                            ch.copyToClipboard(graph, clipboard);\r
+                            for (Set<Representation> object : clipboard.getContents()) {\r
+                                TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);\r
+                                if(tg != null) modelDependencies.addFirst(new ModelDependency(uri, tg));\r
+                            }\r
+                            scanDependencies(graph, library, modelDependencies);\r
+                        }\r
+                    }\r
+                });\r
+            }\r
+            \r
+            mon.setTaskName("Creating transferable graph source...");\r
+            mon.worked(10);\r
+            ModelTransferableGraphSource source = session.sync(new UniqueRead<ModelTransferableGraphSource>() {\r
+                @Override\r
+                public ModelTransferableGraphSource perform(ReadGraph graph) throws DatabaseException {\r
+                    mon.worked(10);\r
+                    TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model);\r
+                    mon.worked(10);\r
+                    if (!tgExtensions.isEmpty())\r
+                        conf.baseExtensions.putAll(tgExtensions);\r
+                    mon.worked(10);\r
+                    return new ModelTransferableGraphSourceRequest(conf).perform(graph);\r
+                }\r
+            });\r
+            \r
+            mon.worked(10);\r
+            mon.setTaskName("Writing metadata...");\r
+            TreeMap<String,Variant> metadata = getModelExportMetadata(description);\r
+            mon.worked(10);\r
+            mon.setTaskName("Writing transferable graph...");\r
+            \r
+            try {\r
+                TransferableGraphs.writeTransferableGraph(session, \r
+                        ExportConstants.CURRENT_MODEL_EXPORT_FORMAT, ExportConstants.CURRENT_MODEL_EXPORT_VERSION, metadata, source, exportLocation);\r
+                mon.worked(20);\r
+                source.closeStreams();\r
+            } catch (Exception e) {\r
+                throw new InvocationTargetException(e);\r
+            }\r
+\r
+            for(File f : source.getFiles())\r
+                f.delete();\r
+            \r
+            mon.worked(10);\r
+            mon.setTaskName("Done!");\r
+        } catch (DatabaseException e) {\r
+            throw new InvocationTargetException(e);\r
+        }\r
+    }\r
+\r
+\r
+    private static TreeMap<String, Variant> getModelExportMetadata(String description) {\r
+        TreeMap<String,Variant> metadata = new TreeMap<String,Variant>();\r
+        metadata.put("date", Variant.ofInstance(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date())));\r
+        metadata.put("author", Variant.ofInstance(System.getProperty("user.name", "")));\r
+        metadata.put("description", Variant.ofInstance(description));\r
+        \r
+        return metadata;\r
+    }\r
+}\r
index 405fc79f906db4e4804b5f00292d073449d969e1..7523baeff6de50e561d408eb961ea4840bed347d 100644 (file)
@@ -27,6 +27,8 @@ import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;\r
 import org.eclipse.core.runtime.SubMonitor;\r
 import org.simantics.Simantics;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
 import org.simantics.databoard.container.DataContainers;\r
 import org.simantics.databoard.container.DataFormatException;\r
 import org.simantics.databoard.container.FormatHandler;\r
@@ -35,6 +37,7 @@ import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;\r
 import org.simantics.db.Session;\r
 import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.primitiverequest.PossibleResource;\r
 import org.simantics.db.common.request.ObjectsWithType;\r
 import org.simantics.db.common.request.PossibleObjectWithType;\r
 import org.simantics.db.common.request.WriteRequest;\r
@@ -47,6 +50,8 @@ import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
 import org.simantics.db.layer0.migration.MigrationState;\r
 import org.simantics.db.layer0.migration.MigrationStateKeys;\r
 import org.simantics.db.layer0.migration.MigrationUtils;\r
+import org.simantics.db.layer0.util.ModelDependenciesBean;\r
+import org.simantics.db.layer0.util.ModelDependency;\r
 import org.simantics.db.layer0.util.RemoverUtil;\r
 import org.simantics.db.request.Read;\r
 import org.simantics.diagram.stubs.DiagramResource;\r
@@ -143,14 +148,27 @@ public class ImportUtils {
         if(project == null) return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import model: project not found", null);\r
 \r
         beginTask(monitor, "Import model", 10);\r
-\r
+        File importFile = new File(path);\r
         MigrationState state = MigrationUtils.newState();\r
         state.setProperty(MigrationStateKeys.BASE_URI, SysdynResource.URIs.Migration);\r
+        state.setProperty(MigrationStateKeys.MODEL_FILE, importFile);\r
         state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, Boolean.FALSE);\r
 \r
+        Session session = Simantics.getSession();\r
+        \r
+        final ModelDependenciesBean dependenciesBean = getModelDependenciesBean(state);\r
+        if(dependenciesBean != null) {\r
+            for(ModelDependency dependency : dependenciesBean.dependencies) {\r
+                Resource existing = session.sync(new PossibleResource(dependency.uri));\r
+                if(existing == null) {\r
+                    MigrationUtils.importSharedOntology(session, dependency.tg);\r
+                }\r
+            }\r
+        }\r
+        \r
         Resource result = null;\r
         try {\r
-            result = MigrationUtils.importMigrated(monitor, Simantics.getSession(), new File(path), state, new DefaultPasteImportAdvisor(project), project);\r
+            result = MigrationUtils.importMigrated(monitor, session, importFile, state, new DefaultPasteImportAdvisor(project), project);\r
         } catch (Exception e1) {\r
             e1.printStackTrace();\r
             throw e1;\r
@@ -233,7 +251,6 @@ public class ImportUtils {
                          */\r
 //                        BatchValidations.runAll(null, mod);\r
 \r
-                        final Session session = Simantics.getSession();\r
                         final Collection<BatchIssueSource> validations = session.sync( new AllBatchIssueSources(ModelRoot) );\r
                         SubMonitor progress = null;\r
                         if(monitor != null)\r
@@ -265,6 +282,20 @@ public class ImportUtils {
         }\r
     }\r
 \r
+    private static ModelDependenciesBean getModelDependenciesBean(MigrationState state) throws DatabaseException {\r
+        Map<String,Variant> extensions = state.getProperty(MigrationStateKeys.TG_EXTENSIONS);\r
+        final Variant variant = extensions.get(ModelDependenciesBean.EXTENSION_KEY);\r
+        if (variant != null) {\r
+            try {\r
+                return (ModelDependenciesBean) variant.getValue(ModelDependenciesBean.BINDING);\r
+            } catch (AdaptException e) {\r
+                e.printStackTrace();\r
+                //Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not get model dependencies bean.", e));\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
     protected static void addSCLMain(WriteGraph graph, Resource modelRoot) throws DatabaseException {\r
         Layer0 L0 = Layer0.getInstance(graph);\r
         \r