| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials! |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog font |
| * should be activated and used by other components. |
| ************************************************************************/ |
| package org.eclipse.ui.internal.ide.dialogs; |
| |
| import java.io.File; |
| import java.util.Set; |
| import org.eclipse.core.resources.IPathVariableManager; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jface.dialogs.*; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.*; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.layout.*; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; |
| |
| /** |
| * Dialog that prompts the user for defining a variable's name and value. It |
| * supports creating a new variable or editing an existing one. The difference |
| * between the two uses is just a matter of which messages to present to the |
| * user and whether the "Ok" button starts enabled or not. |
| */ |
| public class PathVariableDialog extends TitleAreaDialog { |
| |
| // UI widgets |
| private Button okButton; |
| private Label variableNameLabel; |
| private Label variableValueLabel; |
| private Text variableNameField; |
| private Text variableValueField; |
| private Button fileButton; |
| private Button folderButton; |
| |
| /** |
| * This dialog type: <code>NEW_VARIABLE</code> or |
| * <code>EXISTING_VARIABLE</code>. |
| */ |
| private int type; |
| /** |
| * The type of variable that can be edited in this dialog. |
| * <code>IResource.FILE</code> or <code>IResource.FOLDER</code> |
| */ |
| private int variableType; |
| /** |
| * The name of the variable being edited. |
| */ |
| private String variableName; |
| /** |
| * The value of the variable being edited. |
| */ |
| private String variableValue; |
| /** |
| * The original name of the variable being edited. It is used when testing |
| * if the current variable's name is already in use. |
| */ |
| private String originalName; |
| |
| /** |
| * Used to select the proper message depending on the current mode |
| * (new/existing variable). |
| */ |
| private String typeKeySuffix; |
| |
| /** |
| * Reference to the path variable manager. It is used for validating |
| * variable names. |
| */ |
| private IPathVariableManager pathVariableManager; |
| |
| /** |
| * Set of variable names currently in use. Used when warning the user that |
| * the currently selected name is already in use by another variable. |
| */ |
| private Set namesInUse; |
| |
| /** |
| * The current validation status. Its value can be one of the following:<ul> |
| * <li><code>IMessageProvider.NONE</code> (default);</li> |
| * <li><code>IMessageProvider.WARNING</code>;</li> |
| * <li><code>IMessageProvider.ERROR</code>;</li> |
| * </ul> |
| * Used when validating the user input. |
| */ |
| private int validationStatus; |
| |
| /** |
| * The current validation message generated by the last |
| * call to a <code>validate</code> method. |
| */ |
| private String validationMessage; |
| |
| /** |
| * Whether a variable name has been entered. |
| */ |
| private boolean nameEntered = false; |
| |
| /** |
| * Whether a variable location has been entered. |
| */ |
| private boolean locationEntered = false; |
| |
| /** |
| * The standard message to be shown when there are no problems being |
| * reported. |
| */ |
| final private String standardMessage; |
| |
| /** |
| * Constant for defining this dialog as intended to create a new variable |
| * (value = 1). |
| */ |
| public final static int NEW_VARIABLE = 1; |
| /** |
| * Constant for defining this dialog as intended to edit an existing |
| * variable (value = 2). |
| */ |
| public final static int EXISTING_VARIABLE = 2; |
| |
| /** |
| * Constructs a dialog for editing a new/existing path variable. |
| * |
| * @param parentShell the parent shell |
| * @param type the dialog type: <code>NEW_VARIABLE</code> or |
| * <code>EXISTING_VARIABLE</code> |
| * @param variableType the type of variable that can be edited in |
| * this dialog. <code>IResource.FILE</code> or <code>IResource.FOLDER</code> |
| * @param pathVariableManager a reference to the path variable manager |
| * @param namesInUse a set of variable names currently in use |
| */ |
| public PathVariableDialog(Shell parentShell, int type, int variableType, IPathVariableManager pathVariableManager, Set namesInUse) { |
| super(parentShell); |
| this.type = type; |
| this.typeKeySuffix = type == NEW_VARIABLE ? "newVariable" : "existingVariable"; //$NON-NLS-1$ //$NON-NLS-2$ |
| this.variableName = ""; //$NON-NLS-1$ |
| this.variableValue = ""; //$NON-NLS-1$ |
| this.variableType = variableType; |
| this.pathVariableManager = pathVariableManager; |
| this.namesInUse = namesInUse; |
| |
| this.standardMessage = IDEWorkbenchMessages.getString("PathVariableDialog.message." + typeKeySuffix); //$NON-NLS-1$ |
| } |
| /** |
| * Configures this dialog's shell, setting the shell's text. |
| * |
| * @see org.eclipse.jface.window.Window#configureShell(Shell) |
| */ |
| protected void configureShell(Shell shell) { |
| super.configureShell(shell); |
| shell.setText(IDEWorkbenchMessages.getString("PathVariableDialog.shellTitle." + typeKeySuffix)); //$NON-NLS-1$ |
| } |
| /** |
| * Creates and returns the contents of this dialog (except for the button bar). |
| * |
| * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea |
| */ |
| protected Control createDialogArea(Composite parent) { |
| // top level composite |
| Composite parentComposite = (Composite) super.createDialogArea(parent); |
| |
| // creates dialog area composite |
| Composite contents = createComposite(parentComposite); |
| |
| // creates and lay outs dialog area widgets |
| createWidgets(contents, parent.getFont()); |
| |
| // validate possibly already incorrect variable definitions |
| if (type == EXISTING_VARIABLE) { |
| nameEntered = locationEntered = true; |
| validateVariableValue(); |
| } |
| |
| return contents; |
| } |
| |
| /** |
| * Creates and configures this dialog's main composite. |
| * |
| * @param parentComposite parent's composite |
| * @return this dialog's main composite |
| */ |
| private Composite createComposite(Composite parentComposite) { |
| // creates a composite with standard margins and spacing |
| Composite contents = new Composite(parentComposite, SWT.NONE); |
| |
| FormLayout layout = new FormLayout(); |
| |
| layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); |
| layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); |
| |
| contents.setLayout(layout); |
| contents.setFont(parentComposite.getFont()); |
| |
| setTitle(IDEWorkbenchMessages.getString("PathVariableDialog.dialogTitle." + typeKeySuffix)); //$NON-NLS-1$ |
| setMessage(standardMessage); |
| return contents; |
| } |
| |
| /** |
| * Creates widgets for this dialog. |
| * |
| * @param parent the parent composite where to create widgets |
| * @param contents |
| */ |
| private void createWidgets(Composite contents, Font font) { |
| FormData data; |
| |
| String nameLabelText = IDEWorkbenchMessages.getString("PathVariableDialog.variableName"); //$NON-NLS-1$ |
| String valueLabelText = IDEWorkbenchMessages.getString("PathVariableDialog.variableValue"); //$NON-NLS-1$ |
| |
| // variable name label |
| variableNameLabel = new Label(contents, SWT.LEFT); |
| variableNameLabel.setText(nameLabelText); |
| |
| data = new FormData(); |
| variableNameLabel.setLayoutData(data); |
| variableNameLabel.setFont(font); |
| |
| // variable value label |
| variableValueLabel = new Label(contents, SWT.LEFT); |
| variableValueLabel.setText(valueLabelText); |
| |
| data = new FormData(); |
| data.top = new FormAttachment(variableNameLabel, convertVerticalDLUsToPixels(10)); |
| variableValueLabel.setLayoutData(data); |
| variableValueLabel.setFont(font); |
| |
| // the larger label will be used in the left attachments for the fields |
| Label largerLabel = nameLabelText.length() > valueLabelText.length() ? variableNameLabel : variableValueLabel; |
| |
| // variable name field |
| variableNameField = new Text(contents, SWT.SINGLE | SWT.BORDER); |
| variableNameField.setText(variableName); |
| |
| data = new FormData(); |
| data.width = convertWidthInCharsToPixels(50); |
| data.left = new FormAttachment(largerLabel, convertHorizontalDLUsToPixels(5)); |
| variableNameField.setLayoutData(data); |
| variableNameField.setFont(font); |
| variableNameField.setFocus(); |
| |
| variableNameField.addModifyListener(new ModifyListener() { |
| public void modifyText(ModifyEvent event) { |
| variableNameModified(); |
| } |
| }); |
| |
| // variable value field |
| variableValueField = new Text(contents, SWT.SINGLE | SWT.BORDER); |
| variableValueField.setText(variableValue); |
| |
| data = new FormData(); |
| data.width = convertWidthInCharsToPixels(50); |
| data.left = new FormAttachment(largerLabel, convertHorizontalDLUsToPixels(5)); |
| data.top = new FormAttachment(variableNameLabel, convertVerticalDLUsToPixels(10)); |
| variableValueField.setLayoutData(data); |
| variableValueField.setFont(font); |
| |
| variableValueField.addModifyListener(new ModifyListener() { |
| public void modifyText(ModifyEvent event) { |
| variableValueModified(); |
| } |
| }); |
| |
| // select file path button |
| fileButton = new Button(contents, SWT.PUSH); |
| fileButton.setText(IDEWorkbenchMessages.getString("PathVariableDialog.file")); //$NON-NLS-1$ |
| if ((variableType & IResource.FILE) == 0) |
| fileButton.setEnabled(false); |
| |
| data = setButtonFormLayoutData(fileButton); |
| data.top = new FormAttachment(variableNameLabel, convertVerticalDLUsToPixels(10)); |
| data.left = new FormAttachment(variableValueField, convertHorizontalDLUsToPixels(10)); |
| data.right = new FormAttachment(100, -5); |
| fileButton.setLayoutData(data); |
| fileButton.setFont(font); |
| |
| fileButton.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| selectFile(); |
| } |
| }); |
| |
| // select folder path button |
| folderButton = new Button(contents, SWT.PUSH); |
| folderButton.setText(IDEWorkbenchMessages.getString("PathVariableDialog.folder")); //$NON-NLS-1$ |
| if ((variableType & IResource.FOLDER) == 0) |
| folderButton.setEnabled(false); |
| |
| data = setButtonFormLayoutData(folderButton); |
| data.top = new FormAttachment(variableValueLabel, convertVerticalDLUsToPixels(10)); |
| data.left = new FormAttachment(variableValueField, convertHorizontalDLUsToPixels(10)); |
| data.right = new FormAttachment(100, -5); |
| folderButton.setLayoutData(data); |
| folderButton.setFont(font); |
| |
| folderButton.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| selectFolder(); |
| } |
| }); |
| } |
| |
| /** |
| * Sets the <code>FormData</code> on the specified button to be one that is |
| * spaced for the current dialog page units. The method |
| * <code>initializeDialogUnits</code> must be called once before calling this |
| * method for the first time. |
| * |
| * @param button the button to set the <code>FormData</code> |
| * @return the <code>FormData</code> set on the specified button |
| */ |
| private FormData setButtonFormLayoutData(Button button) { |
| FormData data = new FormData(); |
| data.height = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT); |
| int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); |
| data.width = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); |
| button.setLayoutData(data); |
| return data; |
| } |
| |
| /** |
| * Fires validations (variable name first) and updates enabled state for the |
| * "Ok" button accordingly. |
| */ |
| private void variableNameModified() { |
| // updates and validates the variable name |
| variableName = variableNameField.getText().trim(); |
| validationStatus = IMessageProvider.NONE; |
| okButton.setEnabled(validateVariableName() && validateVariableValue()); |
| nameEntered = true; |
| } |
| /** |
| * Fires validations (variable value first) and updates enabled state for the |
| * "Ok" button accordingly. |
| */ |
| private void variableValueModified() { |
| // updates and validates the variable value |
| variableValue = variableValueField.getText().trim(); |
| validationStatus = IMessageProvider.NONE; |
| okButton.setEnabled(validateVariableValue() && validateVariableName()); |
| locationEntered = true; |
| } |
| |
| /** |
| * Opens a dialog where the user can select a folder path. |
| */ |
| private void selectFolder() { |
| DirectoryDialog dialog = new DirectoryDialog(getShell()); |
| dialog.setText(IDEWorkbenchMessages.getString("PathVariableDialog.selectFolderTitle")); //$NON-NLS-1$ |
| dialog.setMessage(IDEWorkbenchMessages.getString("PathVariableDialog.selectFolderMessage")); //$NON-NLS-1$ |
| dialog.setFilterPath(variableValue); |
| String res = dialog.open(); |
| if (res != null) { |
| variableValue = new Path(res).makeAbsolute().toOSString(); |
| variableValueField.setText(variableValue); |
| } |
| } |
| |
| /** |
| * Opens a dialog where the user can select a file path. |
| */ |
| private void selectFile() { |
| FileDialog dialog = new FileDialog(getShell()); |
| dialog.setText(IDEWorkbenchMessages.getString("PathVariableDialog.selectFileTitle")); //$NON-NLS-1$ |
| dialog.setFilterPath(variableValue); |
| String res = dialog.open(); |
| if (res != null) { |
| variableValue = new Path(res).makeAbsolute().toOSString(); |
| variableValueField.setText(variableValue); |
| } |
| } |
| |
| /** |
| * Adds buttons to this dialog's button bar. |
| * |
| * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar |
| */ |
| protected void createButtonsForButtonBar(Composite parent) { |
| okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); |
| okButton.setEnabled(type == EXISTING_VARIABLE); |
| |
| createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); |
| } |
| |
| /** |
| * Validates the current variable name, and updates this dialog's message. |
| * |
| * @return true if the name is valid, false otherwise |
| */ |
| private boolean validateVariableName() { |
| boolean allowFinish = false; |
| |
| // if the current validationStatus is ERROR, no additional validation applies |
| if (validationStatus == IMessageProvider.ERROR) |
| return false; |
| |
| // assumes everything will be ok |
| String message = standardMessage; |
| int newValidationStatus = IMessageProvider.NONE; |
| |
| if (variableName.length() == 0) { |
| // the variable name is empty |
| if (nameEntered) { |
| // a name was entered before and is now empty |
| newValidationStatus = IMessageProvider.ERROR; |
| message = IDEWorkbenchMessages.getString("PathVariableDialog.variableNameEmptyMessage"); //$NON-NLS-1$ |
| } |
| } else { |
| IStatus status = pathVariableManager.validateName(variableName); |
| if (!status.isOK()) { |
| // the variable name is not valid |
| newValidationStatus = IMessageProvider.ERROR; |
| message = status.getMessage(); |
| } else if (namesInUse.contains(variableName) && !variableName.equals(originalName)) { |
| // the variable name is already in use |
| message = IDEWorkbenchMessages.getString("PathVariableDialog.variableAlreadyExistsMessage"); //$NON-NLS-1$ |
| newValidationStatus = IMessageProvider.ERROR; |
| } else { |
| allowFinish = true; |
| } |
| } |
| |
| // overwrite the current validation status / message only if everything is ok (clearing them) |
| // or if we have a more serious problem than the current one |
| if (validationStatus == IMessageProvider.NONE || newValidationStatus == IMessageProvider.ERROR) { |
| validationStatus = newValidationStatus; |
| validationMessage = message; |
| } |
| // only set the message here if it is not going to be set in |
| // validateVariableValue to avoid flashing. |
| if (allowFinish == false) |
| setMessage(validationMessage, validationStatus); |
| return allowFinish; |
| } |
| |
| /** |
| * Validates the current variable value, and updates this dialog's message. |
| * |
| * @return true if the value is valid, false otherwise |
| */ |
| private boolean validateVariableValue() { |
| boolean allowFinish = false; |
| |
| // if the current validationStatus is ERROR, no additional validation applies |
| if (validationStatus == IMessageProvider.ERROR) |
| return false; |
| |
| // assumes everything will be ok |
| String message = standardMessage; |
| int newValidationStatus = IMessageProvider.NONE; |
| |
| if (variableValue.length() == 0) { |
| // the variable value is empty |
| if (locationEntered) { |
| // a location value was entered before and is now empty |
| newValidationStatus = IMessageProvider.ERROR; |
| message = IDEWorkbenchMessages.getString("PathVariableDialog.variableValueEmptyMessage"); //$NON-NLS-1$ |
| } |
| } else if (!Path.EMPTY.isValidPath(variableValue)) { |
| // the variable value is an invalid path |
| message = IDEWorkbenchMessages.getString("PathVariableDialog.variableValueInvalidMessage"); //$NON-NLS-1$ |
| newValidationStatus = IMessageProvider.ERROR; |
| } else if (!new Path(variableValue).isAbsolute()) { |
| // the variable value is a relative path |
| message = IDEWorkbenchMessages.getString("PathVariableDialog.pathIsRelativeMessage"); //$NON-NLS-1$ |
| newValidationStatus = IMessageProvider.ERROR; |
| } else if (!new File(variableValue).exists()) { |
| // the path does not exist (warning) |
| message = IDEWorkbenchMessages.getString("PathVariableDialog.pathDoesNotExistMessage"); //$NON-NLS-1$ |
| newValidationStatus = IMessageProvider.WARNING; |
| allowFinish = true; |
| } else { |
| allowFinish = true; |
| } |
| |
| // overwrite the current validation status / message only if everything is ok (clearing them) |
| // or if we have a more serious problem than the current one |
| if (validationStatus == IMessageProvider.NONE || newValidationStatus > validationStatus) { |
| validationStatus = newValidationStatus; |
| validationMessage = message; |
| } |
| setMessage(validationMessage, validationStatus); |
| return allowFinish; |
| } |
| |
| /** |
| * Returns the variable name. |
| * |
| * @return the variable name |
| */ |
| public String getVariableName() { |
| return variableName; |
| } |
| |
| /** |
| * Returns the variable value. |
| * |
| * @return the variable value |
| */ |
| public String getVariableValue() { |
| return variableValue; |
| } |
| |
| /** |
| * Sets the variable name. |
| * |
| * @param variableName the new variable name |
| */ |
| public void setVariableName(String variableName) { |
| this.variableName = variableName.trim(); |
| this.originalName = this.variableName; |
| } |
| |
| /** |
| * Sets the variable value. |
| * |
| * @param variableValue the new variable value |
| */ |
| public void setVariableValue(String variableValue) { |
| this.variableValue = variableValue; |
| } |
| |
| } |