* added a first PDF Exporter (menu File->Export...)
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.wiki / src / net / sourceforge / phpeclipse / wiki / export / pdf / WikiPDFExportWizardPage.java
1 /*
2  * Copyright (c) 2002 Team in a Box Ltd. All rights reserved. This file is made available under the terms and conditions of the
3  * Common Public License v 1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/cpl-v1.0.html
4  * 
5  * Contributors: Team in a Box Ltd http://www.teaminabox.co.uk/
6  */
7
8 package net.sourceforge.phpeclipse.wiki.export.pdf;
9
10 import java.lang.reflect.InvocationTargetException;
11 import java.util.List;
12
13 import net.sourceforge.phpeclipse.wiki.editor.WikiEditorPlugin;
14
15 import org.eclipse.core.resources.IContainer;
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.resources.IFolder;
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.resources.ResourcesPlugin;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IPath;
23 import org.eclipse.core.runtime.IStatus;
24 import org.eclipse.core.runtime.Path;
25 import org.eclipse.jface.dialogs.ErrorDialog;
26 import org.eclipse.jface.dialogs.IDialogSettings;
27 import org.eclipse.jface.dialogs.MessageDialog;
28 import org.eclipse.jface.operation.IRunnableWithProgress;
29 import org.eclipse.jface.preference.StringFieldEditor;
30 import org.eclipse.jface.util.IPropertyChangeListener;
31 import org.eclipse.jface.util.PropertyChangeEvent;
32 import org.eclipse.jface.viewers.ISelection;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.jface.window.Window;
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.events.SelectionListener;
38 import org.eclipse.swt.graphics.Font;
39 import org.eclipse.swt.layout.GridData;
40 import org.eclipse.swt.layout.GridLayout;
41 import org.eclipse.swt.widgets.Button;
42 import org.eclipse.swt.widgets.Combo;
43 import org.eclipse.swt.widgets.Composite;
44 import org.eclipse.swt.widgets.DirectoryDialog;
45 import org.eclipse.swt.widgets.Event;
46 import org.eclipse.swt.widgets.FileDialog;
47 import org.eclipse.swt.widgets.Group;
48 import org.eclipse.swt.widgets.Label;
49 import org.eclipse.swt.widgets.Widget;
50 import org.eclipse.ui.dialogs.ContainerSelectionDialog;
51 import org.eclipse.ui.dialogs.WizardExportResourcesPage;
52 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
53
54 public final class WikiPDFExportWizardPage extends WizardExportResourcesPage implements IPropertyChangeListener, SelectionListener {
55   private StringFieldEditor folderText;
56
57   private static final String[] PDF_EXTENSION = { "pdf" };
58
59   //dialog store id constants
60   private static final String STORE_DESTINATION_NAMES_ID = "WikiPDFExportWizardPage.STORE_DESTINATION_NAMES_ID"; //$NON-NLS-1$
61
62   private static final String STORE_OVERWRITE_EXISTING_FILES_ID = "WikiPDFExportWizardPage.STORE_OVERWRITE_EXISTING_FILES_ID"; //$NON-NLS-1$
63
64   private StringFieldEditor exportFileText;
65
66   private Combo destinationNameField;
67
68   private Button destinationBrowseButton;
69
70   protected Button overwriteExistingFilesCheckbox;
71
72   private ISelection selection;
73
74   public WikiPDFExportWizardPage(IStructuredSelection selection) {
75     super(WikiEditorPlugin.getResourceString("Export.wizardTitle"), selection);
76     setTitle(WikiEditorPlugin.getResourceString("Export.wizardTitle"));
77     setDescription(WikiEditorPlugin.getResourceString("Export.wizardDescription"));
78     this.selection = selection;
79   }
80
81   /**
82    * Create the export destination specification widgets
83    * 
84    * @param parent
85    *          org.eclipse.swt.widgets.Composite
86    */
87   protected void createDestinationGroup(Composite parent) {
88
89     Font font = parent.getFont();
90     // destination specification group
91     Composite destinationSelectionGroup = new Composite(parent, SWT.NONE);
92     GridLayout layout = new GridLayout();
93     layout.numColumns = 3;
94     destinationSelectionGroup.setLayout(layout);
95     destinationSelectionGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
96     destinationSelectionGroup.setFont(font);
97
98     Label destinationLabel = new Label(destinationSelectionGroup, SWT.NONE);
99     destinationLabel.setText("PDF output filename:");
100     destinationLabel.setFont(font);
101
102     // destination name entry field
103     destinationNameField = new Combo(destinationSelectionGroup, SWT.SINGLE | SWT.BORDER);
104     destinationNameField.addListener(SWT.Modify, this);
105     destinationNameField.addListener(SWT.Selection, this);
106     GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
107     data.widthHint = SIZING_TEXT_FIELD_WIDTH;
108     destinationNameField.setLayoutData(data);
109     destinationNameField.setFont(font);
110
111     // destination browse button
112     destinationBrowseButton = new Button(destinationSelectionGroup, SWT.PUSH);
113     destinationBrowseButton.setText("Browse..."); //$NON-NLS-1$
114     destinationBrowseButton.addListener(SWT.Selection, this);
115     destinationBrowseButton.setFont(font);
116     setButtonLayoutData(destinationBrowseButton);
117
118     new Label(parent, SWT.NONE); // vertical spacer
119   }
120   /**
121          *      Create the options specification widgets.
122          *
123          *      @param parent org.eclipse.swt.widgets.Composite
124          */
125         protected void createOptionsGroup(Composite parent) {
126                 // options group
127                 Group optionsGroup = new Group(parent, SWT.NONE);
128                 GridLayout layout = new GridLayout();
129                 optionsGroup.setLayout(layout);
130                 optionsGroup.setLayoutData(
131                         new GridData(
132                                 GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
133                 optionsGroup.setText(IDEWorkbenchMessages.getString("WizardExportPage.options")); //$NON-NLS-1$
134                 optionsGroup.setFont(parent.getFont());
135
136                 createOptionsGroupButtons(optionsGroup);
137
138         }
139   /**
140          * Create the buttons in the options group.
141          */
142
143         protected void createOptionsGroupButtons(Group optionsGroup) {
144
145                 Font font = optionsGroup.getFont();
146                 createOverwriteExisting(optionsGroup, font);
147
148 //              createDirectoryStructureOptions(optionsGroup, font);
149         }
150   /**
151    * Create the button for checking if we should ask if we are going to overwrite existing files.
152    * 
153    * @param optionsGroup
154    * @param font
155    */
156   protected void createOverwriteExisting(Group optionsGroup, Font font) {
157     // overwrite... checkbox
158     overwriteExistingFilesCheckbox = new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
159     overwriteExistingFilesCheckbox.setText("Overwrite existing files"); //$NON-NLS-1$
160     overwriteExistingFilesCheckbox.setFont(font);
161   }
162
163   /**
164    * Handle all events and enablements for widgets in this page
165    * 
166    * @param e
167    *          Event
168    */
169   public void handleEvent(Event e) {
170     Widget source = e.widget;
171
172     if (source == destinationBrowseButton)
173       handleDestinationBrowseButtonPressed();
174
175     updatePageCompletion();
176   }
177
178   /**
179    * Open an appropriate destination browser so that the user can specify a source to import from
180    */
181   protected void handleDestinationBrowseButtonPressed() {
182     DirectoryDialog dialog = new DirectoryDialog(getContainer().getShell(), SWT.SAVE);
183     dialog.setMessage("Select destination");
184     dialog.setText("Select title");
185     dialog.setFilterPath(getDestinationValue());
186     String selectedDirectoryName = dialog.open();
187
188     if (selectedDirectoryName != null) {
189       setErrorMessage(null);
190       setDestinationValue(selectedDirectoryName);
191     }
192   }
193
194   /**
195    * Answer the contents of self's destination specification widget
196    * 
197    * @return java.lang.String
198    */
199   protected String getDestinationValue() {
200     return destinationNameField.getText().trim();
201   }
202
203   /**
204    * Set the contents of the receivers destination specification widget to the passed value
205    *  
206    */
207   protected void setDestinationValue(String value) {
208     destinationNameField.setText(value);
209   }
210
211   /**
212    * Hook method for saving widget values for restoration by the next instance of this class.
213    */
214   protected void internalSaveWidgetValues() {
215     // update directory names history
216     IDialogSettings settings = getDialogSettings();
217     if (settings != null) {
218       String[] directoryNames = settings.getArray(STORE_DESTINATION_NAMES_ID);
219       if (directoryNames == null)
220         directoryNames = new String[0];
221
222       directoryNames = addToHistory(directoryNames, getDestinationValue());
223       settings.put(STORE_DESTINATION_NAMES_ID, directoryNames);
224
225       // options
226       settings.put(STORE_OVERWRITE_EXISTING_FILES_ID, overwriteExistingFilesCheckbox.getSelection());
227
228       //                        settings.put(
229       //                                STORE_CREATE_STRUCTURE_ID,
230       //                                createDirectoryStructureButton.getSelection());
231
232     }
233   }
234
235   /**
236    * Hook method for restoring widget values to the values that they held last time this wizard was used to completion.
237    */
238   protected void restoreWidgetValues() {
239     IDialogSettings settings = getDialogSettings();
240     if (settings != null) {
241       String[] directoryNames = settings.getArray(STORE_DESTINATION_NAMES_ID);
242       if (directoryNames == null)
243         return; // ie.- no settings stored
244
245       // destination
246       setDestinationValue(directoryNames[0]);
247       for (int i = 0; i < directoryNames.length; i++)
248         addDestinationItem(directoryNames[i]);
249
250       // options
251       overwriteExistingFilesCheckbox.setSelection(settings.getBoolean(STORE_OVERWRITE_EXISTING_FILES_ID));
252
253       //                        boolean createDirectories =
254       //                                settings.getBoolean(STORE_CREATE_STRUCTURE_ID);
255       //                        createDirectoryStructureButton.setSelection(createDirectories);
256       //                        createSelectionOnlyButton.setSelection(!createDirectories);
257     }
258   }
259   /**
260          *      Add the passed value to self's destination widget's history
261          *
262          *      @param value java.lang.String
263          */
264         protected void addDestinationItem(String value) {
265                 destinationNameField.add(value);
266         }
267   /**
268    * (non-Javadoc) Method declared on IDialogPage.
269    */
270   public void createControl(Composite parent) {
271     super.createControl(parent);
272     giveFocusToDestination();
273     //          WorkbenchHelp.setHelp(
274     //                  getControl(),
275     //                  IDataTransferHelpContextIds.FILE_SYSTEM_EXPORT_WIZARD_PAGE);
276   }
277
278   /**
279    * Set the current input focus to self's destination entry field
280    */
281   protected void giveFocusToDestination() {
282     destinationNameField.setFocus();
283   }
284
285   //  private Composite createControlsContainer(Composite parent) {
286   //    Composite container = new Composite(parent, SWT.NULL);
287   //    GridLayout layout = new GridLayout();
288   //    layout.numColumns = 1;
289   //    layout.verticalSpacing = 20;
290   //    container.setLayout(layout);
291   //    container.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
292   //
293   //    createCommonControls(container);
294   //    return container;
295   //  }
296
297   //  private void createCommonControls(Composite parent) {
298   //    Composite container = new Composite(parent, SWT.NULL);
299   //    GridLayout layout = new GridLayout();
300   //    layout.numColumns = 3;
301   //    layout.verticalSpacing = 9;
302   //    container.setLayout(layout);
303   //    container.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
304   //
305   //    createFolderControls(container);
306   //    createExportDirectoryControls(container);
307   //  }
308
309   //  private void createExportDirectoryControls(Composite container) {
310   //    exportFileText = addStringFieldEditor(container, WikiEditorPlugin.getResourceString("Export.wizardExportDirectory"));
311   //
312   //    Button button = new Button(container, SWT.PUSH);
313   //    button.setText(WikiEditorPlugin.getResourceString("Export.wizardBrowse"));
314   //    button.addSelectionListener(new SelectionAdapter() {
315   //      public void widgetSelected(SelectionEvent e) {
316   //        handleBrowseHtmlExportLocation();
317   //      }
318   //    });
319   //  }
320
321   //  private void createFolderControls(Composite container) {
322   //    folderText = addStringFieldEditor(container, WikiEditorPlugin.getResourceString("Export.wizardFolder"));
323   //
324   //    Button button = new Button(container, SWT.PUSH);
325   //    button.setText(WikiEditorPlugin.getResourceString("Export.wizardBrowse"));
326   //    button.addSelectionListener(new SelectionAdapter() {
327   //      public void widgetSelected(SelectionEvent e) {
328   //        try {
329   //          handleBrowseFolders();
330   //        } catch (CoreException cex) {
331   //          WikiEditorPlugin.getDefault().log("", cex);
332   //          throw new RuntimeException("Caught CoreException. See log for details.");
333   //        }
334   //      }
335   //    });
336   //  }
337
338   //  private StringFieldEditor addStringFieldEditor(Composite container, String labelText) {
339   //    Label label = new Label(container, SWT.NULL);
340   //    label.setText(labelText);
341   //
342   //    Composite editorComposite = new Composite(container, SWT.NULL);
343   //    editorComposite.setLayout(new GridLayout());
344   //    editorComposite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
345   //    StringFieldEditor editor = new StringFieldEditor("", "", editorComposite);
346   //
347   //    editor.setPropertyChangeListener(this);
348   //
349   //    return editor;
350   //  }
351
352   private void initialize() throws CoreException {
353     if (selection == null || selection.isEmpty() || !(selection instanceof IStructuredSelection)) {
354       return;
355     }
356
357     IStructuredSelection ssel = (IStructuredSelection) selection;
358     if (ssel.size() == 1) {
359       initialiseFromSelectedObject(ssel.getFirstElement());
360     }
361   }
362
363   private void initialiseFromSelectedObject(Object obj) throws CoreException {
364     if (obj instanceof IFolder || obj instanceof IProject) {
365       initialiseFolder(((IResource) obj));
366     }
367   }
368
369   private void initialiseFolder(IResource resource) throws CoreException {
370     folderText.setStringValue(resource.getFullPath().toString());
371     initialiseExportDirectoryText(resource);
372   }
373
374   private void initialiseExportDirectoryText(IResource resource) throws CoreException {
375     String exportDir = resource.getProject().getPersistentProperty(WikiPDFExportWizard.DIRECTORY_QUALIFIED_NAME);
376     if (exportDir != null) {
377       exportFileText.setStringValue(exportDir);
378     } else {
379       exportFileText.setStringValue("");
380     }
381   }
382
383   private void handleBrowseHtmlExportLocation() {
384     FileDialog dialog = new FileDialog(getShell(), SWT.SINGLE | SWT.OPEN);
385     dialog.setFilterExtensions(PDF_EXTENSION);
386     String path = dialog.open();
387     if (path != null) {
388       exportFileText.setStringValue(path);
389     }
390   }
391
392   private void handleBrowseFolders() throws CoreException {
393     ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), false,
394         WikiEditorPlugin.getResourceString("Export.wizardSelectFolder"));
395     if (dialog.open() == Window.OK) {
396       Object[] result = dialog.getResult();
397       if (result != null && result.length == 1) {
398         IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember((IPath) result[0]);
399         if (resource instanceof IFile) {
400           return;
401         }
402         initialiseFolder(resource);
403       }
404     }
405   }
406
407   private void dialogChanged() {
408     if (getFolderText().length() == 0) {
409       updateStatus("Folder must be specified");
410     } else if (getExportDirectoryPath().length() == 0) {
411       updateStatus("Directory must be specified");
412     } else {
413       updateStatus(null);
414     }
415   }
416
417   private void updateStatus(String message) {
418     setErrorMessage(message);
419     setPageComplete(message == null);
420   }
421
422   public String getExportDirectoryPath() {
423     return exportFileText.getStringValue();
424   }
425
426   public void propertyChange(PropertyChangeEvent event) {
427     dialogChanged();
428   }
429
430   public void widgetSelected(SelectionEvent e) {
431     dialogChanged();
432   }
433
434   public void widgetDefaultSelected(SelectionEvent e) {
435     dialogChanged();
436   }
437
438   String getFolderText() {
439     return folderText.getStringValue();
440   }
441
442   public IContainer getFolder() {
443     return (IContainer) ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(getFolderText()));
444   }
445
446   protected boolean executeExportOperation(WikiPDFExporter op) {
447     //  op.setCreateLeadupStructure(
448     //          createDirectoryStructureButton.getSelection());
449     op.setOverwriteFiles(overwriteExistingFilesCheckbox.getSelection());
450
451     try {
452       getContainer().run(true, true, op);
453     } catch (InterruptedException e) {
454       return true;
455     } catch (InvocationTargetException e) {
456       displayErrorDialog(e.getTargetException());
457       return true;
458     }
459
460     IStatus status = op.getStatus();
461     if (!status.isOK()) {
462       ErrorDialog.openError(getContainer().getShell(), "PDF export problems", //$NON-NLS-1$
463           null, // no special message
464           status);
465       return true;
466     }
467
468     return true;
469   }
470
471   /**
472    * The Finish button was pressed. Try to do the required work now and answer a boolean indicating success. If false is returned
473    * then the wizard will not close.
474    * 
475    * @return boolean
476    */
477   public boolean finish() {
478     //          if (!ensureTargetIsValid(new File(getDestinationValue())))
479     //                  return false;
480
481     List resourcesToExport = getWhiteCheckedResources();
482
483     //Save dirty editors if possible but do not stop if not all are saved
484     saveDirtyEditors();
485     // about to invoke the operation so save our state
486     saveWidgetValues();
487
488     if (resourcesToExport.size() > 0)
489       return executeExportOperation(new WikiPDFExporter(resourcesToExport, getDestinationValue(), this));
490
491     MessageDialog.openInformation(getContainer().getShell(), "PDF export", //$NON-NLS-1$
492         "No file selected"); //$NON-NLS-1$
493
494     return false;
495   }
496 }