001    /**
002     * ========================================
003     * JFreeReport : a free Java report library
004     * ========================================
005     *
006     * Project Info:  http://reporting.pentaho.org/
007     *
008     * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009     *
010     * This library is free software; you can redistribute it and/or modify it under the terms
011     * of the GNU Lesser General Public License as published by the Free Software Foundation;
012     * either version 2.1 of the License, or (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016     * See the GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public License along with this
019     * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020     * Boston, MA 02111-1307, USA.
021     *
022     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023     * in the United States and other countries.]
024     *
025     * ------------
026     * $Id: PdfExportDialog.java 3516 2007-10-16 09:35:34Z tmorgner $
027     * ------------
028     * (C) Copyright 2000-2005, by Object Refinery Limited.
029     * (C) Copyright 2005-2007, by Pentaho Corporation.
030     */
031    
032    package org.jfree.report.modules.gui.swing.pdf;
033    
034    import java.awt.BorderLayout;
035    import java.awt.Dialog;
036    import java.awt.FlowLayout;
037    import java.awt.Frame;
038    import java.awt.GridBagConstraints;
039    import java.awt.GridBagLayout;
040    import java.awt.GridLayout;
041    import java.awt.Insets;
042    import java.awt.event.ActionEvent;
043    import java.awt.event.KeyEvent;
044    import java.io.File;
045    import java.text.MessageFormat;
046    import java.util.Locale;
047    import java.util.ResourceBundle;
048    import javax.swing.AbstractAction;
049    import javax.swing.Action;
050    import javax.swing.BorderFactory;
051    import javax.swing.ButtonGroup;
052    import javax.swing.DefaultComboBoxModel;
053    import javax.swing.JButton;
054    import javax.swing.JCheckBox;
055    import javax.swing.JComboBox;
056    import javax.swing.JComponent;
057    import javax.swing.JFileChooser;
058    import javax.swing.JLabel;
059    import javax.swing.JOptionPane;
060    import javax.swing.JPanel;
061    import javax.swing.JPasswordField;
062    import javax.swing.JRadioButton;
063    import javax.swing.JTabbedPane;
064    import javax.swing.JTextField;
065    import javax.swing.KeyStroke;
066    
067    import org.jfree.fonts.encoding.EncodingRegistry;
068    import org.jfree.layouting.modules.output.pdf.PdfOutputModule;
069    import org.jfree.report.flow.ReportJob;
070    import org.jfree.report.modules.gui.common.GuiContext;
071    import org.jfree.report.modules.gui.swing.common.AbstractExportDialog;
072    import org.jfree.report.modules.gui.swing.common.EncodingComboBoxModel;
073    import org.jfree.report.modules.gui.swing.common.JStatusBar;
074    import org.jfree.ui.FilesystemFilter;
075    import org.jfree.ui.action.ActionButton;
076    import org.jfree.util.Configuration;
077    import org.jfree.util.DefaultConfiguration;
078    import org.jfree.util.Log;
079    
080    /**
081     * Creation-Date: 02.12.2006, 15:27:30
082     *
083     * @author Thomas Morgner
084     */
085    public class PdfExportDialog extends AbstractExportDialog
086    {
087      /** Useful constant. */
088      private static final int CBMODEL_NOPRINTING = 0;
089    
090      /** Useful constant. */
091      private static final int CBMODEL_DEGRADED = 1;
092    
093      /** Useful constant. */
094      private static final int CBMODEL_FULL = 2;
095    
096      /**
097       * Internal action class to enable/disable the Security-Settings panel.
098       * Without encryption a pdf file cannot have any security settings enabled.
099       */
100      private class ActionSecuritySelection extends AbstractAction
101      {
102        /** Default constructor. */
103        protected ActionSecuritySelection()
104        {
105        }
106    
107        /**
108         * Receives notification that the action has occurred.
109         *
110         * @param e the action event.
111         */
112        public void actionPerformed(final ActionEvent e)
113        {
114          updateSecurityPanelEnabled();
115        }
116      }
117    
118      /** Internal action class to select a target file. */
119      private class ActionSelectFile extends AbstractAction
120      {
121        /** Default constructor. */
122        protected ActionSelectFile(final ResourceBundle resources)
123        {
124          putValue(Action.NAME, resources.getString("pdfsavedialog.selectFile"));
125        }
126    
127        /**
128         * Receives notification that the action has occurred.
129         *
130         * @param e the action event.
131         */
132        public void actionPerformed(final ActionEvent e)
133        {
134          performSelectFile();
135        }
136      }
137    
138      /** Security (none) radio button. */
139      private JRadioButton rbSecurityNone;
140    
141      /** Security (40 bit) radio button. */
142      private JRadioButton rbSecurity40Bit;
143    
144      /** Security (128 bit) radio button. */
145      private JRadioButton rbSecurity128Bit;
146    
147      /** User password text field. */
148      private JTextField txUserPassword;
149    
150      /** Owner password text field. */
151      private JTextField txOwnerPassword;
152    
153      /** Confirm user password text field. */
154      private JTextField txConfUserPassword;
155    
156      /** Confirm ownder password text field. */
157      private JTextField txConfOwnerPassword;
158    
159      /** Allow copy check box. */
160      private JCheckBox cxAllowCopy;
161    
162      /** Allow screen readers check box. */
163      private JCheckBox cxAllowScreenReaders;
164    
165      /** Allow printing check box. */
166      private JComboBox cbAllowPrinting;
167    
168      /** Allow assembly check box. */
169      private JCheckBox cxAllowAssembly;
170    
171      /** Allow modify contents check box. */
172      private JCheckBox cxAllowModifyContents;
173    
174      /** Allow modify annotations check box. */
175      private JCheckBox cxAllowModifyAnnotations;
176    
177      /** Allow fill in check box. */
178      private JCheckBox cxAllowFillIn;
179    
180      /** A model for the available encodings. */
181      private EncodingComboBoxModel encodingModel;
182    
183      /** A file chooser. */
184      private JFileChooser fileChooser;
185      private static final String PDF_FILE_EXTENSION = ".pdf";
186      private JStatusBar statusBar;
187      private JTextField txFilename;
188      private DefaultComboBoxModel printingModel;
189    
190      /**
191       * Creates a non-modal dialog without a title and without a specified
192       * <code>Frame</code> owner.  A shared, hidden frame will be set as the owner
193       * of the dialog.
194       */
195      public PdfExportDialog()
196      {
197        initializeComponents();
198      }
199    
200      /**
201       * Creates a non-modal dialog without a title with the specified
202       * <code>Frame</code> as its owner.  If <code>owner</code> is
203       * <code>null</code>, a shared, hidden frame will be set as the owner of the
204       * dialog.
205       *
206       * @param owner the <code>Frame</code> from which the dialog is displayed
207       */
208      public PdfExportDialog(final Frame owner)
209      {
210        super(owner);
211        initializeComponents();
212      }
213    
214      /**
215       * Creates a non-modal dialog without a title with the specified
216       * <code>Dialog</code> as its owner.
217       *
218       * @param owner the non-null <code>Dialog</code> from which the dialog is
219       *              displayed
220       */
221      public PdfExportDialog(final Dialog owner)
222      {
223        super(owner);
224        initializeComponents();
225      }
226    
227      private void initializeComponents ()
228      {
229        final JPanel mainPanel = new JPanel();
230        mainPanel.setLayout(new GridBagLayout());
231        mainPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
232    
233        final JLabel lblFileName = new JLabel(getResources().getString("pdfsavedialog.filename"));
234        final JLabel lblEncoding = new JLabel(getResources().getString("pdfsavedialog.encoding"));
235    
236        final JButton btnSelect = new ActionButton(new ActionSelectFile(getResources()));
237        txFilename = new JTextField();
238        statusBar = new JStatusBar();
239    
240        encodingModel = EncodingComboBoxModel.createDefaultModel(Locale.getDefault());
241        encodingModel.addEncodingUnchecked("Identity-H", "PDF-Unicode encoding");
242        encodingModel.addEncodingUnchecked("Identity-V", "PDF-Unicode encoding");
243        encodingModel.sort();
244    
245        final JComboBox cbEncoding = new JComboBox(encodingModel);
246    
247        GridBagConstraints gbc = new GridBagConstraints();
248        gbc.gridx = 0;
249        gbc.gridy = 0;
250        gbc.anchor = GridBagConstraints.WEST;
251        gbc.insets = new Insets(3, 1, 1, 1);
252        mainPanel.add(lblFileName, gbc);
253    
254        gbc = new GridBagConstraints();
255        gbc.fill = GridBagConstraints.HORIZONTAL;
256        gbc.weightx = 1;
257        gbc.gridx = 1;
258        gbc.gridy = 0;
259        gbc.ipadx = 120;
260        gbc.insets = new Insets(3, 1, 1, 1);
261        mainPanel.add(txFilename, gbc);
262    
263        gbc = new GridBagConstraints();
264        gbc.anchor = GridBagConstraints.NORTHWEST;
265        gbc.gridx = 2;
266        gbc.gridy = 0;
267        mainPanel.add(btnSelect, gbc);
268    
269        gbc = new GridBagConstraints();
270        gbc.anchor = GridBagConstraints.WEST;
271        gbc.gridx = 0;
272        gbc.gridy = 1;
273        gbc.insets = new Insets(1, 1, 1, 1);
274        mainPanel.add(lblEncoding, gbc);
275    
276        gbc = new GridBagConstraints();
277        gbc.fill = GridBagConstraints.HORIZONTAL;
278        gbc.weightx = 1;
279        gbc.gridx = 1;
280        gbc.gridy = 1;
281        gbc.ipadx = 120;
282        gbc.insets = new Insets(1, 1, 1, 1);
283        mainPanel.add(cbEncoding, gbc);
284    
285        final JButton btnCancel = new ActionButton(getCancelAction());
286        final JButton btnConfirm = new ActionButton(getConfirmAction());
287        final JPanel buttonPanel = new JPanel();
288        buttonPanel.setLayout(new GridLayout(1, 2, 5, 5));
289        buttonPanel.add(btnConfirm);
290        buttonPanel.add(btnCancel);
291        btnConfirm.setDefaultCapable(true);
292        getRootPane().setDefaultButton(btnConfirm);
293        buttonPanel.registerKeyboardAction(getConfirmAction(),
294                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
295                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
296    
297        final JPanel buttonCarrier = new JPanel();
298        buttonCarrier.setLayout(new FlowLayout(FlowLayout.RIGHT));
299        buttonCarrier.add(buttonPanel);
300    
301        gbc = new GridBagConstraints();
302        gbc.fill = GridBagConstraints.NONE;
303        gbc.anchor = GridBagConstraints.EAST;
304        gbc.weightx = 1;
305        gbc.gridx = 0;
306        gbc.gridwidth = 3;
307        gbc.gridy = 6;
308        gbc.insets = new Insets(10, 0, 0, 0);
309    
310        final JPanel mainPaneCarrier = new JPanel();
311        mainPaneCarrier.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
312        mainPaneCarrier.setLayout(new BorderLayout());
313        mainPaneCarrier.add(mainPanel, BorderLayout.NORTH);
314    
315        final JPanel securityPaneCarrier = new JPanel();
316        securityPaneCarrier.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
317        securityPaneCarrier.setLayout(new BorderLayout());
318        securityPaneCarrier.add(createSecurityPanel(), BorderLayout.NORTH);
319    
320        final JTabbedPane tabbedPane = new JTabbedPane();
321        tabbedPane.add("Export-Settings", mainPaneCarrier);
322        tabbedPane.add("Security", securityPaneCarrier);
323    
324        final JPanel contentPane = new JPanel();
325        contentPane.setLayout(new BorderLayout());
326        contentPane.add(tabbedPane, BorderLayout.CENTER);
327        contentPane.add(buttonCarrier, BorderLayout.SOUTH);
328    
329        final JPanel contentWithStatus = new JPanel();
330        contentWithStatus.setLayout(new BorderLayout());
331        contentWithStatus.add(contentPane, BorderLayout.CENTER);
332        contentWithStatus.add(getStatusBar(), BorderLayout.SOUTH);
333    
334        setContentPane(contentWithStatus);
335    
336        getFormValidator().registerTextField(txFilename);
337        getFormValidator().registerTextField(txConfOwnerPassword);
338        getFormValidator().registerTextField(txConfUserPassword);
339        getFormValidator().registerTextField(txUserPassword);
340        getFormValidator().registerTextField(txOwnerPassword);
341    
342      }
343    
344    
345      public JStatusBar getStatusBar()
346      {
347        return statusBar;
348      }
349    
350      protected boolean performConfirm()
351      {
352        final String filename = txFilename.getText();
353        final File f = new File(filename);
354        if (f.exists())
355        {
356          final String key1 = "pdfsavedialog.targetOverwriteConfirmation";
357          final String key2 = "pdfsavedialog.targetOverwriteTitle";
358          if (JOptionPane.showConfirmDialog(this,
359                  MessageFormat.format(getResources().getString(key1),
360                          new Object[]{txFilename.getText()}),
361                  getResources().getString(key2),
362                  JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
363                  == JOptionPane.NO_OPTION)
364          {
365            return false;
366          }
367        }
368    
369        if (getEncryptionValue().equals(PdfOutputModule.SECURITY_ENCRYPTION_128BIT)
370                || getEncryptionValue().equals(
371                PdfOutputModule.SECURITY_ENCRYPTION_40BIT))
372        {
373          if (txOwnerPassword.getText().trim().length() == 0)
374          {
375            if (JOptionPane.showConfirmDialog(this,
376                    getResources().getString("pdfsavedialog.ownerpasswordEmpty"),
377                    getResources().getString("pdfsavedialog.warningTitle"),
378                    JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE)
379                    == JOptionPane.NO_OPTION)
380            {
381              return false;
382            }
383          }
384        }
385        return true;
386      }
387    
388      protected boolean performValidate()
389      {
390        getStatusBar().clear();
391    
392        final String filename = txFilename.getText();
393        if (filename.trim().length() == 0)
394        {
395          getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
396                  getResources().getString("pdfsavedialog.targetIsEmpty"));
397          return false;
398        }
399        final File f = new File(filename);
400        if (f.exists())
401        {
402          if (f.isFile() == false)
403          {
404            getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
405                    getResources().getString("pdfsavedialog.targetIsNoFile"));
406            return false;
407          }
408          if (f.canWrite() == false)
409          {
410            getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
411                    getResources().getString("pdfsavedialog.targetIsNotWritable"));
412            return false;
413          }
414    
415          final String message = MessageFormat.format(getResources().getString
416                  ("pdfsavedialog.targetOverwriteWarning"),
417                  new Object[]{filename});
418          getStatusBar().setStatus(JStatusBar.TYPE_WARNING, message);
419        }
420    
421        if (getEncryptionValue().equals(PdfOutputModule.SECURITY_ENCRYPTION_128BIT)
422                || getEncryptionValue().equals(
423                PdfOutputModule.SECURITY_ENCRYPTION_40BIT))
424        {
425          if (txUserPassword.getText().equals(
426                  txConfUserPassword.getText()) == false)
427          {
428            getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
429                    getResources().getString("pdfsavedialog.userpasswordNoMatch"));
430            return false;
431          }
432          if (txOwnerPassword.getText().equals(
433                  txConfOwnerPassword.getText()) == false)
434          {
435            getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
436                    getResources().getString("pdfsavedialog.ownerpasswordNoMatch"));
437            return false;
438          }
439        }
440    
441        return true;
442      }
443    
444      protected void initializeFromJob(final ReportJob job, final GuiContext guiContext)
445      {
446        statusBar.setIconTheme(guiContext.getIconTheme());
447    
448    //    encodingModel = EncodingComboBoxModel.createDefaultModel(Locale.getDefault());
449    //    encodingModel.addEncodingUnchecked("Identity-H", "PDF-Unicode encoding");
450    //    encodingModel.addEncodingUnchecked("Identity-V", "PDF-Unicode encoding");
451    //    encodingModel.sort();
452    //    cbEncoding.setModel(encodingModel);
453      }
454    
455      protected String getConfigurationPrefix()
456      {
457        return "org.jfree.report.modules.gui.common.pdf.";
458      }
459    
460      /**
461       * Returns a new (and not connected to the default config from the job)
462       * configuration containing all properties from the dialog.
463       *
464       * @param full
465       */
466      protected Configuration grabDialogContents(final boolean full)
467      {
468        final DefaultConfiguration config = new DefaultConfiguration();
469    
470        final String prefix = getConfigurationPrefix();
471        config.setConfigProperty(prefix + "TargetFileName", txFilename.getText());
472        config.setConfigProperty(prefix + "Encoding", encodingModel.getSelectedEncoding());
473        config.getConfigProperty(prefix + "security.PrintLevel", getPrintLevel());
474        config.getConfigProperty(prefix + "security.Encryption", getEncryptionValue());
475    
476    
477        config.getConfigProperty(prefix + "security.UserPassword", txUserPassword.getText());
478        config.getConfigProperty(prefix + "security.OwnerPassword", txOwnerPassword.getText());
479    
480        config.setConfigProperty(prefix + "security.AllowAssembly",
481            String.valueOf(cxAllowAssembly.isSelected()));
482        config.setConfigProperty(prefix + "security.AllowCopy",
483            String.valueOf(cxAllowCopy.isSelected()));
484        config.setConfigProperty(prefix + "security.AllowFillIn",
485            String.valueOf(cxAllowFillIn.isSelected()));
486        config.setConfigProperty(prefix + "security.AllowModifyAnnotations",
487            String.valueOf(cxAllowModifyAnnotations.isSelected()));
488        config.setConfigProperty(prefix + "security.AllowModifyContents",
489            String.valueOf(cxAllowModifyContents.isSelected()));
490        config.setConfigProperty(prefix + "security.AllowScreenReaders",
491            String.valueOf(cxAllowScreenReaders.isSelected()));
492        return config;
493      }
494    
495      protected void setDialogContents(final Configuration config)
496      {
497        final String prefix = getConfigurationPrefix();
498        txFilename.setText(config.getConfigProperty(prefix + "TargetFileName"));
499        final String encoding = config.getConfigProperty(prefix + "Encoding");
500        if (encoding != null && encoding.length() > 0)
501        {
502          encodingModel.setSelectedEncoding(encoding);
503        }
504        setPrintLevel(config.getConfigProperty(prefix + "security.PrintLevel"));
505        setEncryptionValue(config.getConfigProperty(prefix + "security.Encryption"));
506    
507        txUserPassword.setText(config.getConfigProperty(prefix + "security.UserPassword"));
508        txOwnerPassword.setText(config.getConfigProperty(prefix + "security.OwnerPassword"));
509        txConfUserPassword.setText(config.getConfigProperty(prefix + "security.UserPassword"));
510        txConfOwnerPassword.setText(config.getConfigProperty(prefix + "security.OwnerPassword"));
511    
512        cxAllowAssembly.setSelected("true".equals
513            (config.getConfigProperty(prefix + "security.AllowAssembly")));
514        cxAllowCopy.setSelected("true".equals
515            (config.getConfigProperty(prefix + "security.AllowCopy")));
516        cxAllowFillIn.setSelected("true".equals
517            (config.getConfigProperty(prefix + "security.AllowFillIn")));
518        cxAllowModifyAnnotations.setSelected("true".equals
519            (config.getConfigProperty(prefix + "security.AllowModifyAnnotations")));
520        cxAllowModifyContents.setSelected("true".equals
521            (config.getConfigProperty(prefix + "security.AllowModifyContents")));
522        cxAllowScreenReaders.setSelected("true".equals
523            (config.getConfigProperty(prefix + "security.AllowScreenReaders")));
524      }
525    
526      protected String getConfigurationSuffix()
527      {
528        return "_pdf_export";
529      }
530    
531      public void clear()
532      {
533        txConfOwnerPassword.setText("");
534        txConfUserPassword.setText("");
535        txFilename.setText("");
536        txOwnerPassword.setText("");
537        txUserPassword.setText("");
538    
539        cxAllowAssembly.setSelected(false);
540        cxAllowCopy.setSelected(false);
541        cbAllowPrinting.setSelectedIndex(CBMODEL_NOPRINTING);
542        cxAllowFillIn.setSelected(false);
543        cxAllowModifyAnnotations.setSelected(false);
544        cxAllowModifyContents.setSelected(false);
545        cxAllowScreenReaders.setSelected(false);
546    
547        rbSecurityNone.setSelected(true);
548        updateSecurityPanelEnabled();
549    
550        final String plattformDefaultEncoding = EncodingRegistry.getPlatformDefaultEncoding();
551        encodingModel.setSelectedEncoding(plattformDefaultEncoding);
552      }
553    
554      protected String getResourceBaseName()
555      {
556        return SwingPdfModule.BUNDLE_NAME;
557      }
558    
559    
560      /**
561       * Updates the security panel state. If no encryption is selected, all
562       * security setting components will be disabled.
563       */
564      protected void updateSecurityPanelEnabled()
565      {
566        final boolean b = (rbSecurityNone.isSelected() == false);
567        txUserPassword.setEnabled(b);
568        txOwnerPassword.setEnabled(b);
569        txConfOwnerPassword.setEnabled(b);
570        txConfUserPassword.setEnabled(b);
571        cxAllowAssembly.setEnabled(b);
572        cxAllowCopy.setEnabled(b);
573        cbAllowPrinting.setEnabled(b);
574        cxAllowFillIn.setEnabled(b);
575        cxAllowModifyAnnotations.setEnabled(b);
576        cxAllowModifyContents.setEnabled(b);
577        cxAllowScreenReaders.setEnabled(b);
578      }
579    
580      /** Initializes the class member components of the security panel. */
581      private void createSecurityPanelComponents()
582      {
583        txUserPassword = new JPasswordField();
584        txConfUserPassword = new JPasswordField();
585        txOwnerPassword = new JPasswordField();
586        txConfOwnerPassword = new JPasswordField();
587    
588        cxAllowCopy = new JCheckBox(getResources().getString(
589                "pdfsavedialog.allowCopy"));
590        cbAllowPrinting = new JComboBox(getPrintingComboBoxModel());
591        cxAllowScreenReaders =
592                new JCheckBox(getResources().getString(
593                        "pdfsavedialog.allowScreenreader"));
594    
595        cxAllowAssembly = new JCheckBox(getResources().getString(
596                "pdfsavedialog.allowAssembly"));
597        cxAllowModifyContents =
598                new JCheckBox(getResources().getString(
599                        "pdfsavedialog.allowModifyContents"));
600        cxAllowModifyAnnotations =
601                new JCheckBox(getResources().getString(
602                        "pdfsavedialog.allowModifyAnnotations"));
603        cxAllowFillIn = new JCheckBox(getResources().getString(
604                "pdfsavedialog.allowFillIn"));
605    
606      }
607    
608      /**
609       * Creates a panel for the security settings.
610       *
611       * @return The panel.
612       */
613      private JPanel createSecurityPanel()
614      {
615        final JPanel securityPanel = new JPanel();
616        securityPanel.setLayout(new GridBagLayout());
617    
618        createSecurityPanelComponents();
619    
620        final JLabel lblUserPass = new JLabel(getResources().getString(
621                "pdfsavedialog.userpassword"));
622        final JLabel lblUserPassConfirm =
623                new JLabel(getResources().getString(
624                        "pdfsavedialog.userpasswordconfirm"));
625        final JLabel lblOwnerPass =
626                new JLabel(getResources().getString("pdfsavedialog.ownerpassword"));
627        final JLabel lblOwnerPassConfirm =
628                new JLabel(getResources().getString(
629                        "pdfsavedialog.ownerpasswordconfirm"));
630        final JLabel lbAllowPrinting =
631                new JLabel(getResources().getString("pdfsavedialog.allowPrinting"));
632    
633        GridBagConstraints gbc = new GridBagConstraints();
634        gbc.fill = GridBagConstraints.HORIZONTAL;
635        gbc.weightx = 1;
636        gbc.gridx = 0;
637        gbc.gridwidth = 4;
638        gbc.gridy = 0;
639        gbc.insets = new Insets(5, 5, 5, 5);
640        securityPanel.add(createSecurityConfigPanel(), gbc);
641    
642        gbc = new GridBagConstraints();
643        gbc.anchor = GridBagConstraints.WEST;
644        gbc.gridx = 0;
645        gbc.gridy = 1;
646        gbc.insets = new Insets(5, 5, 5, 5);
647        securityPanel.add(lblUserPass, gbc);
648    
649        gbc = new GridBagConstraints();
650        gbc.fill = GridBagConstraints.HORIZONTAL;
651        gbc.weightx = 1;
652        gbc.gridx = 1;
653        gbc.gridy = 1;
654        gbc.ipadx = 120;
655        gbc.insets = new Insets(5, 5, 5, 5);
656        securityPanel.add(txUserPassword, gbc);
657    
658        gbc = new GridBagConstraints();
659        gbc.anchor = GridBagConstraints.WEST;
660        gbc.gridx = 0;
661        gbc.gridy = 2;
662        gbc.insets = new Insets(5, 5, 5, 5);
663        securityPanel.add(lblOwnerPass, gbc);
664    
665        gbc = new GridBagConstraints();
666        gbc.fill = GridBagConstraints.HORIZONTAL;
667        gbc.weightx = 1;
668        gbc.gridx = 1;
669        gbc.gridy = 2;
670        gbc.ipadx = 120;
671        gbc.insets = new Insets(5, 5, 5, 5);
672        securityPanel.add(txOwnerPassword, gbc);
673    
674        gbc = new GridBagConstraints();
675        gbc.anchor = GridBagConstraints.WEST;
676        gbc.gridx = 2;
677        gbc.gridy = 1;
678        gbc.insets = new Insets(5, 5, 5, 5);
679        securityPanel.add(lblUserPassConfirm, gbc);
680    
681        gbc = new GridBagConstraints();
682        gbc.fill = GridBagConstraints.HORIZONTAL;
683        gbc.weightx = 1;
684        gbc.gridx = 3;
685        gbc.gridy = 1;
686        gbc.ipadx = 120;
687        gbc.insets = new Insets(5, 5, 5, 5);
688        securityPanel.add(txConfUserPassword, gbc);
689    
690        gbc = new GridBagConstraints();
691        gbc.anchor = GridBagConstraints.WEST;
692        gbc.gridx = 2;
693        gbc.gridy = 2;
694        gbc.insets = new Insets(5, 5, 5, 5);
695        securityPanel.add(lblOwnerPassConfirm, gbc);
696    
697        gbc = new GridBagConstraints();
698        gbc.fill = GridBagConstraints.HORIZONTAL;
699        gbc.weightx = 1;
700        gbc.gridx = 3;
701        gbc.gridy = 2;
702        gbc.ipadx = 120;
703        gbc.insets = new Insets(5, 5, 5, 5);
704        securityPanel.add(txConfOwnerPassword, gbc);
705    
706        gbc = new GridBagConstraints();
707        gbc.gridx = 0;
708        gbc.gridwidth = 2;
709        gbc.gridy = 3;
710        gbc.anchor = GridBagConstraints.WEST;
711        securityPanel.add(cxAllowCopy, gbc);
712    
713        gbc = new GridBagConstraints();
714        gbc.gridx = 0;
715        gbc.gridwidth = 2;
716        gbc.gridy = 4;
717        gbc.anchor = GridBagConstraints.WEST;
718        securityPanel.add(cxAllowScreenReaders, gbc);
719    
720        gbc = new GridBagConstraints();
721        gbc.gridx = 0;
722        gbc.gridwidth = 2;
723        gbc.gridy = 5;
724        gbc.anchor = GridBagConstraints.WEST;
725        securityPanel.add(cxAllowFillIn, gbc);
726    
727        gbc = new GridBagConstraints();
728        gbc.gridx = 2;
729        gbc.gridwidth = 2;
730        gbc.gridy = 3;
731        gbc.anchor = GridBagConstraints.WEST;
732        securityPanel.add(cxAllowAssembly, gbc);
733    
734        gbc = new GridBagConstraints();
735        gbc.gridx = 2;
736        gbc.gridwidth = 2;
737        gbc.gridy = 4;
738        gbc.anchor = GridBagConstraints.WEST;
739        securityPanel.add(cxAllowModifyContents, gbc);
740    
741        gbc = new GridBagConstraints();
742        gbc.gridx = 2;
743        gbc.gridwidth = 2;
744        gbc.gridy = 5;
745        gbc.anchor = GridBagConstraints.WEST;
746        securityPanel.add(cxAllowModifyAnnotations, gbc);
747    
748        gbc = new GridBagConstraints();
749        gbc.gridx = 0;
750        gbc.gridwidth = 1;
751        gbc.gridy = 6;
752        gbc.anchor = GridBagConstraints.WEST;
753        securityPanel.add(lbAllowPrinting, gbc);
754    
755        gbc = new GridBagConstraints();
756        gbc.gridx = 1;
757        gbc.gridwidth = 3;
758        gbc.gridy = 6;
759        gbc.anchor = GridBagConstraints.WEST;
760        securityPanel.add(cbAllowPrinting, gbc);
761    
762        return securityPanel;
763      }
764    
765      /**
766       * Creates the security config panel. This panel is used to select the level
767       * of the PDF security.
768       *
769       * @return the created security config panel.
770       */
771      private JPanel createSecurityConfigPanel()
772      {
773        rbSecurityNone = new JRadioButton(getResources().getString(
774                "pdfsavedialog.securityNone"));
775        rbSecurity40Bit = new JRadioButton(getResources().getString(
776                "pdfsavedialog.security40bit"));
777        rbSecurity128Bit = new JRadioButton(getResources().getString(
778                "pdfsavedialog.security128bit"));
779    
780        final Action securitySelectAction = new ActionSecuritySelection();
781        rbSecurityNone.addActionListener(securitySelectAction);
782        rbSecurity40Bit.addActionListener(securitySelectAction);
783        rbSecurity128Bit.addActionListener(securitySelectAction);
784    
785        rbSecurity128Bit.setSelected(true);
786    
787        final JPanel pnlSecurityConfig = new JPanel();
788        pnlSecurityConfig.setLayout(new GridLayout());
789        pnlSecurityConfig.add(rbSecurityNone);
790        pnlSecurityConfig.add(rbSecurity40Bit);
791        pnlSecurityConfig.add(rbSecurity128Bit);
792    
793        final ButtonGroup btGrpSecurity = new ButtonGroup();
794        btGrpSecurity.add(rbSecurity128Bit);
795        btGrpSecurity.add(rbSecurity40Bit);
796        btGrpSecurity.add(rbSecurityNone);
797    
798        return pnlSecurityConfig;
799      }
800    
801      /**
802       * Gets and initializes the the combobox model for the security setting
803       * "allowPrinting".
804       *
805       * @return the combobox model containing the different values for the
806       *         allowPrinting option.
807       */
808      private DefaultComboBoxModel getPrintingComboBoxModel()
809      {
810        if (printingModel == null)
811        {
812          final Object[] data = {
813                  getResources().getString("pdfsavedialog.option.noprinting"),
814                  getResources().getString("pdfsavedialog.option.degradedprinting"),
815                  getResources().getString("pdfsavedialog.option.fullprinting")
816          };
817          printingModel = new DefaultComboBoxModel(data);
818        }
819        return printingModel;
820      }
821    
822    
823      /** selects a file to use as target for the report processing. */
824      protected void performSelectFile()
825      {
826        // lazy initialize ... the file chooser is one of the hot spots here ...
827        if (fileChooser == null)
828        {
829          fileChooser = new JFileChooser();
830          final FilesystemFilter filter = new FilesystemFilter(PDF_FILE_EXTENSION,
831                  "PDF Documents");
832          fileChooser.addChoosableFileFilter(filter);
833          fileChooser.setMultiSelectionEnabled(false);
834        }
835    
836        final File file = new File(txFilename.getText());
837        fileChooser.setCurrentDirectory(file);
838        fileChooser.setSelectedFile(file);
839        final int option = fileChooser.showSaveDialog(this);
840        if (option == JFileChooser.APPROVE_OPTION)
841        {
842          final File selFile = fileChooser.getSelectedFile();
843          String selFileName = selFile.getAbsolutePath();
844    
845          // Test if ends of pdf
846          if (selFileName.toLowerCase().endsWith(PDF_FILE_EXTENSION) == false)
847          {
848            selFileName = selFileName + PDF_FILE_EXTENSION;
849          }
850          txFilename.setText(selFileName);
851        }
852      }
853    
854      /**
855       * Defines whether the user is allowed to print the file.  If this right is
856       * granted, the user is also able to print a degraded version of the file,
857       * regardless of the <code>allowDegradedPrinting</code< property. If you
858       * disabled printing but enabled degraded printing, then the user is able to
859       * print a low-quality version of the document.
860       *
861       */
862      public void setPrintLevel(final String printLevel)
863      {
864        if ("full".equals(printLevel))
865        {
866          this.cbAllowPrinting.setSelectedIndex(CBMODEL_FULL);
867        }
868        else if ("degraded".equals(printLevel))
869        {
870            this.cbAllowPrinting.setSelectedIndex(CBMODEL_DEGRADED);
871        }
872        else
873        {
874          this.cbAllowPrinting.setSelectedIndex(CBMODEL_NOPRINTING);
875        }
876      }
877    
878      public String getPrintLevel ()
879      {
880        if (cbAllowPrinting.getSelectedIndex() == CBMODEL_FULL)
881        {
882          return "full";
883        }
884        if (cbAllowPrinting.getSelectedIndex() == CBMODEL_DEGRADED)
885        {
886          return "degraded";
887        }
888        return "none";
889      }
890    
891    
892      /**
893       * Queries the currently selected encryption. If an encryption is selected
894       * this method returns either Boolean.TRUE or Boolean.FALSE, when no
895       * encryption is set, <code>null</code> is returned. If no encryption is set,
896       * the security properties have no defined state.
897       *
898       * @return the selection state for the encryption. If no encryption is set,
899       *         this method returns null, if 40-bit encryption is set, the method
900       *         returns Boolean.FALSE and on 128-Bit-encryption, Boolean.TRUE is
901       *         returned.
902       */
903      public String getEncryptionValue()
904      {
905        if (rbSecurity40Bit.isSelected())
906        {
907          return PdfOutputModule.SECURITY_ENCRYPTION_40BIT;
908        }
909        if (rbSecurity128Bit.isSelected())
910        {
911          return PdfOutputModule.SECURITY_ENCRYPTION_128BIT;
912        }
913        return PdfOutputModule.SECURITY_ENCRYPTION_NONE;
914      }
915    
916      /**
917       * Defines the currently selected encryption.
918       *
919       * @param b the new encryption state, one of null, Boolean.TRUE or
920       *          Boolean.FALSE
921       */
922      public void setEncryptionValue(final String b)
923      {
924        if (b != null)
925        {
926          if (b.equals(PdfOutputModule.SECURITY_ENCRYPTION_128BIT))
927          {
928            rbSecurity128Bit.setSelected(true);
929            updateSecurityPanelEnabled();
930            return;
931          }
932          else if (b.equals(PdfOutputModule.SECURITY_ENCRYPTION_40BIT))
933          {
934            rbSecurity40Bit.setSelected(true);
935            updateSecurityPanelEnabled();
936            return;
937          }
938          else if (b.equals(PdfOutputModule.SECURITY_ENCRYPTION_NONE) == false)
939          {
940            Log.warn("Invalid encryption value entered. " + b);
941          }
942        }
943        rbSecurityNone.setSelected(true);
944        updateSecurityPanelEnabled();
945      }
946    }