]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartPDF.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.charts / src / org / simantics / charts / export / ExportChartPDF.java
1 package org.simantics.charts.export;\r
2 \r
3 import java.awt.Graphics2D;\r
4 import java.awt.geom.Rectangle2D;\r
5 import java.util.ArrayList;\r
6 import java.util.Collection;\r
7 import java.util.Collections;\r
8 import java.util.List;\r
9 import java.util.UUID;\r
10 \r
11 import org.eclipse.core.runtime.IProgressMonitor;\r
12 import org.eclipse.core.runtime.OperationCanceledException;\r
13 import org.eclipse.core.runtime.preferences.DefaultScope;\r
14 import org.eclipse.core.runtime.preferences.InstanceScope;\r
15 import org.osgi.service.prefs.Preferences;\r
16 import org.simantics.Simantics;\r
17 import org.simantics.charts.preference.ChartPreferences;\r
18 import org.simantics.charts.query.MilestoneSpecQuery;\r
19 import org.simantics.charts.query.TrendSpecQuery;\r
20 import org.simantics.databoard.Accessors;\r
21 import org.simantics.databoard.accessor.RecordAccessor;\r
22 import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
23 import org.simantics.databoard.accessor.reference.ChildReference;\r
24 import org.simantics.databoard.binding.mutable.Variant;\r
25 import org.simantics.databoard.type.RecordType;\r
26 import org.simantics.databoard.type.UnionType;\r
27 import org.simantics.db.Resource;\r
28 import org.simantics.db.exception.DatabaseException;\r
29 import org.simantics.db.layer0.request.PossibleModel;\r
30 import org.simantics.export.core.ExportContext;\r
31 import org.simantics.export.core.error.ExportException;\r
32 import org.simantics.export.core.manager.Content;\r
33 import org.simantics.export.core.pdf.ExportPdfWriter;\r
34 import org.simantics.export.core.pdf.ExportPdfWriter.Page;\r
35 import org.simantics.export.core.util.ExportQueries;\r
36 import org.simantics.export.core.util.ExporterUtils;\r
37 import org.simantics.g2d.canvas.impl.CanvasContext;\r
38 import org.simantics.history.History;\r
39 import org.simantics.history.HistoryException;\r
40 import org.simantics.history.HistoryManager;\r
41 import org.simantics.simulation.experiment.IExperiment;\r
42 import org.simantics.simulation.experiment.IHistoryExperiment;\r
43 import org.simantics.simulation.export.ExperimentExportClass;\r
44 import org.simantics.simulation.project.ExperimentManager;\r
45 import org.simantics.simulation.project.IExperimentManager;\r
46 import org.simantics.trend.TrendInitializer;\r
47 import org.simantics.trend.configuration.ItemPlacement;\r
48 import org.simantics.trend.configuration.TimeFormat;\r
49 import org.simantics.trend.configuration.TrendSpec;\r
50 import org.simantics.trend.impl.MilestoneSpec;\r
51 import org.simantics.trend.impl.TrendNode;\r
52 import org.simantics.utils.datastructures.MapList;\r
53 import org.simantics.utils.format.ValueFormat;\r
54 import org.simantics.utils.threads.ThreadUtils;\r
55 import org.simantics.utils.threads.WorkerThread;\r
56 \r
57 public class ExportChartPDF extends ExperimentExportClass {\r
58 \r
59         public static final RecordType chartOptions;\r
60         \r
61         public static String S_CHART = "Chart";\r
62         public static ChildReference P_ITEMPLACEMENT = ChildReference.parsePath(S_CHART+"/Item Placement");\r
63         public static ChildReference P_TIMEFORMAT = ChildReference.parsePath(S_CHART+"/Time Format");\r
64         public static ChildReference P_VALUEFORMAT = ChildReference.parsePath(S_CHART+"/Value Format");\r
65         \r
66         static {\r
67                 chartOptions = new RecordType();\r
68             chartOptions.addComponent("Item Placement", UnionType.newEnum("Stacked", "Overlapping"));\r
69             chartOptions.addComponent("Time Format", UnionType.newEnum("Decimal", "Time"));\r
70             chartOptions.addComponent("Value Format", UnionType.newEnum("Currency", "Scientific", "Engineering", "Default"));\r
71         }\r
72 \r
73         @Override\r
74         public void export(List<Content> contents, \r
75                         Object handle,\r
76                         ExportContext ctx, \r
77                         Variant options,\r
78                         IProgressMonitor monitor, \r
79                         MapList<Content, Content> attachmentMap\r
80                         ) throws ExportException {\r
81 \r
82                 // Flush all experiments, just in case.\r
83                 IExperimentManager em = Simantics.getProject().getHint( ExperimentManager.KEY_EXPERIMENT_MANAGER );\r
84                 if ( em != null ) {\r
85                         for (IExperiment exp : em.getExperiments()) {\r
86                                 if ( exp instanceof IHistoryExperiment ) {\r
87                                         IHistoryExperiment he = (IHistoryExperiment) exp;\r
88                                         try {\r
89                                                 he.flushHistory();\r
90                                         } catch (HistoryException e) {\r
91                                         }\r
92                                 }\r
93                         }\r
94                 }\r
95                 \r
96                 final ExportPdfWriter writer = (ExportPdfWriter) handle;\r
97         final WorkerThread workerThread = new WorkerThread("Chart PDF Painter");\r
98         workerThread.start();\r
99                 try {\r
100                         \r
101                         final RecordAccessor ra = Accessors.getAccessor( options );\r
102                         \r
103                         // Get a list of the history managers the user has selected.\r
104                         List<ModelRef> modelRefs = ExperimentExportClass.getResult(ctx, options, true);\r
105                         List<ChartSettings> charts = new ArrayList<ChartSettings>();\r
106                                                 \r
107                         for ( Content content : contents ) {\r
108                                 if (monitor.isCanceled())\r
109                                         throw new OperationCanceledException();\r
110 \r
111                                 Resource chartRes = ctx.session.syncRequest( ExportQueries.toResource(content.url) );\r
112                                 Resource model = ctx.session.syncRequest( new PossibleModel( chartRes ) );\r
113                                 for (ModelRef modelRef : modelRefs) {\r
114                                         if ( !modelRef.resource.equals(model) ) continue;\r
115                                         for (ExperimentRef experimentRef : modelRef.experiments) {\r
116                                                 for (RunRef runRef : experimentRef.runs) {                                              \r
117                                                         if ( runRef.historyFolder == null || !runRef.historyFolder.exists() ) continue;\r
118                                                         HistoryManager history = History.openFileHistory( runRef.historyFolder );\r
119                                                         \r
120                                                         ChartSettings cs = new ChartSettings();\r
121                                                         cs.history = history;\r
122                                                         cs.modelRef = modelRef;\r
123                                                         cs.experimentRef = experimentRef;\r
124                                                         cs.runRef = runRef;\r
125                                                         cs.chartRes = chartRes;\r
126                                                         charts.add( cs );\r
127                                                 }                                               \r
128                                         }\r
129                                 }                               \r
130                         }\r
131                                                 \r
132                                                                         \r
133                         for ( final ChartSettings cs : charts ) {                               \r
134                                 UUID id = UUID.randomUUID();\r
135                                 final TrendSpec trendSpec = ctx.session.syncRequest( new TrendSpecQuery( id, cs.chartRes ) );\r
136                         if ( cs.modelRef.enabledRunCount() > 1 ) {\r
137                                 // Add run ref to the label\r
138                                 trendSpec.name += " / " + cs.runRef.label;\r
139                         }\r
140                         \r
141                         \r
142                         final MilestoneSpec milestones = ctx.session.syncRequest( new MilestoneSpecQuery( cs.experimentRef.resource ) );                        \r
143                         //final CanvasContext cctx = new CanvasContext( workerThread );\r
144                         final ExportException[] error = new ExportException[1]; \r
145                         \r
146                 ThreadUtils.syncExec(workerThread, new Runnable() {\r
147                     @Override\r
148                     public void run() {\r
149                                         CanvasContext cctx = TrendInitializer.createDefaultCanvas(workerThread, cs.history, null, null, trendSpec);\r
150                                         Page pdfPage = null;\r
151                                 try {                                                                   \r
152                                         TrendNode trend = TrendInitializer.getTrendNode( cctx );   \r
153                                         trend.printing = true;\r
154                                         \r
155                                                 String s = ExporterUtils.getUnionValue(ra, P_ITEMPLACEMENT);\r
156                                                 if ( s!=null ) trend.itemPlacement = ItemPlacement.valueOf(s);\r
157                                                 s = ExporterUtils.getUnionValue(ra, P_TIMEFORMAT);\r
158                                                 if ( s!=null ) trend.timeFormat = TimeFormat.valueOf(s);\r
159                                                 s = ExporterUtils.getUnionValue(ra, P_VALUEFORMAT);\r
160                                         if ( s!=null ) trend.valueFormat = ValueFormat.valueOf(s);\r
161                                         \r
162                                         if (milestones!=null) trend.setMilestones(milestones);\r
163                                                 \r
164                                                 pdfPage = writer.createPage( null );\r
165                                                 Graphics2D g2d = pdfPage.createGraphics( true );\r
166                                                 try {\r
167                                                         Rectangle2D clip = new Rectangle2D.Double(0, 0, pdfPage.getWidth(), pdfPage.getHeight());\r
168                                                         g2d.setClip( clip );\r
169                                             g2d.scale(0.25, 0.25);\r
170                                             trend.autoscale(true, true);\r
171                                                         trend.zoomOut();\r
172                                                         trend.layout();\r
173                                                         trend.render( g2d );\r
174                                                 } finally {\r
175                                                         trend.cleanup();\r
176                                                         g2d.dispose();\r
177                                                         cs.history.close();\r
178                                                 }\r
179                         } catch (ExportException e) {\r
180                                 error[0] = e;\r
181                                                 } finally {\r
182                                 cctx.dispose();\r
183                                 if ( pdfPage != null )\r
184                                                                 try {\r
185                                                                         pdfPage.close();\r
186                                                                 } catch (ExportException e) {\r
187                                                                         if ( error[0]==null ) error[0] = e;\r
188                                                                 }\r
189                         }\r
190                     }\r
191                 });\r
192                         if ( error[0] != null ) throw error[0];\r
193                                 \r
194                         }\r
195                 } catch (DatabaseException e) {\r
196                         throw new ExportException( e ); \r
197                 } catch (AccessorConstructionException e) {\r
198                         throw new ExportException( e ); \r
199                 } finally {\r
200                         workerThread.stopDispatchingEvents(true);\r
201                 }\r
202                 \r
203         }\r
204 \r
205         \r
206         @Override\r
207         public RecordType options(ExportContext context, Collection<String> content) throws ExportException {\r
208                 RecordType options = super.options(context, content);\r
209                 options.addComponent(S_CHART, chartOptions);\r
210                 return options;\r
211         }\r
212 \r
213         @Override\r
214         public void fillDefaultPrefs(ExportContext ctx, Variant options) throws ExportException {\r
215                 super.fillDefaultPrefs(ctx, options);\r
216                 // Read from eclipse preferences\r
217         try {\r
218                         RecordAccessor ra = Accessors.getAccessor(options);                     \r
219                         Preferences instPrefs = InstanceScope.INSTANCE.getNode( ChartPreferences.P_NODE );\r
220                         Preferences defaultPrefs = DefaultScope.INSTANCE.getNode( ChartPreferences.P_NODE );\r
221                         \r
222                         String s;\r
223                         s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_ITEMPLACEMENT);\r
224                         ExporterUtils.setUnionValue(ra, P_ITEMPLACEMENT, s);\r
225                         \r
226                         s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_TIMEFORMAT);\r
227                         ExporterUtils.setUnionValue(ra, P_TIMEFORMAT, s);\r
228 \r
229                         s = ExporterUtils.getPrefString(instPrefs, defaultPrefs, ChartPreferences.P_VALUEFORMAT);\r
230                         ExporterUtils.setUnionValue(ra, P_VALUEFORMAT, s);\r
231                         \r
232                 } catch (AccessorConstructionException e) {\r
233                         throw new ExportException(e);\r
234                 }\r
235         }\r
236 \r
237         @Override\r
238         public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {\r
239                 super.savePref(options, contentScopeNode, workbenchScopeNode);\r
240         try {\r
241                         RecordAccessor ra = Accessors.getAccessor(options);                     \r
242                         String s;\r
243                         \r
244                         s = ExporterUtils.getUnionValue(ra, P_ITEMPLACEMENT);\r
245                         ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_ITEMPLACEMENT, s);\r
246                         ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_ITEMPLACEMENT, s);\r
247                         \r
248                         s = ExporterUtils.getUnionValue(ra, P_TIMEFORMAT);\r
249                         ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_TIMEFORMAT, s);\r
250                         ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_TIMEFORMAT, s);\r
251                         \r
252                         s = ExporterUtils.getUnionValue(ra, P_VALUEFORMAT);\r
253                         ExporterUtils.setPrefString(contentScopeNode, ChartPreferences.P_VALUEFORMAT, s);\r
254                         ExporterUtils.setPrefString(workbenchScopeNode, ChartPreferences.P_VALUEFORMAT, s);\r
255                         \r
256                 } catch (AccessorConstructionException e) {\r
257                         throw new ExportException(e);\r
258                 }\r
259                 \r
260         }\r
261 \r
262         @Override\r
263         public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {\r
264                 super.loadPref(options, contentScopeNode, workbenchScopeNode);\r
265         try {\r
266                         RecordAccessor ra = Accessors.getAccessor(options);                     \r
267                         \r
268                         String s;\r
269                         s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_ITEMPLACEMENT);\r
270                         if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_ITEMPLACEMENT);\r
271                         ExporterUtils.setUnionValue(ra, P_ITEMPLACEMENT, s);\r
272                         \r
273                         s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_TIMEFORMAT);\r
274                         if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_TIMEFORMAT); \r
275                         ExporterUtils.setUnionValue(ra, P_TIMEFORMAT, s);\r
276 \r
277                         s = ExporterUtils.getPrefString(contentScopeNode, ChartPreferences.P_VALUEFORMAT);\r
278                         if ( s==null ) s = ExporterUtils.getPrefString(workbenchScopeNode, ChartPreferences.P_VALUEFORMAT); \r
279                         ExporterUtils.setUnionValue(ra, P_VALUEFORMAT, s);\r
280                         \r
281                 } catch (AccessorConstructionException e) {\r
282                         throw new ExportException(e);\r
283                 }\r
284         }\r
285 \r
286         @Override\r
287         public List<String> validate(String contentUri, ExportContext context, Variant options) {\r
288                 return Collections.emptyList();\r
289         }\r
290         \r
291         static class ChartSettings {\r
292 \r
293                 Resource chartRes;\r
294                 ModelRef modelRef;\r
295                 ExperimentRef experimentRef;\r
296                 RunRef runRef;\r
297                 HistoryManager history;\r
298                 \r
299         }\r
300 \r
301 }\r