]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/g3d/wizard/ModelExportWizard.java
27214c930fb8300955b47f4c80345550a8ad668e
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / wizard / ModelExportWizard.java
1 package org.simantics.g3d.wizard;\r
2 \r
3 import java.io.File;\r
4 import java.io.IOException;\r
5 import java.lang.reflect.InvocationTargetException;\r
6 import java.util.Deque;\r
7 import java.util.Iterator;\r
8 import java.util.LinkedList;\r
9 import java.util.Set;\r
10 import java.util.TreeSet;\r
11 \r
12 import org.eclipse.jface.dialogs.MessageDialog;\r
13 import org.eclipse.jface.operation.IRunnableWithProgress;\r
14 import org.eclipse.jface.preference.IPersistentPreferenceStore;\r
15 import org.eclipse.jface.preference.IPreferenceStore;\r
16 import org.eclipse.jface.viewers.IStructuredSelection;\r
17 import org.eclipse.jface.wizard.Wizard;\r
18 import org.eclipse.jface.wizard.WizardPage;\r
19 import org.eclipse.ui.IExportWizard;\r
20 import org.eclipse.ui.IMemento;\r
21 import org.eclipse.ui.IWorkbench;\r
22 import org.simantics.db.management.ISessionContext;\r
23 import org.simantics.project.IProject;\r
24 import org.simantics.project.ProjectKeys;\r
25 import org.simantics.ui.SimanticsUI;\r
26 import org.simantics.utils.ui.ErrorLogger;\r
27 import org.simantics.utils.ui.ExceptionUtils;\r
28 import org.simantics.utils.ui.workbench.StringMemento;\r
29 \r
30 public abstract class ModelExportWizard<T extends IExportModel> extends Wizard implements IExportWizard {\r
31         \r
32         private static final int MAX_RECENT_EXPORT_PATHS = 10;\r
33         Deque<String>            recentExportPaths;\r
34     boolean                  overwrite;\r
35     \r
36     T exportModel;\r
37    \r
38     protected abstract  T createExportModel(Deque<String> recentExportPaths);\r
39     \r
40     protected abstract ModelExportWizardPage<T> createExportPage(T exportModel);\r
41     \r
42     protected abstract IPersistentPreferenceStore getPreferenceStore();\r
43     \r
44     protected abstract IRunnableWithProgress createExportRunnable(T exportModel);\r
45     \r
46     protected abstract String getExportLocationId();\r
47     protected abstract String getExportOverwriteId();\r
48     \r
49     @Override\r
50         public void init(IWorkbench workbench, IStructuredSelection selection) {\r
51                 readPreferences();\r
52 \r
53         ISessionContext ctx = SimanticsUI.getSessionContext();\r
54         if (ctx == null)\r
55             return;\r
56         IProject project = ctx.getHint(ProjectKeys.KEY_PROJECT);\r
57         if (project == null)\r
58             return;\r
59         \r
60         exportModel = createExportModel(recentExportPaths);\r
61         exportModel.setSelection(selection.getFirstElement());\r
62         exportModel.setOverwrite(overwrite);\r
63         }\r
64     \r
65     @Override\r
66         public void addPages() {\r
67                 super.addPages();\r
68                 if (exportModel != null) {\r
69                         addPage(createExportPage(exportModel));\r
70                 }\r
71         }\r
72     \r
73     \r
74     \r
75         @Override\r
76         public boolean performFinish() {\r
77         try {\r
78             recentExportPaths.addFirst(exportModel.getExportLocation().getAbsolutePath());\r
79             removeDuplicates(recentExportPaths);\r
80             if (recentExportPaths.size() > MAX_RECENT_EXPORT_PATHS)\r
81                 recentExportPaths.pollLast();\r
82 \r
83             writePreferences();\r
84         } catch (IOException e) {\r
85             ErrorLogger.defaultLogError("Failed to write preferences", e);\r
86         }\r
87         \r
88         if (exportModel.usesFile()) {\r
89 \r
90                 File outputFile = exportModel.getExportLocation();\r
91                 \r
92                 if (outputFile.exists()) {\r
93                         if (!outputFile.isFile()) {\r
94                                 MessageDialog.openError(getShell(), "File Problem", "Output target is not a file " + outputFile.getAbsolutePath());\r
95                         return false;\r
96                         }\r
97                         if (!exportModel.isOverwrite()) {\r
98                                 boolean ok = MessageDialog.openConfirm(getShell(), "Overwrite", "A file by the name " + outputFile.getAbsolutePath() + " contains files.\n\nDo you want to overwrite the files?");\r
99                                 if (!ok) {\r
100                                         return false;\r
101                                 }\r
102                                 if (!outputFile.delete()) {\r
103                                         MessageDialog.openError(getShell(), "Delete Problem", "Could not overwrite previously existing file " + outputFile.getAbsolutePath());\r
104                           return false;\r
105                                 }\r
106                         }\r
107                 } \r
108         } else {\r
109                 File outputFolder = exportModel.getExportLocation();\r
110             \r
111             if (outputFolder.exists()) {\r
112                 if (!outputFolder.isDirectory()) {\r
113                         MessageDialog.openError(getShell(), "Folder Problem", "Output target is not a folder " + outputFolder.getAbsolutePath());\r
114                     return false;\r
115                 }\r
116                 String files[] = outputFolder.list();\r
117                 if (files.length > 0) {\r
118                         if (!exportModel.isOverwrite()) {\r
119                                 boolean ok = MessageDialog.openConfirm(getShell(), "Overwrite", "A folder by the name " + outputFolder.getAbsolutePath() + " contains files.\n\nDo you want to overwrite the files?");\r
120                                 if (!ok) {\r
121                                         return false;\r
122                                 }\r
123                         }\r
124                 }\r
125 \r
126             } else {\r
127                 if (!outputFolder.mkdir()) {\r
128                         MessageDialog.openError(getShell(), "Folder Problem", "Could not create new folder " + outputFolder);\r
129                     return false;\r
130                 }\r
131             }\r
132         }\r
133 \r
134         try {\r
135             getContainer().run(true, true,createExportRunnable(exportModel));\r
136         } catch (InvocationTargetException e) {\r
137             Throwable t = e.getTargetException();\r
138             WizardPage cp = (WizardPage) getContainer().getCurrentPage();\r
139             if (t instanceof IOException) {\r
140                 ErrorLogger.defaultLogError("An I/O problem occurred while exporting the model. See exception for details.", t);\r
141                 cp.setErrorMessage("An I/O problem occurred while exporting the model.\n\nMessage: " + e.getMessage());\r
142             } else {\r
143                 ErrorLogger.defaultLogError("Unexpected exception while exporting the model. See exception for details.", t);\r
144                 cp.setErrorMessage("Unexpected exception while exporting the model. See error log for details.\n\nMessage: " + e.getMessage());\r
145             }\r
146             return false;\r
147         } catch (InterruptedException e) {\r
148             ExceptionUtils.logAndShowError(e);\r
149             return false;\r
150         }\r
151 \r
152         return true;\r
153         }\r
154         \r
155         \r
156         \r
157         \r
158         private boolean readPreferences() {\r
159         IPreferenceStore store = getPreferenceStore();\r
160 \r
161         String recentPathsPref = store.getString(getExportLocationId());\r
162         recentExportPaths = decodePaths(recentPathsPref);\r
163         overwrite = store.getBoolean(getExportOverwriteId());\r
164 \r
165         return true;\r
166     }\r
167         \r
168         private void writePreferences() throws IOException {\r
169         IPersistentPreferenceStore store = getPreferenceStore();\r
170 \r
171         store.putValue(getExportLocationId(), encodePaths(recentExportPaths));\r
172         store.setValue(getExportOverwriteId(), exportModel.isOverwrite());\r
173 \r
174         if (store.needsSaving())\r
175             store.save();\r
176     }\r
177         \r
178         private static final String TAG_PATH = "path";\r
179         private static final String ATTR_NAME = "name";\r
180         \r
181         \r
182         public static Deque<String> decodePaths(String recentPathsPref) {\r
183                 Deque<String> result = new LinkedList<String>();\r
184                 try {\r
185                         StringMemento sm = new StringMemento(recentPathsPref);\r
186                         for (IMemento m : sm.getChildren(TAG_PATH)) {\r
187                                 String name = m.getString(ATTR_NAME);\r
188                                 if (name != null && !name.isEmpty())\r
189                                         result.add(name);\r
190                         }\r
191                 } catch (IllegalArgumentException e) {\r
192                 }\r
193                 return result;\r
194         }\r
195         \r
196         public static String encodePaths(Deque<String> recentPaths) {\r
197                 StringMemento sm = new StringMemento();\r
198                 for (String path : recentPaths) {\r
199                         IMemento m = sm.createChild(TAG_PATH);\r
200                         m.putString(ATTR_NAME, path);\r
201                 }\r
202                 return sm.toString();\r
203         }\r
204         \r
205         public static <T> void removeDuplicates(Iterable<String> iter) {\r
206                 // Remove duplicates\r
207                 Set<String> dups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);\r
208                 for (Iterator<String> it = iter.iterator(); it.hasNext();) {\r
209                         String path = it.next();\r
210                         if (!dups.add(path)) {\r
211                                 it.remove();\r
212                         }\r
213                 }\r
214         }\r
215 }\r