001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.wizards.datatransfer;
011:
012: import java.io.File;
013: import java.lang.reflect.InvocationTargetException;
014: import java.util.List;
015:
016: import org.eclipse.core.runtime.IStatus;
017: import org.eclipse.jface.dialogs.ErrorDialog;
018: import org.eclipse.jface.dialogs.IDialogSettings;
019: import org.eclipse.jface.viewers.IStructuredSelection;
020: import org.eclipse.swt.SWT;
021: import org.eclipse.swt.graphics.Font;
022: import org.eclipse.swt.layout.GridData;
023: import org.eclipse.swt.layout.GridLayout;
024: import org.eclipse.swt.widgets.Button;
025: import org.eclipse.swt.widgets.Composite;
026: import org.eclipse.swt.widgets.FileDialog;
027: import org.eclipse.swt.widgets.Group;
028: import org.eclipse.ui.PlatformUI;
029:
030: /**
031: * Page 1 of the base resource export-to-archive Wizard.
032: *
033: * @since 3.1
034: */
035: public class WizardArchiveFileResourceExportPage1 extends
036: WizardFileSystemResourceExportPage1 {
037:
038: // widgets
039: protected Button compressContentsCheckbox;
040:
041: private Button zipFormatButton;
042: private Button targzFormatButton;
043:
044: // dialog store id constants
045: private final static String STORE_DESTINATION_NAMES_ID = "WizardZipFileResourceExportPage1.STORE_DESTINATION_NAMES_ID"; //$NON-NLS-1$
046:
047: private final static String STORE_CREATE_STRUCTURE_ID = "WizardZipFileResourceExportPage1.STORE_CREATE_STRUCTURE_ID"; //$NON-NLS-1$
048:
049: private final static String STORE_COMPRESS_CONTENTS_ID = "WizardZipFileResourceExportPage1.STORE_COMPRESS_CONTENTS_ID"; //$NON-NLS-1$
050:
051: /**
052: * Create an instance of this class.
053: *
054: * @param name java.lang.String
055: */
056: protected WizardArchiveFileResourceExportPage1(String name,
057: IStructuredSelection selection) {
058: super (name, selection);
059: }
060:
061: /**
062: * Create an instance of this class
063: * @param selection the selection
064: */
065: public WizardArchiveFileResourceExportPage1(
066: IStructuredSelection selection) {
067: this ("zipFileExportPage1", selection); //$NON-NLS-1$
068: setTitle(DataTransferMessages.ArchiveExport_exportTitle);
069: setDescription(DataTransferMessages.ArchiveExport_description);
070: }
071:
072: /** (non-Javadoc)
073: * Method declared on IDialogPage.
074: */
075: public void createControl(Composite parent) {
076: super .createControl(parent);
077: PlatformUI
078: .getWorkbench()
079: .getHelpSystem()
080: .setHelp(
081: getControl(),
082: IDataTransferHelpContextIds.ZIP_FILE_EXPORT_WIZARD_PAGE);
083: }
084:
085: /**
086: * Create the export options specification widgets.
087: *
088: */
089: protected void createOptionsGroupButtons(Group optionsGroup) {
090: Font font = optionsGroup.getFont();
091: optionsGroup.setLayout(new GridLayout(2, true));
092:
093: Composite left = new Composite(optionsGroup, SWT.NONE);
094: left
095: .setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true,
096: false));
097: left.setLayout(new GridLayout(1, true));
098:
099: createFileFormatOptions(left, font);
100:
101: // compress... checkbox
102: compressContentsCheckbox = new Button(left, SWT.CHECK
103: | SWT.LEFT);
104: compressContentsCheckbox
105: .setText(DataTransferMessages.ZipExport_compressContents);
106: compressContentsCheckbox.setFont(font);
107:
108: Composite right = new Composite(optionsGroup, SWT.NONE);
109: right
110: .setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true,
111: false));
112: right.setLayout(new GridLayout(1, true));
113:
114: createDirectoryStructureOptions(right, font);
115:
116: // initial setup
117: createDirectoryStructureButton.setSelection(true);
118: createSelectionOnlyButton.setSelection(false);
119: compressContentsCheckbox.setSelection(true);
120: }
121:
122: /**
123: * Create the buttons for the group that determine if the entire or
124: * selected directory structure should be created.
125: * @param optionsGroup
126: * @param font
127: */
128: protected void createFileFormatOptions(Composite optionsGroup,
129: Font font) {
130: // create directory structure radios
131: zipFormatButton = new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
132: zipFormatButton
133: .setText(DataTransferMessages.ArchiveExport_saveInZipFormat);
134: zipFormatButton.setSelection(true);
135: zipFormatButton.setFont(font);
136:
137: // create directory structure radios
138: targzFormatButton = new Button(optionsGroup, SWT.RADIO
139: | SWT.LEFT);
140: targzFormatButton
141: .setText(DataTransferMessages.ArchiveExport_saveInTarFormat);
142: targzFormatButton.setSelection(false);
143: targzFormatButton.setFont(font);
144: }
145:
146: /**
147: * Returns a boolean indicating whether the directory portion of the
148: * passed pathname is valid and available for use.
149: */
150: protected boolean ensureTargetDirectoryIsValid(String fullPathname) {
151: int separatorIndex = fullPathname.lastIndexOf(File.separator);
152:
153: if (separatorIndex == -1) {
154: return true;
155: }
156:
157: return ensureTargetIsValid(new File(fullPathname.substring(0,
158: separatorIndex)));
159: }
160:
161: /**
162: * Returns a boolean indicating whether the passed File handle is
163: * is valid and available for use.
164: */
165: protected boolean ensureTargetFileIsValid(File targetFile) {
166: if (targetFile.exists() && targetFile.isDirectory()) {
167: displayErrorDialog(DataTransferMessages.ZipExport_mustBeFile);
168: giveFocusToDestination();
169: return false;
170: }
171:
172: if (targetFile.exists()) {
173: if (targetFile.canWrite()) {
174: if (!queryYesNoQuestion(DataTransferMessages.ZipExport_alreadyExists)) {
175: return false;
176: }
177: } else {
178: displayErrorDialog(DataTransferMessages.ZipExport_alreadyExistsError);
179: giveFocusToDestination();
180: return false;
181: }
182: }
183:
184: return true;
185: }
186:
187: /**
188: * Ensures that the target output file and its containing directory are
189: * both valid and able to be used. Answer a boolean indicating validity.
190: */
191: protected boolean ensureTargetIsValid() {
192: String targetPath = getDestinationValue();
193:
194: if (!ensureTargetDirectoryIsValid(targetPath)) {
195: return false;
196: }
197:
198: if (!ensureTargetFileIsValid(new File(targetPath))) {
199: return false;
200: }
201:
202: return true;
203: }
204:
205: /**
206: * Export the passed resource and recursively export all of its child resources
207: * (iff it's a container). Answer a boolean indicating success.
208: */
209: protected boolean executeExportOperation(
210: ArchiveFileExportOperation op) {
211: op.setCreateLeadupStructure(createDirectoryStructureButton
212: .getSelection());
213: op.setUseCompression(compressContentsCheckbox.getSelection());
214: op.setUseTarFormat(targzFormatButton.getSelection());
215:
216: try {
217: getContainer().run(true, true, op);
218: } catch (InterruptedException e) {
219: return false;
220: } catch (InvocationTargetException e) {
221: displayErrorDialog(e.getTargetException());
222: return false;
223: }
224:
225: IStatus status = op.getStatus();
226: if (!status.isOK()) {
227: ErrorDialog.openError(getContainer().getShell(),
228: DataTransferMessages.DataTransfer_exportProblems,
229: null, // no special message
230: status);
231: return false;
232: }
233:
234: return true;
235: }
236:
237: /**
238: * The Finish button was pressed. Try to do the required work now and answer
239: * a boolean indicating success. If false is returned then the wizard will
240: * not close.
241: * @returns boolean
242: */
243: public boolean finish() {
244: List resourcesToExport = getWhiteCheckedResources();
245:
246: if (!ensureTargetIsValid()) {
247: return false;
248: }
249:
250: //Save dirty editors if possible but do not stop if not all are saved
251: saveDirtyEditors();
252: // about to invoke the operation so save our state
253: saveWidgetValues();
254:
255: return executeExportOperation(new ArchiveFileExportOperation(
256: null, resourcesToExport, getDestinationValue()));
257: }
258:
259: /**
260: * Answer the string to display in the receiver as the destination type
261: */
262: protected String getDestinationLabel() {
263: return DataTransferMessages.ArchiveExport_destinationLabel;
264: }
265:
266: /**
267: * Answer the contents of self's destination specification widget. If this
268: * value does not have a suffix then add it first.
269: */
270: protected String getDestinationValue() {
271: String idealSuffix = getOutputSuffix();
272: String destinationText = super .getDestinationValue();
273:
274: // only append a suffix if the destination doesn't already have a . in
275: // its last path segment.
276: // Also prevent the user from selecting a directory. Allowing this will
277: // create a ".zip" file in the directory
278: if (destinationText.length() != 0
279: && !destinationText.endsWith(File.separator)) {
280: int dotIndex = destinationText.lastIndexOf('.');
281: if (dotIndex != -1) {
282: // the last path seperator index
283: int pathSepIndex = destinationText
284: .lastIndexOf(File.separator);
285: if (pathSepIndex != -1 && dotIndex < pathSepIndex) {
286: destinationText += idealSuffix;
287: }
288: } else {
289: destinationText += idealSuffix;
290: }
291: }
292:
293: return destinationText;
294: }
295:
296: /**
297: * Answer the suffix that files exported from this wizard should have.
298: * If this suffix is a file extension (which is typically the case)
299: * then it must include the leading period character.
300: *
301: */
302: protected String getOutputSuffix() {
303: if (zipFormatButton.getSelection()) {
304: return ".zip"; //$NON-NLS-1$
305: } else if (compressContentsCheckbox.getSelection()) {
306: return ".tar.gz"; //$NON-NLS-1$
307: } else {
308: return ".tar"; //$NON-NLS-1$
309: }
310: }
311:
312: /**
313: * Open an appropriate destination browser so that the user can specify a source
314: * to import from
315: */
316: protected void handleDestinationBrowseButtonPressed() {
317: FileDialog dialog = new FileDialog(getContainer().getShell(),
318: SWT.SAVE);
319: dialog.setFilterExtensions(new String[] {
320: "*.zip;*.tar.gz;*.tar;*.tgz", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
321: dialog
322: .setText(DataTransferMessages.ArchiveExport_selectDestinationTitle);
323: String currentSourceString = getDestinationValue();
324: int lastSeparatorIndex = currentSourceString
325: .lastIndexOf(File.separator);
326: if (lastSeparatorIndex != -1) {
327: dialog.setFilterPath(currentSourceString.substring(0,
328: lastSeparatorIndex));
329: }
330: String selectedFileName = dialog.open();
331:
332: if (selectedFileName != null) {
333: setErrorMessage(null);
334: setDestinationValue(selectedFileName);
335: }
336: }
337:
338: /**
339: * Hook method for saving widget values for restoration by the next instance
340: * of this class.
341: */
342: protected void internalSaveWidgetValues() {
343: // update directory names history
344: IDialogSettings settings = getDialogSettings();
345: if (settings != null) {
346: String[] directoryNames = settings
347: .getArray(STORE_DESTINATION_NAMES_ID);
348: if (directoryNames == null) {
349: directoryNames = new String[0];
350: }
351:
352: directoryNames = addToHistory(directoryNames,
353: getDestinationValue());
354: settings.put(STORE_DESTINATION_NAMES_ID, directoryNames);
355:
356: settings.put(STORE_CREATE_STRUCTURE_ID,
357: createDirectoryStructureButton.getSelection());
358:
359: settings.put(STORE_COMPRESS_CONTENTS_ID,
360: compressContentsCheckbox.getSelection());
361: }
362: }
363:
364: /**
365: * Hook method for restoring widget values to the values that they held
366: * last time this wizard was used to completion.
367: */
368: protected void restoreWidgetValues() {
369: IDialogSettings settings = getDialogSettings();
370: if (settings != null) {
371: String[] directoryNames = settings
372: .getArray(STORE_DESTINATION_NAMES_ID);
373: if (directoryNames == null || directoryNames.length == 0) {
374: return; // ie.- no settings stored
375: }
376:
377: // destination
378: setDestinationValue(directoryNames[0]);
379: for (int i = 0; i < directoryNames.length; i++) {
380: addDestinationItem(directoryNames[i]);
381: }
382:
383: boolean setStructure = settings
384: .getBoolean(STORE_CREATE_STRUCTURE_ID);
385:
386: createDirectoryStructureButton.setSelection(setStructure);
387: createSelectionOnlyButton.setSelection(!setStructure);
388:
389: compressContentsCheckbox.setSelection(settings
390: .getBoolean(STORE_COMPRESS_CONTENTS_ID));
391: }
392: }
393:
394: /* (non-Javadoc)
395: * @see org.eclipse.ui.wizards.datatransfer.WizardFileSystemResourceExportPage1#destinationEmptyMessage()
396: */
397: protected String destinationEmptyMessage() {
398: return DataTransferMessages.ArchiveExport_destinationEmpty;
399: }
400:
401: /**
402: * Answer a boolean indicating whether the receivers destination specification
403: * widgets currently all contain valid values.
404: */
405: protected boolean validateDestinationGroup() {
406: String destinationValue = getDestinationValue();
407: if (destinationValue.endsWith(".tar")) { //$NON-NLS-1$
408: compressContentsCheckbox.setSelection(false);
409: targzFormatButton.setSelection(true);
410: zipFormatButton.setSelection(false);
411: } else if (destinationValue.endsWith(".tar.gz") //$NON-NLS-1$
412: || destinationValue.endsWith(".tgz")) { //$NON-NLS-1$
413: compressContentsCheckbox.setSelection(true);
414: targzFormatButton.setSelection(true);
415: zipFormatButton.setSelection(false);
416: } else if (destinationValue.endsWith(".zip")) { //$NON-NLS-1$
417: zipFormatButton.setSelection(true);
418: targzFormatButton.setSelection(false);
419: }
420:
421: return super.validateDestinationGroup();
422: }
423: }
|