0001: /*******************************************************************************
0002: * Copyright (c) 2005, 2007 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.preferences;
0011:
0012: import java.io.File;
0013: import java.util.ArrayList;
0014: import java.util.Arrays;
0015: import java.util.Hashtable;
0016: import java.util.Iterator;
0017: import java.util.List;
0018: import java.util.Map;
0019:
0020: import org.eclipse.core.runtime.CoreException;
0021: import org.eclipse.core.runtime.Path;
0022: import org.eclipse.core.runtime.preferences.ConfigurationScope;
0023: import org.eclipse.core.runtime.preferences.IPreferenceFilter;
0024: import org.eclipse.core.runtime.preferences.InstanceScope;
0025: import org.eclipse.jface.dialogs.Dialog;
0026: import org.eclipse.jface.dialogs.IDialogConstants;
0027: import org.eclipse.jface.dialogs.IDialogSettings;
0028: import org.eclipse.jface.dialogs.MessageDialog;
0029: import org.eclipse.jface.resource.ImageDescriptor;
0030: import org.eclipse.jface.wizard.WizardPage;
0031: import org.eclipse.osgi.util.NLS;
0032: import org.eclipse.swt.SWT;
0033: import org.eclipse.swt.events.SelectionAdapter;
0034: import org.eclipse.swt.events.SelectionEvent;
0035: import org.eclipse.swt.events.SelectionListener;
0036: import org.eclipse.swt.graphics.Font;
0037: import org.eclipse.swt.graphics.Image;
0038: import org.eclipse.swt.layout.GridData;
0039: import org.eclipse.swt.layout.GridLayout;
0040: import org.eclipse.swt.widgets.Button;
0041: import org.eclipse.swt.widgets.Combo;
0042: import org.eclipse.swt.widgets.Composite;
0043: import org.eclipse.swt.widgets.Event;
0044: import org.eclipse.swt.widgets.FileDialog;
0045: import org.eclipse.swt.widgets.Group;
0046: import org.eclipse.swt.widgets.Label;
0047: import org.eclipse.swt.widgets.Listener;
0048: import org.eclipse.swt.widgets.Shell;
0049: import org.eclipse.swt.widgets.Table;
0050: import org.eclipse.swt.widgets.TableItem;
0051: import org.eclipse.swt.widgets.Text;
0052: import org.eclipse.swt.widgets.Widget;
0053: import org.eclipse.ui.dialogs.IOverwriteQuery;
0054: import org.eclipse.ui.internal.WorkbenchPlugin;
0055: import org.eclipse.ui.internal.preferences.PreferenceTransferElement;
0056: import org.eclipse.ui.internal.preferences.PreferenceTransferManager;
0057:
0058: /**
0059: * Base class for preference export/import pages.
0060: *
0061: * @since 3.1
0062: */
0063: public abstract class WizardPreferencesPage extends WizardPage
0064: implements Listener, IOverwriteQuery {
0065:
0066: // widgets
0067: protected Combo destinationNameField;
0068:
0069: // constants
0070: private Button destinationBrowseButton;
0071:
0072: private Button overwriteExistingFilesCheckbox;
0073:
0074: protected Table transfersTable;
0075:
0076: protected Text text;
0077:
0078: private Composite buttonComposite;
0079:
0080: private Button allButton;
0081:
0082: protected Button chooseImportsButton;
0083:
0084: private Group group;
0085:
0086: // dialog store id constants
0087: private static final String STORE_DESTINATION_NAMES_ID = "WizardPreferencesExportPage1.STORE_DESTINATION_NAMES_ID";//$NON-NLS-1$
0088:
0089: private static final String STORE_OVERWRITE_EXISTING_FILES_ID = "WizardPreferencesExportPage1.STORE_OVERWRITE_EXISTING_FILES_ID";//$NON-NLS-1$
0090:
0091: private static final String TRANSFER_ALL_PREFERENCES_ID = "WizardPreferencesExportPage1.EXPORT_ALL_PREFERENCES_ID"; //$NON-NLS-1$
0092:
0093: private Hashtable imageTable;
0094:
0095: private PreferenceTransferElement[] transfers;
0096:
0097: private String currentMessage;
0098:
0099: private static final String STORE_DESTINATION_ID = null;
0100:
0101: protected static final int COMBO_HISTORY_LENGTH = 5;
0102:
0103: /**
0104: * @param pageName
0105: */
0106: protected WizardPreferencesPage(String pageName) {
0107: super (pageName);
0108: }
0109:
0110: /**
0111: * Creates a new button with the given id.
0112: * <p>
0113: * The <code>Dialog</code> implementation of this framework method creates
0114: * a standard push button, registers for selection events including button
0115: * presses and registers default buttons with its shell. The button id is
0116: * stored as the buttons client data. Note that the parent's layout is
0117: * assumed to be a GridLayout and the number of columns in this layout is
0118: * incremented. Subclasses may override.
0119: * </p>
0120: *
0121: * @param parent
0122: * the parent composite
0123: * @param id
0124: * the id of the button (see <code>IDialogConstants.*_ID</code>
0125: * constants for standard dialog button ids)
0126: * @param label
0127: * the label from the button
0128: * @param defaultButton
0129: * <code>true</code> if the button is to be the default button,
0130: * and <code>false</code> otherwise
0131: */
0132: protected Button createButton(Composite parent, int id,
0133: String label, boolean defaultButton) {
0134: // increment the number of columns in the button bar
0135: ((GridLayout) parent.getLayout()).numColumns++;
0136:
0137: Button button = new Button(parent, SWT.PUSH);
0138: button.setFont(parent.getFont());
0139:
0140: GridData buttonData = new GridData(GridData.FILL_HORIZONTAL);
0141: button.setLayoutData(buttonData);
0142:
0143: button.setData(new Integer(id));
0144: button.setText(label);
0145:
0146: if (defaultButton) {
0147: Shell shell = parent.getShell();
0148: if (shell != null) {
0149: shell.setDefaultButton(button);
0150: }
0151: button.setFocus();
0152: }
0153: return button;
0154: }
0155:
0156: /**
0157: * Add the passed value to self's destination widget's history
0158: *
0159: * @param value
0160: * java.lang.String
0161: */
0162: protected void addDestinationItem(String value) {
0163: destinationNameField.add(value);
0164: }
0165:
0166: /**
0167: * (non-Javadoc) Method declared on IDialogPage.
0168: */
0169: public void createControl(Composite parent) {
0170: initializeDialogUnits(parent);
0171: Composite composite = new Composite(parent, SWT.NULL);
0172: composite.setLayout(new GridLayout());
0173: composite.setLayoutData(new GridData(
0174: GridData.VERTICAL_ALIGN_FILL
0175: | GridData.HORIZONTAL_ALIGN_FILL));
0176:
0177: createTransferArea(composite);
0178:
0179: restoreWidgetValues();
0180: // updateWidgetEnablements();
0181:
0182: // can not finish initially, but don't want to start with an error
0183: // message either
0184: if (!(validDestination() && validateOptionsGroup() && validateSourceGroup())) {
0185: setPageComplete(false);
0186: }
0187:
0188: setPreferenceTransfers();
0189: setControl(composite);
0190:
0191: giveFocusToDestination();
0192: Dialog.applyDialogFont(composite);
0193: }
0194:
0195: /**
0196: * @param composite
0197: */
0198: protected abstract void createTransferArea(Composite composite);
0199:
0200: /**
0201: * Validate the destination group.
0202: * @return <code>true</code> if the group is valid. If
0203: * not set the error message and return <code>false</code>.
0204: */
0205: protected boolean validateDestinationGroup() {
0206: if (!validDestination()) {
0207: currentMessage = getInvalidDestinationMessage();
0208: return false;
0209: }
0210:
0211: return true;
0212: }
0213:
0214: /**
0215: * Return the message that indicates an invalid destination.
0216: * @return String
0217: */
0218: abstract protected String getInvalidDestinationMessage();
0219:
0220: private String getNoOptionsMessage() {
0221: return PreferencesMessages.WizardPreferencesPage_noOptionsSelected;
0222: }
0223:
0224: protected boolean validDestination() {
0225: File file = new File(getDestinationValue());
0226: return !(file.getPath().length() <= 0 || file.isDirectory());
0227: }
0228:
0229: /**
0230: *
0231: */
0232: protected void setPreferenceTransfers() {
0233: PreferenceTransferElement[] transfers = getTransfers();
0234: transfersTable.removeAll();
0235: for (int i = 0; i < transfers.length; i++) {
0236: PreferenceTransferElement element = transfers[i];
0237: createItem(element, transfersTable);
0238: }
0239: }
0240:
0241: /*
0242: * return the PreferenceTransgerElements specified
0243: */
0244: protected PreferenceTransferElement[] getTransfers() {
0245: if (transfers == null) {
0246: transfers = PreferenceTransferManager
0247: .getPreferenceTransfers();
0248: }
0249: return transfers;
0250: }
0251:
0252: /**
0253: * @param element
0254: * @param table
0255: */
0256: private void createItem(PreferenceTransferElement element,
0257: Table table) {
0258: TableItem item = new TableItem(table, SWT.CHECK);
0259: item.setText(element.getName());
0260: item.setData(element);
0261: ImageDescriptor descriptor = element.getImageDescriptor();
0262: Image image = null;
0263: if (descriptor != null) {
0264: Hashtable images = getImageTable();
0265: image = (Image) images.get(descriptor);
0266: if (image == null) {
0267: image = descriptor.createImage();
0268: images.put(descriptor, image);
0269: }
0270: item.setImage(image);
0271: }
0272:
0273: }
0274:
0275: /**
0276: * @return <code>Hashtable</code> the table of images
0277: */
0278: private Hashtable getImageTable() {
0279: if (imageTable == null) {
0280: imageTable = new Hashtable(10);
0281: }
0282: return imageTable;
0283: }
0284:
0285: /**
0286: * @param composite
0287: */
0288: protected void createTransfersList(Composite composite) {
0289:
0290: allButton = new Button(composite, SWT.RADIO);
0291: allButton.setText(getAllButtonText());
0292:
0293: chooseImportsButton = new Button(composite, SWT.RADIO);
0294: chooseImportsButton.setText(getChooseButtonText());
0295:
0296: group = new Group(composite, SWT.NONE);
0297: group
0298: .setText(PreferencesMessages.WizardPreferencesExportPage1_preferences);
0299: GridData data = new GridData(GridData.FILL_BOTH);
0300: data.horizontalSpan = 2;
0301: group.setLayoutData(data);
0302:
0303: GridLayout layout = new GridLayout();
0304: group.setLayout(layout);
0305:
0306: transfersTable = new Table(group, SWT.CHECK | SWT.BORDER);
0307: transfersTable.setLayoutData(new GridData(GridData.FILL_BOTH));
0308:
0309: Label description = new Label(group, SWT.NONE);
0310: description
0311: .setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
0312: description
0313: .setText(PreferencesMessages.WizardPreferences_description);
0314:
0315: text = new Text(group, SWT.V_SCROLL | SWT.READ_ONLY
0316: | SWT.BORDER | SWT.WRAP);
0317: text.setLayoutData(new GridData(GridData.FILL_BOTH));
0318:
0319: SelectionListener selection = new SelectionListener() {
0320:
0321: public void widgetSelected(SelectionEvent e) {
0322: // Selecting an item in the list forces
0323: // the radio buttons to get selected
0324: if (e.widget == transfersTable) {
0325: updateState(e);
0326: updateDescription();
0327: }
0328: updatePageCompletion();
0329: }
0330:
0331: private void updateState(SelectionEvent e) {
0332: if (((TableItem) e.item).getChecked()) {
0333: allButton.setSelection(false);
0334: chooseImportsButton.setSelection(true);
0335: }
0336: }
0337:
0338: public void widgetDefaultSelected(SelectionEvent e) {
0339: widgetSelected(e);
0340: }
0341:
0342: private void updateDescription() {
0343: if (transfersTable.getSelectionCount() > 0) {
0344: TableItem item = transfersTable.getSelection()[0];
0345: text.setText(((PreferenceTransferElement) item
0346: .getData()).getDescription());
0347: } else {
0348: text.setText(""); //$NON-NLS-1$
0349: }
0350: }
0351: };
0352:
0353: transfersTable.addSelectionListener(selection);
0354: chooseImportsButton.addSelectionListener(selection);
0355: allButton.addSelectionListener(selection);
0356:
0357: addSelectionButtons(group);
0358:
0359: }
0360:
0361: protected abstract String getChooseButtonText();
0362:
0363: protected abstract String getAllButtonText();
0364:
0365: /**
0366: * Add the selection and deselection buttons to the composite.
0367: *
0368: * @param composite
0369: * org.eclipse.swt.widgets.Composite
0370: */
0371: private void addSelectionButtons(Composite composite) {
0372: Font parentFont = composite.getFont();
0373: buttonComposite = new Composite(composite, SWT.NONE);
0374: GridLayout layout = new GridLayout();
0375: layout.numColumns = 2;
0376: buttonComposite.setLayout(layout);
0377: GridData data = new GridData(GridData.GRAB_HORIZONTAL);
0378: data.grabExcessHorizontalSpace = true;
0379: buttonComposite.setLayoutData(data);
0380: buttonComposite.setFont(parentFont);
0381:
0382: Button selectButton = createButton(buttonComposite,
0383: IDialogConstants.SELECT_ALL_ID,
0384: PreferencesMessages.SelectionDialog_selectLabel, false);
0385:
0386: SelectionListener listener = new SelectionAdapter() {
0387: public void widgetSelected(SelectionEvent e) {
0388: setAllChecked(true);
0389: updatePageCompletion();
0390: }
0391: };
0392: selectButton.addSelectionListener(listener);
0393: selectButton.setFont(parentFont);
0394:
0395: Button deselectButton = createButton(buttonComposite,
0396: IDialogConstants.DESELECT_ALL_ID,
0397: PreferencesMessages.SelectionDialog_deselectLabel,
0398: false);
0399:
0400: listener = new SelectionAdapter() {
0401: public void widgetSelected(SelectionEvent e) {
0402: setAllChecked(false);
0403: updatePageCompletion();
0404: }
0405: };
0406: deselectButton.addSelectionListener(listener);
0407: deselectButton.setFont(parentFont);
0408: }
0409:
0410: /**
0411: * @param bool
0412: */
0413: protected void setAllChecked(boolean bool) {
0414: TableItem[] items = transfersTable.getItems();
0415: for (int i = 0; i < items.length; i++) {
0416: TableItem item = items[i];
0417: item.setChecked(bool);
0418: }
0419: }
0420:
0421: /**
0422: * Create the export destination specification widgets
0423: *
0424: * @param parent
0425: * org.eclipse.swt.widgets.Composite
0426: */
0427: protected void createDestinationGroup(Composite parent) {
0428: // destination specification group
0429: Composite destinationSelectionGroup = new Composite(parent,
0430: SWT.NONE);
0431: GridLayout layout = new GridLayout();
0432: layout.numColumns = 3;
0433: destinationSelectionGroup.setLayout(layout);
0434: destinationSelectionGroup.setLayoutData(new GridData(
0435: GridData.HORIZONTAL_ALIGN_FILL
0436: | GridData.VERTICAL_ALIGN_FILL));
0437:
0438: Label dest = new Label(destinationSelectionGroup, SWT.NONE);
0439: dest.setText(getDestinationLabel());
0440:
0441: // destination name entry field
0442: destinationNameField = new Combo(destinationSelectionGroup,
0443: SWT.SINGLE | SWT.BORDER);
0444: destinationNameField.addListener(SWT.Modify, this );
0445: destinationNameField.addListener(SWT.Selection, this );
0446: GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
0447: | GridData.GRAB_HORIZONTAL);
0448: destinationNameField.setLayoutData(data);
0449:
0450: // destination browse button
0451: destinationBrowseButton = new Button(destinationSelectionGroup,
0452: SWT.PUSH);
0453: destinationBrowseButton
0454: .setText(PreferencesMessages.PreferencesExport_browse);
0455: destinationBrowseButton.setLayoutData(new GridData(
0456: GridData.HORIZONTAL_ALIGN_FILL));
0457: destinationBrowseButton.addListener(SWT.Selection, this );
0458:
0459: new Label(parent, SWT.NONE); // vertical spacer
0460: }
0461:
0462: /**
0463: * Create the export options specification widgets.
0464: *
0465: * @param parent
0466: * org.eclipse.swt.widgets.Composite
0467: */
0468: protected void createOptionsGroup(Composite parent) {
0469: // options group
0470:
0471: Composite optionsGroup = new Composite(parent, SWT.NONE);
0472: GridLayout layout = new GridLayout();
0473: layout.marginHeight = 0;
0474: optionsGroup.setLayout(layout);
0475: optionsGroup.setLayoutData(new GridData(
0476: GridData.HORIZONTAL_ALIGN_FILL
0477: | GridData.GRAB_HORIZONTAL));
0478:
0479: // overwrite... checkbox
0480: overwriteExistingFilesCheckbox = new Button(optionsGroup,
0481: SWT.CHECK | SWT.LEFT);
0482: overwriteExistingFilesCheckbox
0483: .setText(PreferencesMessages.ExportFile_overwriteExisting);
0484:
0485: }
0486:
0487: /**
0488: * Attempts to ensure that the specified directory exists on the local file
0489: * system. Answers a boolean indicating success.
0490: *
0491: * @return boolean
0492: * @param directory
0493: * java.io.File
0494: */
0495: protected boolean ensureDirectoryExists(File directory) {
0496: if (!directory.exists()) {
0497: if (!queryYesNoQuestion(PreferencesMessages.PreferencesExport_createTargetDirectory)) {
0498: return false;
0499: }
0500:
0501: if (!directory.mkdirs()) {
0502: MessageDialog
0503: .openError(
0504: getContainer().getShell(),
0505: PreferencesMessages.PreferencesExport_error,
0506: PreferencesMessages.PreferencesExport_directoryCreationError);
0507: return false;
0508: }
0509: }
0510: return true;
0511: }
0512:
0513: /**
0514: * Displays a Yes/No question to the user with the specified message and
0515: * returns the user's response.
0516: *
0517: * @param message
0518: * the question to ask
0519: * @return <code>true</code> for Yes, and <code>false</code> for No
0520: */
0521: protected boolean queryYesNoQuestion(String message) {
0522: MessageDialog dialog = new MessageDialog(getContainer()
0523: .getShell(), PreferencesMessages.Question,
0524: (Image) null, message, MessageDialog.NONE,
0525: new String[] { IDialogConstants.YES_LABEL,
0526: IDialogConstants.NO_LABEL }, 0);
0527: // ensure yes is the default
0528:
0529: return dialog.open() == 0;
0530: }
0531:
0532: /**
0533: * If the target for export does not exist then attempt to create it. Answer
0534: * a boolean indicating whether the target exists (ie.- if it either
0535: * pre-existed or this method was able to create it)
0536: *
0537: * @return boolean
0538: */
0539: protected boolean ensureTargetIsValid(File file) {
0540: if (file.exists()) {
0541: if (!getOverwriteExisting()) {
0542: String msg = NLS
0543: .bind(
0544: PreferencesMessages.WizardPreferencesExportPage1_overwrite,
0545: file.getAbsolutePath());
0546: if (!queryYesNoQuestion(msg)) {
0547: return false;
0548: }
0549: }
0550: file.delete();
0551: } else if (!file.isDirectory()) {
0552: File parent = file.getParentFile();
0553: if (parent != null) {
0554: file.getParentFile().mkdirs();
0555: }
0556: }
0557: return true;
0558: }
0559:
0560: /*
0561: * (non-Javadoc)
0562: *
0563: * @see org.eclipse.ui.dialogs.WizardDataTransferPage#saveWidgetValues()
0564: */
0565: protected void saveWidgetValues() {
0566: // allow subclasses to save values
0567: internalSaveWidgetValues();
0568: }
0569:
0570: /**
0571: * The Finish button was pressed. Try to do the required work now and answer
0572: * a boolean indicating success. If false is returned then the wizard will
0573: * not close.
0574: *
0575: * @return boolean
0576: */
0577: public boolean finish() {
0578: // about to invoke the operation so save our state
0579: saveWidgetValues();
0580:
0581: IPreferenceFilter[] transfers = null;
0582:
0583: if (getTransferAll()) {
0584: // export all
0585: transfers = new IPreferenceFilter[1];
0586:
0587: // For export all create a preference filter that can export
0588: // all nodes of the Instance and Configuration scopes
0589: transfers[0] = new IPreferenceFilter() {
0590:
0591: public String[] getScopes() {
0592: return new String[] { InstanceScope.SCOPE,
0593: ConfigurationScope.SCOPE };
0594: }
0595:
0596: public Map getMapping(String scope) {
0597: return null;
0598: }
0599: };
0600: } else {
0601: transfers = getFilters();
0602: }
0603:
0604: boolean success = transfer(transfers);
0605: // if it was a successful tranfer then store the name of the file to use
0606: // it on the next export
0607: if (success) {
0608: saveWidgetValues();
0609: }
0610: return success;
0611: }
0612:
0613: /**
0614: * @return the preference transfer filters
0615: */
0616: protected IPreferenceFilter[] getFilters() {
0617: IPreferenceFilter[] filters = null;
0618: PreferenceTransferElement[] transferElements;
0619: transferElements = getPreferenceTransferElements();
0620: if (transferElements != null) {
0621: filters = new IPreferenceFilter[transferElements.length];
0622: for (int j = 0; j < transferElements.length; j++) {
0623: PreferenceTransferElement element = transferElements[j];
0624: try {
0625: filters[j] = element.getFilter();
0626: } catch (CoreException e) {
0627: WorkbenchPlugin.log(e.getMessage(), e);
0628: }
0629: }
0630: } else {
0631: filters = new IPreferenceFilter[0];
0632: }
0633:
0634: return filters;
0635: }
0636:
0637: /**
0638: * @return the list of transfer elements
0639: */
0640: protected PreferenceTransferElement[] getPreferenceTransferElements() {
0641: PreferenceTransferElement[] transferElements;
0642: // export selected transfer types
0643: TableItem[] items = transfersTable.getItems();
0644: List transferList = new ArrayList();
0645: for (int i = 0; i < items.length; i++) {
0646: TableItem item = items[i];
0647: if (item.getChecked()) {
0648: transferList.add(item.getData());
0649: }
0650: }
0651: transferElements = new PreferenceTransferElement[transferList
0652: .size()];
0653: int i = 0;
0654: for (Iterator iter = transferList.iterator(); iter.hasNext();) {
0655: transferElements[i] = (PreferenceTransferElement) iter
0656: .next();
0657: i++;
0658: }
0659: return transferElements;
0660: }
0661:
0662: /**
0663: * @param transfers
0664: * @return boolean
0665: */
0666: protected abstract boolean transfer(IPreferenceFilter[] transfers);
0667:
0668: /**
0669: * Check whether the internal state of the page is complete and update the
0670: * dialog
0671: */
0672: public void setPageComplete() {
0673: boolean complete = true;
0674:
0675: if (!determinePageCompletion()) {
0676: complete = false;
0677: }
0678:
0679: super .setPageComplete(complete);
0680: }
0681:
0682: /**
0683: * Returns whether this page is complete. This determination is made based
0684: * upon the current contents of this page's controls. Subclasses wishing to
0685: * include their controls in this determination should override the hook
0686: * methods <code>validateSourceGroup</code> and/or
0687: * <code>validateOptionsGroup</code>.
0688: *
0689: * @return <code>true</code> if this page is complete, and
0690: * <code>false</code> if incomplete
0691: * @see #validateSourceGroup
0692: * @see #validateOptionsGroup
0693: */
0694: protected boolean determinePageCompletion() {
0695:
0696: // validate groups in order of priority so error message is the most important one
0697: boolean complete = validateSourceGroup()
0698: && validateDestinationGroup() && validateOptionsGroup();
0699:
0700: // Avoid draw flicker by not clearing the error
0701: // message unless all is valid.
0702: if (complete) {
0703: setErrorMessage(null);
0704: } else {
0705: setErrorMessage(currentMessage);
0706: }
0707:
0708: return complete;
0709: }
0710:
0711: /**
0712: * Returns whether this page's options group's controls currently all
0713: * contain valid values.
0714: * <p>
0715: * The <code>WizardPreferencesPage</code> implementation of this method
0716: * returns <code>true</code> if the button to transfer all preferences is
0717: * selected OR at least one of the individual items are checked. Subclasses
0718: * may reimplement this method.
0719: * </p>
0720: *
0721: * @return <code>true</code> indicating validity of all controls in the
0722: * options group
0723: */
0724: protected boolean validateOptionsGroup() {
0725: if (chooseImportsButton.getSelection()) {
0726: TableItem[] items = transfersTable.getItems();
0727: for (int i = 0; i < items.length; i++) {
0728: TableItem item = items[i];
0729: if (item.getChecked()) {
0730: return true;
0731: }
0732: }
0733: currentMessage = getNoOptionsMessage();
0734: return false;
0735: }
0736: return true;
0737: }
0738:
0739: /**
0740: * Returns whether this page's source specification controls currently all
0741: * contain valid values.
0742: * <p>
0743: * The <code>WizardDataTransferPage</code> implementation of this method
0744: * returns <code>true</code>. Subclasses may reimplement this hook
0745: * method.
0746: * </p>
0747: *
0748: * @return <code>true</code> indicating validity of all controls in the
0749: * source specification group
0750: */
0751: protected boolean validateSourceGroup() {
0752: return true;
0753: }
0754:
0755: /**
0756: * Answer the string to display in self as the destination type
0757: *
0758: * @return java.lang.String
0759: */
0760: protected abstract String getDestinationLabel();
0761:
0762: /**
0763: * Answer the contents of self's destination specification widget
0764: *
0765: * @return java.lang.String
0766: */
0767: protected String getDestinationValue() {
0768: return destinationNameField.getText().trim();
0769: }
0770:
0771: /**
0772: * Set the current input focus to self's destination entry field
0773: */
0774: protected void giveFocusToDestination() {
0775: destinationNameField.setFocus();
0776: }
0777:
0778: /**
0779: * Open an appropriate destination browser so that the user can specify a
0780: * source to import from
0781: */
0782: protected void handleDestinationBrowseButtonPressed() {
0783: FileDialog dialog = new FileDialog(getContainer().getShell(),
0784: getFileDialogStyle());
0785: dialog.setText(getFileDialogTitle());
0786: dialog.setFilterPath(getDestinationValue());
0787: dialog.setFilterExtensions(new String[] { "*.epf", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
0788: String selectedFileName = dialog.open();
0789:
0790: if (selectedFileName != null) {
0791: setDestinationValue(selectedFileName);
0792: }
0793: }
0794:
0795: protected abstract String getFileDialogTitle();
0796:
0797: protected abstract int getFileDialogStyle();
0798:
0799: /**
0800: * Handle all events and enablements for widgets in this page
0801: *
0802: * @param e
0803: * Event
0804: */
0805: public void handleEvent(Event e) {
0806: Widget source = e.widget;
0807:
0808: if (source == destinationBrowseButton) {
0809: handleDestinationBrowseButtonPressed();
0810: }
0811:
0812: updatePageCompletion();
0813: }
0814:
0815: /**
0816: * Determine if the page is complete and update the page appropriately.
0817: */
0818: protected void updatePageCompletion() {
0819: boolean pageComplete = determinePageCompletion();
0820: setPageComplete(pageComplete);
0821: if (pageComplete) {
0822: setMessage(null);
0823: }
0824: }
0825:
0826: /**
0827: * Hook method for saving widget values for restoration by the next instance
0828: * of this class.
0829: */
0830: protected void internalSaveWidgetValues() {
0831: // update directory names history
0832: IDialogSettings settings = getDialogSettings();
0833: if (settings != null) {
0834: String[] directoryNames = settings
0835: .getArray(STORE_DESTINATION_NAMES_ID);
0836: if (directoryNames == null) {
0837: directoryNames = new String[0];
0838: }
0839:
0840: directoryNames = addToHistory(directoryNames,
0841: getDestinationValue());
0842: settings.put(STORE_DESTINATION_NAMES_ID, directoryNames);
0843: String current = getDestinationValue();
0844: if (current != null && !current.equals("")) { //$NON-NLS-1$
0845: settings.put(STORE_DESTINATION_ID, current);
0846: }
0847: // options
0848: if (overwriteExistingFilesCheckbox != null) {
0849: settings.put(STORE_OVERWRITE_EXISTING_FILES_ID,
0850: overwriteExistingFilesCheckbox.getSelection());
0851: }
0852: settings.put(TRANSFER_ALL_PREFERENCES_ID, allButton
0853: .getSelection());
0854:
0855: }
0856: }
0857:
0858: /**
0859: * Adds an entry to a history, while taking care of duplicate history items
0860: * and excessively long histories. The assumption is made that all histories
0861: * should be of length <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>.
0862: *
0863: * @param history the current history
0864: * @param newEntry the entry to add to the history
0865: */
0866: protected String[] addToHistory(String[] history, String newEntry) {
0867: java.util.ArrayList l = new java.util.ArrayList(Arrays
0868: .asList(history));
0869: addToHistory(l, newEntry);
0870: String[] r = new String[l.size()];
0871: l.toArray(r);
0872: return r;
0873: }
0874:
0875: /**
0876: * Adds an entry to a history, while taking care of duplicate history items
0877: * and excessively long histories. The assumption is made that all histories
0878: * should be of length <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>.
0879: *
0880: * @param history the current history
0881: * @param newEntry the entry to add to the history
0882: */
0883: protected void addToHistory(List history, String newEntry) {
0884: history.remove(newEntry);
0885: history.add(0, newEntry);
0886:
0887: // since only one new item was added, we can be over the limit
0888: // by at most one item
0889: if (history.size() > COMBO_HISTORY_LENGTH) {
0890: history.remove(COMBO_HISTORY_LENGTH);
0891: }
0892: }
0893:
0894: /**
0895: * Hook method for restoring widget values to the values that they held last
0896: * time this wizard was used to completion.
0897: */
0898: protected void restoreWidgetValues() {
0899: IDialogSettings settings = getDialogSettings();
0900: boolean all = true;
0901: if (settings != null) {
0902: String[] directoryNames = settings
0903: .getArray(STORE_DESTINATION_NAMES_ID);
0904: if (directoryNames != null) {
0905: // destination
0906: setDestinationValue(directoryNames[0]);
0907: for (int i = 0; i < directoryNames.length; i++) {
0908: addDestinationItem(directoryNames[i]);
0909: }
0910:
0911: String current = settings.get(STORE_DESTINATION_ID);
0912: if (current != null) {
0913: setDestinationValue(current);
0914: }
0915: // options
0916: if (overwriteExistingFilesCheckbox != null) {
0917: overwriteExistingFilesCheckbox
0918: .setSelection(settings
0919: .getBoolean(STORE_OVERWRITE_EXISTING_FILES_ID));
0920: }
0921: all = settings.getBoolean(TRANSFER_ALL_PREFERENCES_ID);
0922: }
0923: }
0924: if (all) {
0925: allButton.setSelection(true);
0926: } else {
0927: chooseImportsButton.setSelection(true);
0928: }
0929:
0930: }
0931:
0932: private boolean getOverwriteExisting() {
0933: return overwriteExistingFilesCheckbox.getSelection();
0934: }
0935:
0936: private boolean getTransferAll() {
0937: return allButton.getSelection();
0938: }
0939:
0940: /**
0941: * Set the contents of self's destination specification widget to the passed
0942: * value
0943: *
0944: * @param value
0945: * java.lang.String
0946: */
0947: protected void setDestinationValue(String value) {
0948: destinationNameField.setText(value);
0949: }
0950:
0951: /*
0952: * (non-Javadoc)
0953: *
0954: * @see org.eclipse.jface.dialogs.DialogPage#dispose()
0955: */
0956: public void dispose() {
0957: super .dispose();
0958: if (imageTable == null) {
0959: return;
0960: }
0961:
0962: for (Iterator i = imageTable.values().iterator(); i.hasNext();) {
0963: ((Image) i.next()).dispose();
0964: }
0965: imageTable = null;
0966: transfers = null;
0967: }
0968:
0969: /*
0970: * (non-Javadoc)
0971: *
0972: * @see org.eclipse.ui.dialogs.WizardDataTransferPage#allowNewContainerName()
0973: */
0974: protected boolean allowNewContainerName() {
0975: return true;
0976: }
0977:
0978: /**
0979: * The <code>WizardDataTransfer</code> implementation of this
0980: * <code>IOverwriteQuery</code> method asks the user whether the existing
0981: * resource at the given path should be overwritten.
0982: *
0983: * @param pathString
0984: * @return the user's reply: one of <code>"YES"</code>, <code>"NO"</code>,
0985: * <code>"ALL"</code>, or <code>"CANCEL"</code>
0986: */
0987: public String queryOverwrite(String pathString) {
0988:
0989: Path path = new Path(pathString);
0990:
0991: String messageString;
0992: // Break the message up if there is a file name and a directory
0993: // and there are at least 2 segments.
0994: if (path.getFileExtension() == null || path.segmentCount() < 2) {
0995: messageString = NLS
0996: .bind(
0997: PreferencesMessages.WizardDataTransfer_existsQuestion,
0998: pathString);
0999: } else {
1000: messageString = NLS
1001: .bind(
1002: PreferencesMessages.WizardDataTransfer_overwriteNameAndPathQuestion,
1003: path.lastSegment(), path
1004: .removeLastSegments(1).toOSString());
1005: }
1006:
1007: final MessageDialog dialog = new MessageDialog(getContainer()
1008: .getShell(), PreferencesMessages.Question, null,
1009: messageString, MessageDialog.QUESTION, new String[] {
1010: IDialogConstants.YES_LABEL,
1011: IDialogConstants.YES_TO_ALL_LABEL,
1012: IDialogConstants.NO_LABEL,
1013: IDialogConstants.NO_TO_ALL_LABEL,
1014: IDialogConstants.CANCEL_LABEL }, 0);
1015: String[] response = new String[] { YES, ALL, NO, NO_ALL, CANCEL };
1016: // run in syncExec because callback is from an operation,
1017: // which is probably not running in the UI thread.
1018: getControl().getDisplay().syncExec(new Runnable() {
1019: public void run() {
1020: dialog.open();
1021: }
1022: });
1023: return dialog.getReturnCode() < 0 ? CANCEL : response[dialog
1024: .getReturnCode()];
1025: }
1026: }
|