]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.export.core/src/org/simantics/export/core/pdf/ExportPdfFormat.java
Merge branch 'feature/funcwrite'
[simantics/platform.git] / bundles / org.simantics.export.core / src / org / simantics / export / core / pdf / ExportPdfFormat.java
1 package org.simantics.export.core.pdf;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.List;
9 import java.util.StringTokenizer;
10 import java.util.concurrent.atomic.AtomicBoolean;
11 import java.util.regex.Pattern;
12
13 import org.eclipse.core.runtime.IProduct;
14 import org.eclipse.core.runtime.Platform;
15 import org.eclipse.core.runtime.preferences.DefaultScope;
16 import org.eclipse.core.runtime.preferences.InstanceScope;
17 import org.osgi.service.prefs.Preferences;
18 import org.simantics.databoard.Accessors;
19 import org.simantics.databoard.Bindings;
20 import org.simantics.databoard.Datatypes;
21 import org.simantics.databoard.accessor.RecordAccessor;
22 import org.simantics.databoard.accessor.UnionAccessor;
23 import org.simantics.databoard.accessor.error.AccessorConstructionException;
24 import org.simantics.databoard.accessor.error.AccessorException;
25 import org.simantics.databoard.accessor.error.ReferenceException;
26 import org.simantics.databoard.accessor.reference.ChildReference;
27 import org.simantics.databoard.accessor.reference.LabelReference;
28 import org.simantics.databoard.binding.mutable.Variant;
29 import org.simantics.databoard.forms.DataboardForm;
30 import org.simantics.databoard.type.DoubleType;
31 import org.simantics.databoard.type.RecordType;
32 import org.simantics.databoard.type.StringType;
33 import org.simantics.databoard.type.UnionType;
34 import org.simantics.export.core.ExportContext;
35 import org.simantics.export.core.error.ExportException;
36 import org.simantics.export.core.intf.FormatClass;
37 import org.simantics.export.core.manager.Content;
38 import org.simantics.export.core.util.ExporterUtils;
39 import org.simantics.utils.page.MarginUtils;
40 import org.simantics.utils.page.MarginUtils.Margin;
41 import org.simantics.utils.page.MarginUtils.Margins;
42 import org.simantics.utils.page.PageDesc;
43 import org.simantics.utils.page.PageOrientation;
44
45 import com.lowagie.text.Document;
46 import com.lowagie.text.DocumentException;
47 import com.lowagie.text.FontFactory;
48 import com.lowagie.text.Rectangle;
49 import com.lowagie.text.pdf.PdfBoolean;
50 import com.lowagie.text.pdf.PdfCopy;
51 import com.lowagie.text.pdf.PdfName;
52 import com.lowagie.text.pdf.PdfWriter;
53
54 /**
55  * Represents the actions to Pdf File format in Export Core.
56  *
57  * @author toni.kalajainen@semantum.fi
58  */
59 public class ExportPdfFormat implements FormatClass {
60
61         public static final Pattern PATTERN_PDF = Pattern.compile(".*\\.pdf$", Pattern.CASE_INSENSITIVE);
62         
63         // Options references
64         public static String S_PDF = "Portable Document Format (PDF)";
65         public static ChildReference P_PDF_TITLE = ChildReference.parsePath(S_PDF+"/Title");
66         public static ChildReference P_PDF_AUTHOR = ChildReference.parsePath(S_PDF+"/Author");
67         public static ChildReference P_PDF_SUBJECT = ChildReference.parsePath(S_PDF+"/Subject");
68         public static ChildReference P_PDF_KEYWORDS = ChildReference.parsePath(S_PDF+"/Keywords");
69         public static ChildReference P_PDF_COMPRESSION = ChildReference.parsePath(S_PDF+"/Compression");
70         
71         public static String S_SIGN = "Digital Signature";
72         public static LabelReference P_SIGN = new LabelReference( S_SIGN );
73         public static ChildReference P_SIGN_KEYSTORE = ChildReference.concatenate(P_SIGN, new LabelReference("Keystore") );     
74         public static ChildReference P_SIGN_KEYSTOREPASSWORD = ChildReference.concatenate(P_SIGN, new LabelReference("Keystore Password"));
75         public static ChildReference P_SIGN_PRIVATEKEYPASSWORD = ChildReference.concatenate(P_SIGN, new LabelReference("Private Key Password"));
76         public static ChildReference P_SIGN_LOCATION = ChildReference.concatenate(P_SIGN, new LabelReference("Sign Location")); 
77         public static ChildReference P_SIGN_REASON = ChildReference.concatenate(P_SIGN, new LabelReference("Sign Reason"));     
78
79         public static String S_PAGE = "Page Settings";
80         public static ChildReference P_PAGE = new LabelReference( S_PAGE );
81         public static ChildReference P_PAGE_PAPERSIZE = ChildReference.concatenate(P_PAGE, new LabelReference("Size"));
82         public static ChildReference P_PAGE_ORIENTATION = ChildReference.concatenate(P_PAGE, new LabelReference("Orientation"));
83         public static ChildReference P_PAGE_MARGIN_LEFT = ChildReference.concatenate(P_PAGE, new LabelReference("Margin Left"));
84         public static ChildReference P_PAGE_MARGIN_RIGHT = ChildReference.concatenate(P_PAGE, new LabelReference("Margin Right"));
85         public static ChildReference P_PAGE_MARGIN_TOP = ChildReference.concatenate(P_PAGE, new LabelReference("Margin Top"));
86         public static ChildReference P_PAGE_MARGIN_BOTTOM = ChildReference.concatenate(P_PAGE, new LabelReference("Margin Bottom"));
87         
88         // Preference page IDs
89     public static String PAGE_PLUGIN_ID = "org.simantics.modeling.ui";
90         
91     public static String P_DEFAULT_PAGE_SIZE        = "page.default.size";
92     
93     private static final AtomicBoolean fontFactoryInitialized = new AtomicBoolean();
94     
95     public static final RecordType pdfOptions;
96
97     static {
98         pdfOptions = new RecordType();          
99         DoubleType mm = new DoubleType();
100         mm.setUnit("mm");
101         
102             // PDF metadata         
103         RecordType pdfRecord = new RecordType();
104             pdfRecord.addComponent("Title", Datatypes.STRING );
105             pdfRecord.addComponent("Author", Datatypes.STRING );
106             pdfRecord.addComponent("Subject", Datatypes.STRING );
107             pdfRecord.addComponent("Keywords", DataboardForm.TEXTBOX );     
108             // Formatter options 
109             pdfRecord.addComponent("Compression", UnionType.newEnum("0 (No compression)", "1", "2", "3", "4", "5", "6", "7", "8", "9 (Best)"));
110             
111             // PDF Encryption
112         RecordType pdfSign = new RecordType();
113             StringType certificate = DataboardForm.fileOpenDialog("PKCS#12 keystore (.p12)", "*.p12", "PFX (.pfx)", "*.pfx"); //, "Privacy Enhanced Mail (.pem)", ".pem" 
114             pdfSign.addComponent("Keystore", certificate);
115             pdfSign.addComponent("Keystore Password", DataboardForm.PASSWORD);
116             pdfSign.addComponent("Private Key Password", DataboardForm.PASSWORD);
117             pdfSign.addComponent("Sign Location", Datatypes.STRING);        
118             pdfSign.addComponent("Sign Reason", Datatypes.STRING);                  
119             
120             PageDesc[] descs = PageDesc.PDF_ITEMS;
121             String[] pageSizesStr = new String[ descs.length ];
122             for ( int i=0; i<descs.length; i++ ) pageSizesStr[i] = descs[i].getText();
123             UnionType pageSizes = UnionType.newEnum("A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10");
124             UnionType orientation = UnionType.newEnum("Portrait", "Landscape");
125             RecordType pagePrefs = new RecordType();
126             pagePrefs.addComponent("Size", pageSizes);
127             pagePrefs.addComponent("Orientation", orientation);
128             pagePrefs.addComponent("Margin Left", mm);
129             pagePrefs.addComponent("Margin Right", mm);
130             pagePrefs.addComponent("Margin Top", mm);
131             pagePrefs.addComponent("Margin Bottom", mm);
132             //pagePrefs.metadata.put("style", "dialog");
133             
134             pdfOptions.addComponent(S_PDF, pdfRecord);
135             pdfOptions.addComponent(S_SIGN, pdfSign);
136             pdfOptions.addComponent(S_PAGE, pagePrefs);
137     }
138     
139         @Override
140         public RecordType options(ExportContext context) throws ExportException {
141                 return pdfOptions;              
142         }
143
144         @Override
145         public Object createFile(ExportContext ctx, File outputFile, Variant options) throws ExportException {
146                 try {
147                         RecordAccessor ra = Accessors.getAccessor( options );
148                         
149             if (fontFactoryInitialized.compareAndSet(false, true)) {
150                 // Only register directories once.
151                 FontFactory.registerDirectories();
152             }
153             
154                         ExportPdfWriter writer = new ExportPdfWriter();
155                         
156                         Rectangle pageSize = null;
157                         writer.document = new Document(pageSize);
158                         writer.outputFile = outputFile;
159                         writer.fos = new FileOutputStream(writer.outputFile);
160                         writer.pdfCopy = new PdfCopy(writer.document, writer.fos); 
161                         writer.pdfCopy.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
162                         writer.fontMapper = FontMapping.defaultFontMapper();
163                         writer.options = options;
164                         writer.ctx = ctx;
165
166                         String creator = getCreator();
167                         writer.document.addCreator(creator);
168
169                         String s; 
170                         s = (String) ra.getValue(P_PDF_TITLE, Bindings.STRING);
171                         if ( s!=null ) writer.document.addTitle(s);                     
172
173                         s = (String) ra.getValue(P_PDF_AUTHOR, Bindings.STRING);
174                         if ( s!=null ) writer.document.addAuthor(s);
175
176                         s = (String) ra.getValue(P_PDF_SUBJECT, Bindings.STRING);
177                         if ( s!=null ) writer.document.addSubject(s);
178
179                         s = (String) ra.getValue(P_PDF_KEYWORDS, Bindings.STRING);
180                         if ( s!=null ) writer.document.addKeywords(s);
181
182                         // Compression Level
183                         try {                   
184                         UnionAccessor ua = ra.getComponent(P_PDF_COMPRESSION);
185                         int tag = ua.getTag();                  
186                         writer.pdfCopy.setCompressionLevel( tag );
187                         writer.compressionLevel = tag;
188                 } catch (ReferenceException re) {                       
189                         }
190
191                         // PageSize
192                         {                               
193                                 Margins margins = MarginUtils.MARGINS_10mm;
194                                 Double left = (Double) ra.getValue(P_PAGE_MARGIN_LEFT, Bindings.DOUBLE);
195                                 if ( left!=null ) margins = margins.withSide(Margins.LEFT, new Margin(0, 0, left));
196                                 Double right = (Double) ra.getValue(P_PAGE_MARGIN_RIGHT, Bindings.DOUBLE);
197                                 if ( right!=null ) margins = margins.withSide(Margins.RIGHT, new Margin(0, 0, right));
198                                 Double bottom = (Double) ra.getValue(P_PAGE_MARGIN_BOTTOM, Bindings.DOUBLE);
199                                 if ( bottom!=null ) margins = margins.withSide(Margins.BOTTOM, new Margin(0, 0, bottom));
200                                 Double top = (Double) ra.getValue(P_PAGE_MARGIN_TOP, Bindings.DOUBLE);
201                                 if ( top!=null ) margins = margins.withSide(Margins.TOP, new Margin(0, 0, top));
202                                 
203                                 String paperName = "A4";
204                                 try {                   
205                                 UnionAccessor ua = ra.getComponent(P_PAGE_PAPERSIZE);
206                                 int tag = ua.getTag();
207                                 paperName = ua.type().getComponent(tag).name;                           
208                         } catch (ReferenceException re) {                       
209                                 }
210                                 
211                                 PageOrientation pageOrientation = PageOrientation.Portrait;
212                                 try {                   
213                                 UnionAccessor ua = ra.getComponent(P_PAGE_ORIENTATION);
214                                 int tag = ua.getTag();
215                                 String str = ua.type().getComponent(tag).name;
216                                 pageOrientation = PageOrientation.valueOf( str );
217                         } catch (ReferenceException re) {                       
218                                 }
219                                 
220                                 PageDesc pd = PageDesc.getByName(paperName);
221                                 pd = pd.withOrientation(pageOrientation);
222                                 pd = pd.withMargins(margins);
223                                 writer.margins = margins;
224                                 writer.defaultPageDesc = pd;
225                                 writer.defaultRectangle = ExportPdfWriter.toRectangle( writer.defaultPageDesc );
226                                 writer.document.setPageSize( writer.defaultRectangle );
227                         }
228                         
229                         // Add Developer Extension - not used
230 //              PdfName companyName = new PdfName("SMTC");          
231 //          PdfDeveloperExtension ext = new PdfDeveloperExtension(companyName, PdfWriter.PDF_VERSION_1_7, 3);
232 //          writer.addDeveloperExtension( ext );
233                         
234                         
235             writer.document.open();
236             writer.cb = writer.pdfCopy.getDirectContent();
237                         
238                         return writer;
239                 } catch (FileNotFoundException e) {
240                         throw new ExportException( e );
241                 } catch (DocumentException e) {
242                         throw new ExportException( e );
243                 } catch (AccessorConstructionException e) {
244                         throw new ExportException( e );
245                 } catch (AccessorException e) {
246                         throw new ExportException( e );
247                 }
248         }
249
250         @Override
251         public Object openFile(ExportContext context, File inputFile, Variant options) throws ExportException {
252                 try {
253                         return new ImportPdfReader(inputFile);
254                 } catch (IOException e) {
255                         throw new ExportException(e);
256                 }
257         }
258         
259         @Override
260         public List<String> validate(ExportContext context, Variant options) throws ExportException {
261                 List<String> problems = new ArrayList<String>();
262                 
263                 try {
264                         RecordAccessor ra = Accessors.getAccessor( options );
265
266                         // Assert the keystore file exists, if set.
267                         String keystoreFileName = (String) ra.getValue(P_SIGN_KEYSTORE, Bindings.STRING);                                                       
268                         if ( keystoreFileName != null && !keystoreFileName.isEmpty() ) {
269                                 File keystoreFile = new File( keystoreFileName );
270                                 if ( !keystoreFile.exists() ) {
271                                         problems.add( "Keystore file was not found: "+keystoreFile );
272                                 }
273                         }
274                         
275                 } catch (AccessorConstructionException e) {
276                         throw new ExportException( e );
277                 } catch (AccessorException e) {
278                         throw new ExportException( e );
279                 }
280                 
281                 return problems;
282         }
283
284         @Override
285         public void closeFile(ExportContext context, Object handle) throws ExportException {
286                 if ( handle instanceof ImportPdfReader ) {
287                         ImportPdfReader reader = (ImportPdfReader) handle;
288                         reader.close();
289                 }
290                 
291                 if ( handle instanceof ExportPdfWriter ) {
292                         ExportPdfWriter writer = (ExportPdfWriter) handle;
293         
294                         writer.close();
295                         
296                         try {
297                                 RecordAccessor ra = Accessors.getAccessor( writer.options );
298                                 
299                                 String keystoreFileName = (String) ra.getValue(P_SIGN_KEYSTORE, Bindings.STRING);                               
300                                 String keystorePassword = (String) ra.getValue(P_SIGN_KEYSTOREPASSWORD, Bindings.STRING);
301                                 String privateKeyPassword = (String) ra.getValue(P_SIGN_PRIVATEKEYPASSWORD, Bindings.STRING);
302                                 String signLocation = (String) ra.getValue(P_SIGN_LOCATION, Bindings.STRING);
303                                 String signReason = (String) ra.getValue(P_SIGN_REASON, Bindings.STRING);
304                                 
305                                 if ( keystoreFileName != null && !keystoreFileName.isEmpty() ) 
306                                 {
307                                         File keystoreFile = new File( keystoreFileName );
308                                         if ( !keystoreFile.exists() ) {
309                                                 throw new ExportException( "Keystore file was not found: "+keystoreFile );
310                                         }
311                                         writer.sign(keystoreFile, keystorePassword, privateKeyPassword, signLocation, signReason);
312                                 }
313         
314                         } catch (AccessorConstructionException e) {
315                                 throw new ExportException( e.getClass().getName()+": "+e.getMessage() );
316                         } catch (AccessorException e) {
317                                 throw new ExportException( e.getClass().getName()+": "+e.getMessage() );
318                         }
319                         
320                         // Encrypt
321                     /*
322                     writer.setEncryption(
323                                 new Certificate[] {}, 
324                                 new int[] {PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING}, 
325                                 PdfWriter.STANDARD_ENCRYPTION_128);
326                     //writer.setEncryption(PdfWriter.STANDARD_ENCRYPTION_128, "", "password", PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_ASSEMBLY);
327                         
328                         int permission = PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_ASSEMBLY;
329                         PdfEncryption crypto = new PdfEncryption();
330                         //for (Certificate c : chain) crypto.addRecipient(c, permission);
331                         //crypto.addRecipient(chain[2], permission);
332                 crypto.setCryptoMode(PdfWriter.ENCRYPTION_AES_128, 0);
333                         crypto.setupByEncryptionKey(key.getEncoded(), key.getEncoded().length*8);
334                 crypto.getEncryptionDictionary();
335                         */
336                 }
337         }
338
339         @Override
340         public void addAttachment(ExportContext ctx, Object handle, List<Content> attachments) throws ExportException {
341                 ExportPdfWriter writer = (ExportPdfWriter) handle; 
342
343         writer.pdfCopy.addViewerPreference(PdfName.USEATTACHMENTS, PdfBoolean.PDFTRUE);
344                 for ( Content content : attachments ) {
345                         writer.addAttachment( content );
346                 }               
347         }
348         
349         @Override
350         public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {
351         try {
352                         RecordAccessor ra = Accessors.getAccessor(options);                     
353                         String s; 
354                         
355                         s = (String) ra.getValue(P_PDF_TITLE, Bindings.STRING);
356                         if ( s!=null ) contentScopeNode.put(P_PDF_TITLE.tail().toString(), s);
357
358                         s = (String) ra.getValue(P_PDF_AUTHOR, Bindings.STRING);
359                         if ( s!=null ) workbenchScopeNode.put(P_PDF_AUTHOR.tail().toString(), s);
360
361                         s = (String) ra.getValue(P_PDF_SUBJECT, Bindings.STRING);
362                         if ( s!=null ) contentScopeNode.put(P_PDF_SUBJECT.tail().toString(), s);
363
364                         s = (String) ra.getValue(P_PDF_KEYWORDS, Bindings.STRING);
365                         if ( s!=null ) contentScopeNode.put(P_PDF_KEYWORDS.tail().toString(), s);
366
367                         s = (String) ra.getValue(P_SIGN_KEYSTORE, Bindings.STRING);
368                         if ( s!=null ) workbenchScopeNode.put(P_SIGN_KEYSTORE.tail().toString(), s);
369
370                         s = (String) ra.getValue(P_SIGN_KEYSTOREPASSWORD, Bindings.STRING);
371                         if ( s!=null ) workbenchScopeNode.put(P_SIGN_KEYSTOREPASSWORD.tail().toString(), s);
372
373                         s = (String) ra.getValue(P_SIGN_PRIVATEKEYPASSWORD, Bindings.STRING);
374                         if ( s!=null ) workbenchScopeNode.put(P_SIGN_PRIVATEKEYPASSWORD.tail().toString(), s);
375
376                         s = (String) ra.getValue(P_SIGN_LOCATION, Bindings.STRING);
377                         if ( s!=null ) workbenchScopeNode.put(P_SIGN_LOCATION.tail().toString(), s);
378
379                         s = (String) ra.getValue(P_SIGN_REASON, Bindings.STRING);
380                         if ( s!=null ) workbenchScopeNode.put(P_SIGN_REASON.tail().toString(), s);
381                         
382                         try {                   
383                         UnionAccessor ua = ra.getComponent(P_PDF_COMPRESSION);
384                         int tag = ua.getTag();
385                         workbenchScopeNode.putInt(P_PDF_COMPRESSION.tail().toString(), tag);
386                 } catch (ReferenceException re) {                       
387                         }
388                         
389                         Double d = (Double) ra.getValue(P_PAGE_MARGIN_LEFT, Bindings.DOUBLE);
390                         if ( d!=null ) contentScopeNode.putDouble(P_PAGE_MARGIN_LEFT.tail().toString(), d);
391
392                         d = (Double) ra.getValue(P_PAGE_MARGIN_RIGHT, Bindings.DOUBLE);
393                         if ( d!=null ) contentScopeNode.putDouble(P_PAGE_MARGIN_RIGHT.tail().toString(), d);
394                         
395                         d = (Double) ra.getValue(P_PAGE_MARGIN_BOTTOM, Bindings.DOUBLE);
396                         if ( d!=null ) contentScopeNode.putDouble(P_PAGE_MARGIN_BOTTOM.tail().toString(), d);
397
398                         d = (Double) ra.getValue(P_PAGE_MARGIN_TOP, Bindings.DOUBLE);
399                         if ( d!=null ) contentScopeNode.putDouble(P_PAGE_MARGIN_TOP.tail().toString(), d);
400                         
401                         try {                   
402                         UnionAccessor ua = ra.getComponent(P_PAGE_PAPERSIZE);
403                         int tag = ua.getTag();
404                         contentScopeNode.putInt(P_PAGE_PAPERSIZE.tail().toString(), tag);
405                 } catch (ReferenceException re) {                       
406                         }
407                         
408                         try {                   
409                         UnionAccessor ua = ra.getComponent(P_PAGE_ORIENTATION);
410                         int tag = ua.getTag();
411                         contentScopeNode.putInt(P_PAGE_ORIENTATION.tail().toString(), tag);
412                 } catch (ReferenceException re) {                       
413                         }
414                         
415                 } catch (AccessorConstructionException e) {
416                         throw new ExportException(e);
417                 } catch (AccessorException e) {
418                         throw new ExportException(e);
419                 }
420         }
421
422         @Override
423         public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {
424         try {
425                         RecordAccessor ra = Accessors.getAccessor(options);                     
426                         String s;
427                         
428                         s = contentScopeNode.get(P_PDF_TITLE.tail().toString(), null);
429                         if ( s!=null ) ra.setValue(P_PDF_TITLE, Bindings.STRING, s);
430                 
431                         s = workbenchScopeNode.get(P_PDF_AUTHOR.tail().toString(), null);
432                         if ( s!=null ) ra.setValue(P_PDF_AUTHOR, Bindings.STRING, s);
433                 
434                         s = contentScopeNode.get(P_PDF_SUBJECT.tail().toString(), null);
435                         if ( s!=null ) ra.setValue(P_PDF_SUBJECT, Bindings.STRING, s);
436                 
437                         s = contentScopeNode.get(P_PDF_KEYWORDS.tail().toString(), null);
438                         if ( s!=null ) ra.setValue(P_PDF_KEYWORDS, Bindings.STRING, s);
439                 
440                         s = workbenchScopeNode.get(P_SIGN_KEYSTORE.tail().toString(), null);
441                         if ( s!=null ) ra.setValue(P_SIGN_KEYSTORE, Bindings.STRING, s);
442                 
443                         s = workbenchScopeNode.get(P_SIGN_KEYSTOREPASSWORD.tail().toString(), null);
444                         if ( s!=null ) ra.setValue(P_SIGN_KEYSTOREPASSWORD, Bindings.STRING, s);
445                 
446                         s = workbenchScopeNode.get(P_SIGN_PRIVATEKEYPASSWORD.tail().toString(), null);
447                         if ( s!=null ) ra.setValue(P_SIGN_PRIVATEKEYPASSWORD, Bindings.STRING, s);
448
449                         s = workbenchScopeNode.get(P_SIGN_LOCATION.tail().toString(), null);
450                         if ( s!=null ) ra.setValue(P_SIGN_LOCATION, Bindings.STRING, s);
451                         
452                         s = workbenchScopeNode.get(P_SIGN_REASON.tail().toString(), null);
453                         if ( s!=null ) ra.setValue(P_SIGN_REASON, Bindings.STRING, s);
454
455                         int tag = workbenchScopeNode.getInt(P_PDF_COMPRESSION.tail().toString(), -1);
456                         if ( tag>=0 )
457                 try {                   
458                         UnionAccessor ua = ra.getComponent(P_PDF_COMPRESSION);
459                         ua.setComponentValue(tag, Bindings.VOID, null);
460                 } catch (ReferenceException re) {                       
461                         }
462                 
463                 
464
465                         s = contentScopeNode.get(P_PAGE_MARGIN_LEFT.tail().toString(), null);
466                         if ( s!=null ) ra.setValue(P_PAGE_MARGIN_LEFT, Bindings.DOUBLE, Double.valueOf(s));
467                 
468                         s = contentScopeNode.get(P_PAGE_MARGIN_RIGHT.tail().toString(), null);
469                         if ( s!=null ) ra.setValue(P_PAGE_MARGIN_RIGHT, Bindings.DOUBLE, Double.valueOf(s));
470                 
471                         s = contentScopeNode.get(P_PAGE_MARGIN_TOP.tail().toString(), null);
472                         if ( s!=null ) ra.setValue(P_PAGE_MARGIN_TOP, Bindings.DOUBLE, Double.valueOf(s));
473                 
474                         s = contentScopeNode.get(P_PAGE_MARGIN_BOTTOM.tail().toString(), null);
475                         if ( s!=null ) ra.setValue(P_PAGE_MARGIN_BOTTOM, Bindings.DOUBLE, Double.valueOf(s));
476                         
477                         tag = contentScopeNode.getInt(P_PAGE_PAPERSIZE.tail().toString(), -1);
478                         if ( tag>=0 )
479                 try {                   
480                         UnionAccessor ua = ra.getComponent(P_PAGE_PAPERSIZE);
481                         ua.setComponentValue(tag, Bindings.VOID, null);
482                 } catch (ReferenceException re) {                       
483                         }
484                         
485                         tag = contentScopeNode.getInt(P_PAGE_ORIENTATION.tail().toString(), -1);
486                         if ( tag>=0 )
487                 try {                   
488                         UnionAccessor ua = ra.getComponent(P_PAGE_ORIENTATION);
489                         ua.setComponentValue(tag, Bindings.VOID, null);
490                 } catch (ReferenceException re) {                       
491                         }
492                 
493                 
494                 } catch (AccessorConstructionException e) {
495                         throw new ExportException(e);
496                 } catch (AccessorException e) {
497                         throw new ExportException(e);
498                 }
499         }
500
501         @Override
502         public void fillDefaultPrefs( ExportContext ctx, Variant options) throws ExportException {
503         try {
504                         RecordAccessor ra = Accessors.getAccessor(options);     
505
506                         Preferences instPrefs = InstanceScope.INSTANCE.getNode( PAGE_PLUGIN_ID );
507                         Preferences defaultPrefs = DefaultScope.INSTANCE.getNode( PAGE_PLUGIN_ID );
508                         
509                         String value = ExporterUtils.getPrefString(instPrefs, defaultPrefs, P_DEFAULT_PAGE_SIZE);
510                 if ( value != null ) {
511                         try {
512                     StringTokenizer tok = new StringTokenizer( value );
513                     String w = tok.nextToken().trim();
514                     String h = tok.nextToken().trim();
515                     String orientation = tok.nextToken().trim();
516                     if ( orientation!=null ) {
517                                 try {                                                           
518                                 UnionAccessor ua = ra.getComponent(P_PAGE_ORIENTATION);
519                                 int index = ua.type().getComponentIndex2(orientation);
520                                 if ( index<0 ) index = 1;
521                                 ua.setComponentValue(index, Bindings.VOID, new Object());
522                         } catch (ReferenceException re) {                                                                       
523                                 }
524                     }
525                     String centering = tok.nextToken().trim();
526                     String pagesize = tok.nextToken("\u0001").trim();
527                     ExporterUtils.setUnionValue(ra, P_PAGE_PAPERSIZE, pagesize);
528                     
529                     String margins = tok.nextToken().trim();                                
530                     if ( margins != null ) {
531                         String[] split = margins.split(";");
532                         if (split.length == 4) {
533                                 for (int i=0; i<4; i++) {
534                                         String[] tok2 = split[i].split(" ");
535                                         String controlRelative = tok2[0];
536                                         String controlAbsolute = tok2[1];
537                                         String diagramAbsolute = tok2[2];
538                                         
539                                         ChildReference ref = null;
540                                         switch (i) {
541                                                 case 0: ref = P_PAGE_MARGIN_TOP; break;
542                                                 case 1: ref = P_PAGE_MARGIN_BOTTOM; break;
543                                                 case 2: ref = P_PAGE_MARGIN_LEFT; break;
544                                                 case 3: ref = P_PAGE_MARGIN_RIGHT; break;
545                                         }
546                                         double margin_mm = Double.valueOf(diagramAbsolute);
547                                                 ra.setValue(ref, Bindings.DOUBLE, margin_mm);                                                           
548                                 }                                               
549                         }
550                     }
551                         } catch( Exception e ) {
552                                 // This is not so important that pdf export should fail.
553                                 e.printStackTrace();
554                         }
555
556                 }
557                         
558                 String username = System.getProperty("user.name");
559                 if ( username != null ) ra.setValue(P_PDF_AUTHOR, Bindings.STRING, username);
560
561                 ra.setValue(P_SIGN_REASON, Bindings.STRING, "Document Created");
562                 ExporterUtils.setUnionValue(ra, P_PDF_COMPRESSION, 9);          
563                 
564                 } catch (AccessorConstructionException e) {
565                         throw new ExportException(e);
566                 } catch (AccessorException e) {
567                         throw new ExportException(e);
568                 }
569         }       
570
571         public static String getCreator() {
572                 String creator = null;
573                 IProduct product = Platform.getProduct();
574                 if (product != null) {
575                         creator = product.getDescription();
576                         if (creator == null) {
577                                 creator = product.getName();
578                         }
579                 }
580                 if (creator == null) {
581                         creator = "Simantics";
582                 }
583                 return creator;
584         }
585
586         public static boolean isPdf(String filename) {
587                 return PATTERN_PDF.matcher(filename).matches();
588         }
589         
590         public static boolean isPdf(File file) {
591                 return PATTERN_PDF.matcher(file.getName()).matches();
592         }
593         
594 }