0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2006 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.ui.internal.wizards.datatransfer;
0011:
0012: import java.io.File;
0013: import java.lang.reflect.InvocationTargetException;
0014: import java.util.ArrayList;
0015: import java.util.Collection;
0016: import java.util.Hashtable;
0017: import java.util.Iterator;
0018: import java.util.List;
0019: import java.util.Map;
0020:
0021: import org.eclipse.core.resources.IContainer;
0022: import org.eclipse.core.runtime.IPath;
0023: import org.eclipse.core.runtime.IProgressMonitor;
0024: import org.eclipse.core.runtime.IStatus;
0025: import org.eclipse.core.runtime.Path;
0026: import org.eclipse.jface.dialogs.ErrorDialog;
0027: import org.eclipse.jface.dialogs.IDialogConstants;
0028: import org.eclipse.jface.dialogs.IDialogSettings;
0029: import org.eclipse.jface.dialogs.MessageDialog;
0030: import org.eclipse.jface.dialogs.ProgressMonitorDialog;
0031: import org.eclipse.jface.operation.IRunnableWithProgress;
0032: import org.eclipse.jface.viewers.IStructuredSelection;
0033: import org.eclipse.jface.viewers.ITreeContentProvider;
0034: import org.eclipse.swt.SWT;
0035: import org.eclipse.swt.custom.BusyIndicator;
0036: import org.eclipse.swt.events.FocusEvent;
0037: import org.eclipse.swt.events.FocusListener;
0038: import org.eclipse.swt.events.KeyEvent;
0039: import org.eclipse.swt.events.KeyListener;
0040: import org.eclipse.swt.events.SelectionAdapter;
0041: import org.eclipse.swt.events.SelectionEvent;
0042: import org.eclipse.swt.events.SelectionListener;
0043: import org.eclipse.swt.layout.GridData;
0044: import org.eclipse.swt.layout.GridLayout;
0045: import org.eclipse.swt.widgets.Button;
0046: import org.eclipse.swt.widgets.Combo;
0047: import org.eclipse.swt.widgets.Composite;
0048: import org.eclipse.swt.widgets.DirectoryDialog;
0049: import org.eclipse.swt.widgets.Event;
0050: import org.eclipse.swt.widgets.Group;
0051: import org.eclipse.swt.widgets.Label;
0052: import org.eclipse.swt.widgets.Listener;
0053: import org.eclipse.swt.widgets.Shell;
0054: import org.eclipse.ui.IWorkbench;
0055: import org.eclipse.ui.PlatformUI;
0056: import org.eclipse.ui.dialogs.FileSystemElement;
0057: import org.eclipse.ui.dialogs.WizardResourceImportPage;
0058: import org.eclipse.ui.internal.ide.dialogs.IElementFilter;
0059: import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog;
0060: import org.eclipse.ui.model.WorkbenchContentProvider;
0061: import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
0062: import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
0063: import org.eclipse.ui.wizards.datatransfer.ImportOperation;
0064:
0065: /**
0066: * Page 1 of the base resource import-from-file-system Wizard
0067: */
0068: public class WizardFileSystemResourceImportPage1 extends
0069: WizardResourceImportPage implements Listener {
0070: // widgets
0071: protected Combo sourceNameField;
0072:
0073: protected Button overwriteExistingResourcesCheckbox;
0074:
0075: protected Button createContainerStructureButton;
0076:
0077: protected Button createOnlySelectedButton;
0078:
0079: protected Button sourceBrowseButton;
0080:
0081: protected Button selectTypesButton;
0082:
0083: protected Button selectAllButton;
0084:
0085: protected Button deselectAllButton;
0086:
0087: //A boolean to indicate if the user has typed anything
0088: private boolean entryChanged = false;
0089:
0090: // dialog store id constants
0091: private final static String STORE_SOURCE_NAMES_ID = "WizardFileSystemResourceImportPage1.STORE_SOURCE_NAMES_ID";//$NON-NLS-1$
0092:
0093: private final static String STORE_OVERWRITE_EXISTING_RESOURCES_ID = "WizardFileSystemResourceImportPage1.STORE_OVERWRITE_EXISTING_RESOURCES_ID";//$NON-NLS-1$
0094:
0095: private final static String STORE_CREATE_CONTAINER_STRUCTURE_ID = "WizardFileSystemResourceImportPage1.STORE_CREATE_CONTAINER_STRUCTURE_ID";//$NON-NLS-1$
0096:
0097: private static final String SELECT_TYPES_TITLE = DataTransferMessages.DataTransfer_selectTypes;
0098:
0099: private static final String SELECT_ALL_TITLE = DataTransferMessages.DataTransfer_selectAll;
0100:
0101: private static final String DESELECT_ALL_TITLE = DataTransferMessages.DataTransfer_deselectAll;
0102:
0103: private static final String SELECT_SOURCE_TITLE = DataTransferMessages.FileImport_selectSourceTitle;
0104:
0105: private static final String SELECT_SOURCE_MESSAGE = DataTransferMessages.FileImport_selectSource;
0106:
0107: protected static final String SOURCE_EMPTY_MESSAGE = DataTransferMessages.FileImport_sourceEmpty;
0108:
0109: /**
0110: * Creates an instance of this class
0111: */
0112: protected WizardFileSystemResourceImportPage1(String name,
0113: IWorkbench aWorkbench, IStructuredSelection selection) {
0114: super (name, selection);
0115: }
0116:
0117: /**
0118: * Creates an instance of this class
0119: *
0120: * @param aWorkbench IWorkbench
0121: * @param selection IStructuredSelection
0122: */
0123: public WizardFileSystemResourceImportPage1(IWorkbench aWorkbench,
0124: IStructuredSelection selection) {
0125: this ("fileSystemImportPage1", aWorkbench, selection);//$NON-NLS-1$
0126: setTitle(DataTransferMessages.DataTransfer_fileSystemTitle);
0127: setDescription(DataTransferMessages.FileImport_importFileSystem);
0128: }
0129:
0130: /**
0131: * Creates a new button with the given id.
0132: * <p>
0133: * The <code>Dialog</code> implementation of this framework method
0134: * creates a standard push button, registers for selection events
0135: * including button presses and registers
0136: * default buttons with its shell.
0137: * The button id is stored as the buttons client data.
0138: * Note that the parent's layout is assumed to be a GridLayout and
0139: * the number of columns in this layout is incremented.
0140: * Subclasses may override.
0141: * </p>
0142: *
0143: * @param parent the parent composite
0144: * @param id the id of the button (see
0145: * <code>IDialogConstants.*_ID</code> constants
0146: * for standard dialog button ids)
0147: * @param label the label from the button
0148: * @param defaultButton <code>true</code> if the button is to be the
0149: * default button, and <code>false</code> otherwise
0150: */
0151: protected Button createButton(Composite parent, int id,
0152: String label, boolean defaultButton) {
0153: // increment the number of columns in the button bar
0154: ((GridLayout) parent.getLayout()).numColumns++;
0155:
0156: Button button = new Button(parent, SWT.PUSH);
0157: button.setFont(parent.getFont());
0158:
0159: GridData buttonData = new GridData(GridData.FILL_HORIZONTAL);
0160: button.setLayoutData(buttonData);
0161:
0162: button.setData(new Integer(id));
0163: button.setText(label);
0164:
0165: if (defaultButton) {
0166: Shell shell = parent.getShell();
0167: if (shell != null) {
0168: shell.setDefaultButton(button);
0169: }
0170: button.setFocus();
0171: }
0172: return button;
0173: }
0174:
0175: /**
0176: * Creates the buttons for selecting specific types or selecting all or none of the
0177: * elements.
0178: *
0179: * @param parent the parent control
0180: */
0181: protected final void createButtonsGroup(Composite parent) {
0182: // top level group
0183: Composite buttonComposite = new Composite(parent, SWT.NONE);
0184: GridLayout layout = new GridLayout();
0185: layout.numColumns = 3;
0186: layout.makeColumnsEqualWidth = true;
0187: buttonComposite.setLayout(layout);
0188: buttonComposite.setFont(parent.getFont());
0189: GridData buttonData = new GridData(GridData.VERTICAL_ALIGN_FILL
0190: | GridData.HORIZONTAL_ALIGN_FILL);
0191: buttonData.horizontalSpan = 2;
0192: buttonComposite.setLayoutData(buttonData);
0193:
0194: // types edit button
0195: selectTypesButton = createButton(buttonComposite,
0196: IDialogConstants.SELECT_TYPES_ID, SELECT_TYPES_TITLE,
0197: false);
0198:
0199: SelectionListener listener = new SelectionAdapter() {
0200: public void widgetSelected(SelectionEvent e) {
0201: handleTypesEditButtonPressed();
0202: }
0203: };
0204: selectTypesButton.addSelectionListener(listener);
0205: setButtonLayoutData(selectTypesButton);
0206:
0207: selectAllButton = createButton(buttonComposite,
0208: IDialogConstants.SELECT_ALL_ID, SELECT_ALL_TITLE, false);
0209:
0210: listener = new SelectionAdapter() {
0211: public void widgetSelected(SelectionEvent e) {
0212: setAllSelections(true);
0213: updateWidgetEnablements();
0214: }
0215: };
0216: selectAllButton.addSelectionListener(listener);
0217: setButtonLayoutData(selectAllButton);
0218:
0219: deselectAllButton = createButton(buttonComposite,
0220: IDialogConstants.DESELECT_ALL_ID, DESELECT_ALL_TITLE,
0221: false);
0222:
0223: listener = new SelectionAdapter() {
0224: public void widgetSelected(SelectionEvent e) {
0225: setAllSelections(false);
0226: updateWidgetEnablements();
0227: }
0228: };
0229: deselectAllButton.addSelectionListener(listener);
0230: setButtonLayoutData(deselectAllButton);
0231:
0232: }
0233:
0234: /* (non-Javadoc)
0235: * Method declared on IDialogPage.
0236: */
0237: public void createControl(Composite parent) {
0238: super .createControl(parent);
0239: validateSourceGroup();
0240: PlatformUI
0241: .getWorkbench()
0242: .getHelpSystem()
0243: .setHelp(
0244: getControl(),
0245: IDataTransferHelpContextIds.FILE_SYSTEM_IMPORT_WIZARD_PAGE);
0246: }
0247:
0248: /**
0249: * Create the import options specification widgets.
0250: */
0251: protected void createOptionsGroupButtons(Group optionsGroup) {
0252:
0253: // overwrite... checkbox
0254: overwriteExistingResourcesCheckbox = new Button(optionsGroup,
0255: SWT.CHECK);
0256: overwriteExistingResourcesCheckbox.setFont(optionsGroup
0257: .getFont());
0258: overwriteExistingResourcesCheckbox
0259: .setText(DataTransferMessages.FileImport_overwriteExisting);
0260:
0261: // create containers radio
0262: createContainerStructureButton = new Button(optionsGroup,
0263: SWT.RADIO);
0264: createContainerStructureButton.setFont(optionsGroup.getFont());
0265: createContainerStructureButton
0266: .setText(DataTransferMessages.FileImport_createComplete);
0267: createContainerStructureButton.setSelection(false);
0268:
0269: // create selection only radio
0270: createOnlySelectedButton = new Button(optionsGroup, SWT.RADIO);
0271: createOnlySelectedButton.setFont(optionsGroup.getFont());
0272: createOnlySelectedButton
0273: .setText(DataTransferMessages.FileImport_createSelectedFolders);
0274: createOnlySelectedButton.setSelection(true);
0275:
0276: }
0277:
0278: /**
0279: * Create the group for creating the root directory
0280: */
0281: protected void createRootDirectoryGroup(Composite parent) {
0282: Composite sourceContainerGroup = new Composite(parent, SWT.NONE);
0283: GridLayout layout = new GridLayout();
0284: layout.numColumns = 3;
0285: sourceContainerGroup.setLayout(layout);
0286: sourceContainerGroup.setFont(parent.getFont());
0287: sourceContainerGroup.setLayoutData(new GridData(
0288: GridData.HORIZONTAL_ALIGN_FILL
0289: | GridData.GRAB_HORIZONTAL));
0290:
0291: Label groupLabel = new Label(sourceContainerGroup, SWT.NONE);
0292: groupLabel.setText(getSourceLabel());
0293: groupLabel.setFont(parent.getFont());
0294:
0295: // source name entry field
0296: sourceNameField = new Combo(sourceContainerGroup, SWT.BORDER);
0297: GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
0298: | GridData.GRAB_HORIZONTAL);
0299: data.widthHint = SIZING_TEXT_FIELD_WIDTH;
0300: sourceNameField.setLayoutData(data);
0301: sourceNameField.setFont(parent.getFont());
0302:
0303: sourceNameField.addSelectionListener(new SelectionAdapter() {
0304: public void widgetSelected(SelectionEvent e) {
0305: updateFromSourceField();
0306: }
0307: });
0308:
0309: sourceNameField.addKeyListener(new KeyListener() {
0310: /*
0311: * @see KeyListener.keyPressed
0312: */
0313: public void keyPressed(KeyEvent e) {
0314: //If there has been a key pressed then mark as dirty
0315: entryChanged = true;
0316: }
0317:
0318: /*
0319: * @see KeyListener.keyReleased
0320: */
0321: public void keyReleased(KeyEvent e) {
0322: }
0323: });
0324:
0325: sourceNameField.addFocusListener(new FocusListener() {
0326: /*
0327: * @see FocusListener.focusGained(FocusEvent)
0328: */
0329: public void focusGained(FocusEvent e) {
0330: //Do nothing when getting focus
0331: }
0332:
0333: /*
0334: * @see FocusListener.focusLost(FocusEvent)
0335: */
0336: public void focusLost(FocusEvent e) {
0337: //Clear the flag to prevent constant update
0338: if (entryChanged) {
0339: entryChanged = false;
0340: updateFromSourceField();
0341: }
0342:
0343: }
0344: });
0345:
0346: // source browse button
0347: sourceBrowseButton = new Button(sourceContainerGroup, SWT.PUSH);
0348: sourceBrowseButton
0349: .setText(DataTransferMessages.DataTransfer_browse);
0350: sourceBrowseButton.addListener(SWT.Selection, this );
0351: sourceBrowseButton.setLayoutData(new GridData(
0352: GridData.HORIZONTAL_ALIGN_FILL));
0353: sourceBrowseButton.setFont(parent.getFont());
0354: setButtonLayoutData(sourceBrowseButton);
0355: }
0356:
0357: /**
0358: * Update the receiver from the source name field.
0359: */
0360:
0361: private void updateFromSourceField() {
0362:
0363: setSourceName(sourceNameField.getText());
0364: //Update enablements when this is selected
0365: updateWidgetEnablements();
0366: }
0367:
0368: /**
0369: * Creates and returns a <code>FileSystemElement</code> if the specified
0370: * file system object merits one. The criteria for this are:
0371: * Also create the children.
0372: */
0373: protected MinimizedFileSystemElement createRootElement(
0374: Object fileSystemObject, IImportStructureProvider provider) {
0375: boolean isContainer = provider.isFolder(fileSystemObject);
0376: String elementLabel = provider.getLabel(fileSystemObject);
0377:
0378: // Use an empty label so that display of the element's full name
0379: // doesn't include a confusing label
0380: MinimizedFileSystemElement dummyParent = new MinimizedFileSystemElement(
0381: "", null, true);//$NON-NLS-1$
0382: dummyParent.setPopulated();
0383: MinimizedFileSystemElement result = new MinimizedFileSystemElement(
0384: elementLabel, dummyParent, isContainer);
0385: result.setFileSystemObject(fileSystemObject);
0386:
0387: //Get the files for the element so as to build the first level
0388: result.getFiles(provider);
0389:
0390: return dummyParent;
0391: }
0392:
0393: /**
0394: * Create the import source specification widgets
0395: */
0396: protected void createSourceGroup(Composite parent) {
0397:
0398: createRootDirectoryGroup(parent);
0399: createFileSelectionGroup(parent);
0400: createButtonsGroup(parent);
0401: }
0402:
0403: /**
0404: * Enable or disable the button group.
0405: */
0406: protected void enableButtonGroup(boolean enable) {
0407: selectTypesButton.setEnabled(enable);
0408: selectAllButton.setEnabled(enable);
0409: deselectAllButton.setEnabled(enable);
0410: }
0411:
0412: /**
0413: * Answer a boolean indicating whether the specified source currently exists
0414: * and is valid
0415: */
0416: protected boolean ensureSourceIsValid() {
0417: if (new File(getSourceDirectoryName()).isDirectory()) {
0418: return true;
0419: }
0420:
0421: setErrorMessage(DataTransferMessages.FileImport_invalidSource);
0422: return false;
0423: }
0424:
0425: /**
0426: * Execute the passed import operation. Answer a boolean indicating success.
0427: */
0428: protected boolean executeImportOperation(ImportOperation op) {
0429: initializeOperation(op);
0430:
0431: try {
0432: getContainer().run(true, true, op);
0433: } catch (InterruptedException e) {
0434: return false;
0435: } catch (InvocationTargetException e) {
0436: displayErrorDialog(e.getTargetException());
0437: return false;
0438: }
0439:
0440: IStatus status = op.getStatus();
0441: if (!status.isOK()) {
0442: ErrorDialog.openError(getContainer().getShell(),
0443: DataTransferMessages.FileImport_importProblems,
0444: null, // no special message
0445: status);
0446: return false;
0447: }
0448:
0449: return true;
0450: }
0451:
0452: /**
0453: * The Finish button was pressed. Try to do the required work now and answer
0454: * a boolean indicating success. If false is returned then the wizard will
0455: * not close.
0456: *
0457: * @return boolean
0458: */
0459: public boolean finish() {
0460: if (!ensureSourceIsValid()) {
0461: return false;
0462: }
0463:
0464: saveWidgetValues();
0465:
0466: Iterator resourcesEnum = getSelectedResources().iterator();
0467: List fileSystemObjects = new ArrayList();
0468: while (resourcesEnum.hasNext()) {
0469: fileSystemObjects.add(((FileSystemElement) resourcesEnum
0470: .next()).getFileSystemObject());
0471: }
0472:
0473: if (fileSystemObjects.size() > 0) {
0474: return importResources(fileSystemObjects);
0475: }
0476:
0477: MessageDialog.openInformation(getContainer().getShell(),
0478: DataTransferMessages.DataTransfer_information,
0479: DataTransferMessages.FileImport_noneSelected);
0480:
0481: return false;
0482: }
0483:
0484: /**
0485: * Returns a content provider for <code>FileSystemElement</code>s that returns
0486: * only files as children.
0487: */
0488: protected ITreeContentProvider getFileProvider() {
0489: return new WorkbenchContentProvider() {
0490: public Object[] getChildren(Object o) {
0491: if (o instanceof MinimizedFileSystemElement) {
0492: MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
0493: return element.getFiles(
0494: FileSystemStructureProvider.INSTANCE)
0495: .getChildren(element);
0496: }
0497: return new Object[0];
0498: }
0499: };
0500: }
0501:
0502: /**
0503: * Answer the root FileSystemElement that represents the contents of
0504: * the currently-specified source. If this FileSystemElement is not
0505: * currently defined then create and return it.
0506: */
0507: protected MinimizedFileSystemElement getFileSystemTree() {
0508:
0509: File sourceDirectory = getSourceDirectory();
0510: if (sourceDirectory == null) {
0511: return null;
0512: }
0513:
0514: return selectFiles(sourceDirectory,
0515: FileSystemStructureProvider.INSTANCE);
0516: }
0517:
0518: /**
0519: * Returns a content provider for <code>FileSystemElement</code>s that returns
0520: * only folders as children.
0521: */
0522: protected ITreeContentProvider getFolderProvider() {
0523: return new WorkbenchContentProvider() {
0524: public Object[] getChildren(Object o) {
0525: if (o instanceof MinimizedFileSystemElement) {
0526: MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
0527: return element.getFolders(
0528: FileSystemStructureProvider.INSTANCE)
0529: .getChildren(element);
0530: }
0531: return new Object[0];
0532: }
0533:
0534: public boolean hasChildren(Object o) {
0535: if (o instanceof MinimizedFileSystemElement) {
0536: MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
0537: if (element.isPopulated()) {
0538: return getChildren(element).length > 0;
0539: }
0540:
0541: //If we have not populated then wait until asked
0542: return true;
0543: }
0544: return false;
0545: }
0546: };
0547: }
0548:
0549: /**
0550: * Returns a File object representing the currently-named source directory iff
0551: * it exists as a valid directory, or <code>null</code> otherwise.
0552: */
0553: protected File getSourceDirectory() {
0554: return getSourceDirectory(this .sourceNameField.getText());
0555: }
0556:
0557: /**
0558: * Returns a File object representing the currently-named source directory iff
0559: * it exists as a valid directory, or <code>null</code> otherwise.
0560: *
0561: * @param path a String not yet formatted for java.io.File compatability
0562: */
0563: private File getSourceDirectory(String path) {
0564: File sourceDirectory = new File(getSourceDirectoryName(path));
0565: if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
0566: return null;
0567: }
0568:
0569: return sourceDirectory;
0570: }
0571:
0572: /**
0573: * Answer the directory name specified as being the import source.
0574: * Note that if it ends with a separator then the separator is first
0575: * removed so that java treats it as a proper directory
0576: */
0577: private String getSourceDirectoryName() {
0578: return getSourceDirectoryName(this .sourceNameField.getText());
0579: }
0580:
0581: /**
0582: * Answer the directory name specified as being the import source.
0583: * Note that if it ends with a separator then the separator is first
0584: * removed so that java treats it as a proper directory
0585: */
0586: private String getSourceDirectoryName(String sourceName) {
0587: IPath result = new Path(sourceName.trim());
0588:
0589: if (result.getDevice() != null && result.segmentCount() == 0) {
0590: result = result.addTrailingSeparator();
0591: } else {
0592: result = result.removeTrailingSeparator();
0593: }
0594:
0595: return result.toOSString();
0596: }
0597:
0598: /**
0599: * Answer the string to display as the label for the source specification field
0600: */
0601: protected String getSourceLabel() {
0602: return DataTransferMessages.FileImport_fromDirectory;
0603: }
0604:
0605: /**
0606: * Handle all events and enablements for widgets in this dialog
0607: *
0608: * @param event Event
0609: */
0610: public void handleEvent(Event event) {
0611: if (event.widget == sourceBrowseButton) {
0612: handleSourceBrowseButtonPressed();
0613: }
0614:
0615: super .handleEvent(event);
0616: }
0617:
0618: /**
0619: * Open an appropriate source browser so that the user can specify a source
0620: * to import from
0621: */
0622: protected void handleSourceBrowseButtonPressed() {
0623:
0624: String currentSource = this .sourceNameField.getText();
0625: DirectoryDialog dialog = new DirectoryDialog(sourceNameField
0626: .getShell(), SWT.SAVE);
0627: dialog.setText(SELECT_SOURCE_TITLE);
0628: dialog.setMessage(SELECT_SOURCE_MESSAGE);
0629: dialog.setFilterPath(getSourceDirectoryName(currentSource));
0630:
0631: String selectedDirectory = dialog.open();
0632: if (selectedDirectory != null) {
0633: //Just quit if the directory is not valid
0634: if ((getSourceDirectory(selectedDirectory) == null)
0635: || selectedDirectory.equals(currentSource)) {
0636: return;
0637: }
0638: //If it is valid then proceed to populate
0639: setErrorMessage(null);
0640: setSourceName(selectedDirectory);
0641: selectionGroup.setFocus();
0642: }
0643: }
0644:
0645: /**
0646: * Open a registered type selection dialog and note the selections
0647: * in the receivers types-to-export field.,
0648: * Added here so that inner classes can have access
0649: */
0650: protected void handleTypesEditButtonPressed() {
0651:
0652: super .handleTypesEditButtonPressed();
0653: }
0654:
0655: /**
0656: * Import the resources with extensions as specified by the user
0657: */
0658: protected boolean importResources(List fileSystemObjects) {
0659: ImportOperation operation = new ImportOperation(
0660: getContainerFullPath(), getSourceDirectory(),
0661: FileSystemStructureProvider.INSTANCE, this ,
0662: fileSystemObjects);
0663:
0664: operation.setContext(getShell());
0665: return executeImportOperation(operation);
0666: }
0667:
0668: /**
0669: * Initializes the specified operation appropriately.
0670: */
0671: protected void initializeOperation(ImportOperation op) {
0672: op.setCreateContainerStructure(createContainerStructureButton
0673: .getSelection());
0674: op.setOverwriteResources(overwriteExistingResourcesCheckbox
0675: .getSelection());
0676: }
0677:
0678: /**
0679: * Returns whether the extension provided is an extension that
0680: * has been specified for export by the user.
0681: *
0682: * @param extension the resource name
0683: * @return <code>true</code> if the resource name is suitable for export based
0684: * upon its extension
0685: */
0686: protected boolean isExportableExtension(String extension) {
0687: if (selectedTypes == null) {
0688: return true;
0689: }
0690:
0691: Iterator itr = selectedTypes.iterator();
0692: while (itr.hasNext()) {
0693: if (extension.equalsIgnoreCase((String) itr.next())) {
0694: return true;
0695: }
0696: }
0697:
0698: return false;
0699: }
0700:
0701: /**
0702: * Repopulate the view based on the currently entered directory.
0703: */
0704: protected void resetSelection() {
0705:
0706: MinimizedFileSystemElement currentRoot = getFileSystemTree();
0707: this .selectionGroup.setRoot(currentRoot);
0708:
0709: }
0710:
0711: /**
0712: * Use the dialog store to restore widget values to the values that they held
0713: * last time this wizard was used to completion
0714: */
0715: protected void restoreWidgetValues() {
0716: IDialogSettings settings = getDialogSettings();
0717: if (settings != null) {
0718: String[] sourceNames = settings
0719: .getArray(STORE_SOURCE_NAMES_ID);
0720: if (sourceNames == null) {
0721: return; // ie.- no values stored, so stop
0722: }
0723:
0724: // set filenames history
0725: for (int i = 0; i < sourceNames.length; i++) {
0726: sourceNameField.add(sourceNames[i]);
0727: }
0728:
0729: // radio buttons and checkboxes
0730: overwriteExistingResourcesCheckbox.setSelection(settings
0731: .getBoolean(STORE_OVERWRITE_EXISTING_RESOURCES_ID));
0732:
0733: boolean createStructure = settings
0734: .getBoolean(STORE_CREATE_CONTAINER_STRUCTURE_ID);
0735: createContainerStructureButton
0736: .setSelection(createStructure);
0737: createOnlySelectedButton.setSelection(!createStructure);
0738:
0739: }
0740: }
0741:
0742: /**
0743: * Since Finish was pressed, write widget values to the dialog store so that they
0744: * will persist into the next invocation of this wizard page
0745: */
0746: protected void saveWidgetValues() {
0747: IDialogSettings settings = getDialogSettings();
0748: if (settings != null) {
0749: // update source names history
0750: String[] sourceNames = settings
0751: .getArray(STORE_SOURCE_NAMES_ID);
0752: if (sourceNames == null) {
0753: sourceNames = new String[0];
0754: }
0755:
0756: sourceNames = addToHistory(sourceNames,
0757: getSourceDirectoryName());
0758: settings.put(STORE_SOURCE_NAMES_ID, sourceNames);
0759:
0760: // radio buttons and checkboxes
0761: settings.put(STORE_OVERWRITE_EXISTING_RESOURCES_ID,
0762: overwriteExistingResourcesCheckbox.getSelection());
0763:
0764: settings.put(STORE_CREATE_CONTAINER_STRUCTURE_ID,
0765: createContainerStructureButton.getSelection());
0766:
0767: }
0768: }
0769:
0770: /**
0771: * Invokes a file selection operation using the specified file system and
0772: * structure provider. If the user specifies files to be imported then
0773: * this selection is cached for later retrieval and is returned.
0774: */
0775: protected MinimizedFileSystemElement selectFiles(
0776: final Object rootFileSystemObject,
0777: final IImportStructureProvider structureProvider) {
0778:
0779: final MinimizedFileSystemElement[] results = new MinimizedFileSystemElement[1];
0780:
0781: BusyIndicator.showWhile(getShell().getDisplay(),
0782: new Runnable() {
0783: public void run() {
0784: //Create the root element from the supplied file system object
0785: results[0] = createRootElement(
0786: rootFileSystemObject, structureProvider);
0787: }
0788: });
0789:
0790: return results[0];
0791: }
0792:
0793: /**
0794: * Set all of the selections in the selection group to value. Implemented here
0795: * to provide access for inner classes.
0796: * @param value boolean
0797: */
0798: protected void setAllSelections(boolean value) {
0799: super .setAllSelections(value);
0800: }
0801:
0802: /**
0803: * Sets the source name of the import to be the supplied path.
0804: * Adds the name of the path to the list of items in the
0805: * source combo and selects it.
0806: *
0807: * @param path the path to be added
0808: */
0809: protected void setSourceName(String path) {
0810:
0811: if (path.length() > 0) {
0812:
0813: String[] currentItems = this .sourceNameField.getItems();
0814: int selectionIndex = -1;
0815: for (int i = 0; i < currentItems.length; i++) {
0816: if (currentItems[i].equals(path)) {
0817: selectionIndex = i;
0818: }
0819: }
0820: if (selectionIndex < 0) {
0821: int oldLength = currentItems.length;
0822: String[] newItems = new String[oldLength + 1];
0823: System.arraycopy(currentItems, 0, newItems, 0,
0824: oldLength);
0825: newItems[oldLength] = path;
0826: this .sourceNameField.setItems(newItems);
0827: selectionIndex = oldLength;
0828: }
0829: this .sourceNameField.select(selectionIndex);
0830:
0831: resetSelection();
0832: }
0833: }
0834:
0835: /**
0836: * Update the tree to only select those elements that match the selected types
0837: */
0838: protected void setupSelectionsBasedOnSelectedTypes() {
0839: ProgressMonitorDialog dialog = new ProgressMonitorJobsDialog(
0840: getContainer().getShell());
0841: final Map selectionMap = new Hashtable();
0842:
0843: final IElementFilter filter = new IElementFilter() {
0844:
0845: public void filterElements(Collection files,
0846: IProgressMonitor monitor)
0847: throws InterruptedException {
0848: if (files == null) {
0849: throw new InterruptedException();
0850: }
0851: Iterator filesList = files.iterator();
0852: while (filesList.hasNext()) {
0853: if (monitor.isCanceled()) {
0854: throw new InterruptedException();
0855: }
0856: checkFile(filesList.next());
0857: }
0858: }
0859:
0860: public void filterElements(Object[] files,
0861: IProgressMonitor monitor)
0862: throws InterruptedException {
0863: if (files == null) {
0864: throw new InterruptedException();
0865: }
0866: for (int i = 0; i < files.length; i++) {
0867: if (monitor.isCanceled()) {
0868: throw new InterruptedException();
0869: }
0870: checkFile(files[i]);
0871: }
0872: }
0873:
0874: private void checkFile(Object fileElement) {
0875: MinimizedFileSystemElement file = (MinimizedFileSystemElement) fileElement;
0876: if (isExportableExtension(file.getFileNameExtension())) {
0877: List elements = new ArrayList();
0878: FileSystemElement parent = file.getParent();
0879: if (selectionMap.containsKey(parent)) {
0880: elements = (List) selectionMap.get(parent);
0881: }
0882: elements.add(file);
0883: selectionMap.put(parent, elements);
0884: }
0885: }
0886:
0887: };
0888:
0889: IRunnableWithProgress runnable = new IRunnableWithProgress() {
0890: public void run(final IProgressMonitor monitor)
0891: throws InterruptedException {
0892: monitor
0893: .beginTask(
0894: DataTransferMessages.ImportPage_filterSelections,
0895: IProgressMonitor.UNKNOWN);
0896: getSelectedResources(filter, monitor);
0897: }
0898: };
0899:
0900: try {
0901: dialog.run(true, true, runnable);
0902: } catch (InvocationTargetException exception) {
0903: //Couldn't start. Do nothing.
0904: return;
0905: } catch (InterruptedException exception) {
0906: //Got interrupted. Do nothing.
0907: return;
0908: }
0909: // make sure that all paint operations caused by closing the progress
0910: // dialog get flushed, otherwise extra pixels will remain on the screen until
0911: // updateSelections is completed
0912: getShell().update();
0913: // The updateSelections method accesses SWT widgets so cannot be executed
0914: // as part of the above progress dialog operation since the operation forks
0915: // a new process.
0916: if (selectionMap != null) {
0917: updateSelections(selectionMap);
0918: }
0919: }
0920:
0921: /* (non-Javadoc)
0922: * Method declared on IDialogPage. Set the selection up when it becomes visible.
0923: */
0924: public void setVisible(boolean visible) {
0925: super .setVisible(visible);
0926: resetSelection();
0927: if (visible) {
0928: this .sourceNameField.setFocus();
0929: }
0930: }
0931:
0932: /**
0933: * Update the selections with those in map . Implemented here to give inner class
0934: * visibility
0935: * @param map Map - key tree elements, values Lists of list elements
0936: */
0937: protected void updateSelections(Map map) {
0938: super .updateSelections(map);
0939: }
0940:
0941: /**
0942: * Check if widgets are enabled or disabled by a change in the dialog.
0943: * Provided here to give access to inner classes.
0944: */
0945: protected void updateWidgetEnablements() {
0946: super .updateWidgetEnablements();
0947: enableButtonGroup(ensureSourceIsValid());
0948: }
0949:
0950: /**
0951: * Answer a boolean indicating whether self's source specification
0952: * widgets currently all contain valid values.
0953: */
0954: protected boolean validateSourceGroup() {
0955: File sourceDirectory = getSourceDirectory();
0956: if (sourceDirectory == null) {
0957: setMessage(SOURCE_EMPTY_MESSAGE);
0958: enableButtonGroup(false);
0959: return false;
0960: }
0961:
0962: if (sourceConflictsWithDestination(new Path(sourceDirectory
0963: .getPath()))) {
0964: setMessage(null);
0965: setErrorMessage(getSourceConflictMessage());
0966: enableButtonGroup(false);
0967: return false;
0968: }
0969:
0970: List resourcesToExport = selectionGroup
0971: .getAllWhiteCheckedItems();
0972: if (resourcesToExport.size() == 0) {
0973: setMessage(null);
0974: setErrorMessage(DataTransferMessages.FileImport_noneSelected);
0975: return false;
0976: }
0977:
0978: enableButtonGroup(true);
0979: setErrorMessage(null);
0980: return true;
0981: }
0982:
0983: /**
0984: * Returns whether the source location conflicts
0985: * with the destination resource. This will occur if
0986: * the source is already under the destination.
0987: *
0988: * @param sourcePath the path to check
0989: * @return <code>true</code> if there is a conflict, <code>false</code> if not
0990: */
0991: protected boolean sourceConflictsWithDestination(IPath sourcePath) {
0992:
0993: IContainer container = getSpecifiedContainer();
0994: if (container == null) {
0995: return false;
0996: }
0997:
0998: IPath destinationLocation = getSpecifiedContainer()
0999: .getLocation();
1000: if (destinationLocation != null) {
1001: return destinationLocation.isPrefixOf(sourcePath);
1002: }
1003: // null destination location is handled in
1004: // WizardResourceImportPage
1005: return false;
1006: }
1007:
1008: }
|