package com.tibco.as.spacebar.ui.wizards.transfer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.IOverwriteQuery; /** * The common superclass for wizard import and export pages. * <p> * This class is not intended to be subclassed outside of the workbench. * </p> * * @noextend This class is not intended to be subclassed by clients. */ public abstract class AbstractTransferWizardPage extends WizardPage implements Listener, IOverwriteQuery { // constants protected static final int SIZING_TEXT_FIELD_WIDTH = 250; protected static final int COMBO_HISTORY_LENGTH = 5; /** * Creates a new wizard page. * * @param pageName * the name of the page */ protected AbstractTransferWizardPage(String pageName) { super(pageName); } protected String getSettingKey(String id) { return getName() + "." + id; } /** * Adds an entry to a history, while taking care of duplicate history items * and excessively long histories. The assumption is made that all histories * should be of length * <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>. * * @param history * the current history * @param newEntry * the entry to add to the history */ protected String[] addToHistory(String[] history, String newEntry) { List<String> list = new ArrayList<String>(Arrays.asList(history)); addToHistory(list, newEntry); return list.toArray(new String[list.size()]); } /** * Adds an entry to a history, while taking care of duplicate history items * and excessively long histories. The assumption is made that all histories * should be of length * <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>. * * @param history * the current history * @param newEntry * the entry to add to the history */ protected void addToHistory(List<String> history, String newEntry) { history.remove(newEntry); history.add(0, newEntry); // since only one new item was added, we can be over the limit // by at most one item if (history.size() > COMBO_HISTORY_LENGTH) { history.remove(COMBO_HISTORY_LENGTH); } } /** * Creates a new label with a bold font. * * @param parent * the parent control * @param text * the label text * @return the new label control */ protected Label createBoldLabel(Composite parent, String text) { Label label = new Label(parent, SWT.NONE); label.setFont(JFaceResources.getBannerFont()); label.setText(text); GridData data = new GridData(); data.verticalAlignment = GridData.FILL; data.horizontalAlignment = GridData.FILL; label.setLayoutData(data); return label; } /** * Creates the import/export options group controls. * <p> * The <code>WizardDataTransferPage</code> implementation of this method * does nothing. Subclasses wishing to define such components should * reimplement this hook method. * </p> * * @param optionsGroup * the parent control */ protected void createOptionsGroup(Composite parent) { } /** * Creates a new label with a bold font. * * @param parent * the parent control * @param text * the label text * @return the new label control */ protected Label createPlainLabel(Composite parent, String text) { Label label = new Label(parent, SWT.NONE); label.setText(text); label.setFont(parent.getFont()); GridData data = new GridData(); data.verticalAlignment = GridData.FILL; data.horizontalAlignment = GridData.FILL; label.setLayoutData(data); return label; } /** * Creates a horizontal spacer line that fills the width of its container. * * @param parent * the parent control */ protected void createSpacer(Composite parent) { Label spacer = new Label(parent, SWT.NONE); GridData data = new GridData(); data.horizontalAlignment = GridData.FILL; data.verticalAlignment = GridData.BEGINNING; spacer.setLayoutData(data); } /** * Returns whether this page is complete. This determination is made based * upon the current contents of this page's controls. Subclasses wishing to * include their controls in this determination should override the hook * methods <code>validateSourceGroup</code> and/or * <code>validateOptionsGroup</code>. * * @return <code>true</code> if this page is complete, and * <code>false</code> if incomplete * @see #validateSourceGroup * @see #validateOptionsGroup */ protected boolean determinePageCompletion() { boolean complete = validateSourceGroup() && validateDestinationGroup() && validateOptionsGroup(); // Avoid draw flicker by not clearing the error // message unless all is valid. if (complete) { setErrorMessage(null); } return complete; } /** * Get a path from the supplied text widget. * * @return org.eclipse.core.runtime.IPath */ protected IPath getPathFromText(Text textField) { String text = textField.getText(); // Do not make an empty path absolute so as not to confuse with the root if (text.length() == 0) { return new Path(text); } return (new Path(text)).makeAbsolute(); } /** * The <code>WizardDataTransfer</code> implementation of this * <code>IOverwriteQuery</code> method asks the user whether the existing * resource at the given path should be overwritten. * * @param pathString * @return the user's reply: one of <code>"YES"</code>, <code>"NO"</code>, * <code>"ALL"</code>, or <code>"CANCEL"</code> */ public String queryOverwrite(String pathString) { Path path = new Path(pathString); String messageString; // Break the message up if there is a file name and a directory // and there are at least 2 segments. if (path.getFileExtension() == null || path.segmentCount() < 2) { messageString = NLS.bind( "''{0}'' already exists. Would you like to overwrite it?", pathString); } else { messageString = NLS .bind("Overwrite ''{0}'' in folder ''{1}''?", path .lastSegment(), path.removeLastSegments(1) .toOSString()); } final MessageDialog dialog = new MessageDialog(getContainer() .getShell(), "Question", null, messageString, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.NO_TO_ALL_LABEL, IDialogConstants.CANCEL_LABEL }, 0) { protected int getShellStyle() { return super.getShellStyle() | SWT.SHEET; } }; String[] response = new String[] { YES, ALL, NO, NO_ALL, CANCEL }; // run in syncExec because callback is from an operation, // which is probably not running in the UI thread. getControl().getDisplay().syncExec(new Runnable() { public void run() { dialog.open(); } }); return dialog.getReturnCode() < 0 ? CANCEL : response[dialog .getReturnCode()]; } /** * Restores control settings that were saved in the previous instance of * this page. * <p> * The <code>WizardDataTransferPage</code> implementation of this method * does nothing. Subclasses may override this hook method. * </p> */ protected abstract void restoreWidgetValues(); /** * Saves control settings that are to be restored in the next instance of * this page. * <p> * The <code>WizardDataTransferPage</code> implementation of this method * does nothing. Subclasses may override this hook method. * </p> */ protected abstract void saveWidgetValues(); /** * Determine if the page is complete and update the page appropriately. */ protected void updatePageCompletion() { boolean pageComplete = determinePageCompletion(); setPageComplete(pageComplete); if (pageComplete) { setErrorMessage(null); } } /** * Updates the enable state of this page's controls. * <p> * The <code>WizardDataTransferPage</code> implementation of this method * does nothing. Subclasses may extend this hook method. * </p> */ protected void updateWidgetEnablements() { boolean pageComplete = determinePageCompletion(); setPageComplete(pageComplete); if (pageComplete) { setMessage(null); } } /** * Returns whether this page's destination specification controls currently * all contain valid values. * <p> * The <code>WizardDataTransferPage</code> implementation of this method * returns <code>true</code>. Subclasses may reimplement this hook method. * </p> * * @return <code>true</code> indicating validity of all controls in the * destination specification group */ protected boolean validateDestinationGroup() { return true; } /** * Returns whether this page's options group's controls currently all * contain valid values. * <p> * The <code>WizardDataTransferPage</code> implementation of this method * returns <code>true</code>. Subclasses may reimplement this hook method. * </p> * * @return <code>true</code> indicating validity of all controls in the * options group */ protected boolean validateOptionsGroup() { return true; } /** * Returns whether this page's source specification controls currently all * contain valid values. * <p> * The <code>WizardDataTransferPage</code> implementation of this method * returns <code>true</code>. Subclasses may reimplement this hook method. * </p> * * @return <code>true</code> indicating validity of all controls in the * source specification group */ protected boolean validateSourceGroup() { return true; } /** * Get the title for an error dialog. Subclasses should override. */ protected String getErrorDialogTitle() { return "Internal error"; } protected boolean inRegularFontMode(Composite parent) { return availableRows(parent) > 50; } private int availableRows(Composite parent) { int fontHeight = (parent.getFont().getFontData())[0].getHeight(); int displayHeight = parent.getDisplay().getClientArea().height; return displayHeight / fontHeight; } public void finish() { saveWidgetValues(); } }