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