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