1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

2005-03-06 Alain Magloire

Part of plan item 79518: for PathEntry variable manager.
	Not enable.
	* plugin.xml
	* src/org/eclipse/cdt/internal/ui/preferences/PathEntryVariableDialog.java
	* src/org/eclipse/cdt/internal/ui/preferences/PathEntryVariablePreferencePage.java
	* src/org/eclipse/cdt/internal/ui/preferences/PathEntryVariableGroup.java
	* src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties
This commit is contained in:
Alain Magloire 2005-03-07 04:29:20 +00:00
parent 7854896a04
commit 1ecfef7421
6 changed files with 1320 additions and 0 deletions

View file

@ -1,3 +1,12 @@
2005-03-06 Alain Magloire
Part of plan item 79518: for PathEntry variable manager.
Not enable.
* plugin.xml
* src/org/eclipse/cdt/internal/ui/preferences/PathEntryVariableDialog.java
* src/org/eclipse/cdt/internal/ui/preferences/PathEntryVariablePreferencePage.java
* src/org/eclipse/cdt/internal/ui/preferences/PathEntryVariableGroup.java
* src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties
2005-03-02 Alain Magloire 2005-03-02 Alain Magloire
Fix for PR 87027: Thanks to Jonathan Emmett, for noticing. Fix for PR 87027: Thanks to Jonathan Emmett, for noticing.
* src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java * src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java

View file

@ -626,6 +626,12 @@
class="org.eclipse.cdt.internal.ui.preferences.AppearancePreferencePage" class="org.eclipse.cdt.internal.ui.preferences.AppearancePreferencePage"
id="org.eclipse.cdt.ui.preferences.AppearancePreferencePage"> id="org.eclipse.cdt.ui.preferences.AppearancePreferencePage">
</page> </page>
<!--page
name="PathEntry Variable"
category="org.eclipse.cdt.ui.preferences.CPluginPreferencePage"
class="org.eclipse.cdt.internal.ui.preferences.PathEntryVariablePreferencePage"
id="org.eclipse.cdt.ui.preferences.PathEntryVariablePreferencePage">
</page-->
<!--page <!--page
name="%WorkInProgress.name" name="%WorkInProgress.name"
category="org.eclipse.cdt.ui.preferences.CPluginPreferencePage" category="org.eclipse.cdt.ui.preferences.CPluginPreferencePage"

View file

@ -0,0 +1,587 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems 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
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.io.File;
import java.util.Set;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class PathEntryVariableDialog 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 boolean newVariable;
/**
* 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 pathEntryVariableManager a reference to the path variable manager
* @param namesInUse a set of variable names currently in use
*/
public PathEntryVariableDialog(Shell parentShell, int type, int variableType, Set namesInUse) {
super(parentShell);
this.type = type;
this.newVariable = type == NEW_VARIABLE;
this.variableName = ""; //$NON-NLS-1$
this.variableValue = ""; //$NON-NLS-1$
this.variableType = variableType;
this.namesInUse = namesInUse;
if (newVariable)
this.standardMessage = PreferencesMessages
.getString("PathVariableDialog.message.newVariable"); //$NON-NLS-1$
else
this.standardMessage = PreferencesMessages
.getString("PathVariableDialog.message.existingVariable"); //$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);
if (newVariable)
shell.setText(PreferencesMessages
.getString("PathVariableDialog.shellTitle.newVariable")); //$NON-NLS-1$
else
shell
.setText(PreferencesMessages
.getString("PathVariableDialog.shellTitle.existingVariable")); //$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());
if (newVariable)
setTitle(PreferencesMessages
.getString("PathVariableDialog.dialogTitle.newVariable")); //$NON-NLS-1$
else
setTitle(PreferencesMessages
.getString("PathVariableDialog.dialogTitle.existingVariable")); //$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 = PreferencesMessages
.getString("PathVariableDialog.variableName"); //$NON-NLS-1$
String valueLabelText = PreferencesMessages
.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(PreferencesMessages
.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(PreferencesMessages
.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();
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.
*/
protected 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.
*/
protected 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.
*/
protected void selectFolder() {
DirectoryDialog dialog = new DirectoryDialog(getShell());
dialog.setText(PreferencesMessages
.getString("PathVariableDialog.selectFolderTitle")); //$NON-NLS-1$
dialog.setMessage(PreferencesMessages
.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.
*/
protected void selectFile() {
FileDialog dialog = new FileDialog(getShell());
dialog.setText(PreferencesMessages
.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 = PreferencesMessages
.getString("PathVariableDialog.variableNameEmptyMessage"); //$NON-NLS-1$
}
} else {
if (namesInUse.contains(variableName)
&& !variableName.equals(originalName)) {
// the variable name is already in use
message = PreferencesMessages
.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 = PreferencesMessages
.getString("PathVariableDialog.variableValueEmptyMessage"); //$NON-NLS-1$
}
} else if (!Path.EMPTY.isValidPath(variableValue)) {
// the variable value is an invalid path
message = PreferencesMessages
.getString("PathVariableDialog.variableValueInvalidMessage"); //$NON-NLS-1$
newValidationStatus = IMessageProvider.ERROR;
} else if (!new Path(variableValue).isAbsolute()) {
// the variable value is a relative path
message = PreferencesMessages
.getString("PathVariableDialog.pathIsRelativeMessage"); //$NON-NLS-1$
newValidationStatus = IMessageProvider.ERROR;
} else if (!new File(variableValue).exists()) {
// the path does not exist (warning)
message = PreferencesMessages
.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;
}
}

View file

@ -0,0 +1,126 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* IBM Corporation - initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
public class PathEntryVariablePreferencePage extends PreferencePage
implements IWorkbenchPreferencePage {
private Label topLabel;
private PathEntryVariablesGroup pathEntryVariablesGroup;
/**
* Constructs a preference page of path variables.
* Omits "Restore Defaults"/"Apply Changes" buttons.
*/
public PathEntryVariablePreferencePage() {
pathEntryVariablesGroup = new PathEntryVariablesGroup(true, IResource.FILE | IResource.FOLDER);
this.noDefaultAndApplyButton();
}
/**
* Resets this page's internal state and creates its UI contents.
*
* @see PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(Composite parent) {
Font font = parent.getFont();
// PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
// ICHelpContextIds.LINKED_RESOURCE_PREFERENCE_PAGE);
// define container & its gridding
Composite pageComponent = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
pageComponent.setLayout(layout);
GridData data = new GridData();
data.verticalAlignment = GridData.FILL;
data.horizontalAlignment = GridData.FILL;
pageComponent.setLayoutData(data);
pageComponent.setFont(font);
topLabel = new Label(pageComponent, SWT.NONE);
topLabel.setText(PreferencesMessages
.getString("LinkedResourcesPreference.explanation")); //$NON-NLS-1$
data = new GridData();
data.verticalAlignment = GridData.FILL;
data.horizontalAlignment = GridData.FILL;
topLabel.setLayoutData(data);
topLabel.setFont(font);
pathEntryVariablesGroup.createContents(pageComponent);
return pageComponent;
}
/**
* Creates a tab of one horizontal spans.
*
* @param parent the parent in which the tab should be created
*/
protected static void createSpace(Composite parent) {
Label vfiller = new Label(parent, SWT.LEFT);
GridData gridData = new GridData();
gridData = new GridData();
gridData.horizontalAlignment = GridData.BEGINNING;
gridData.grabExcessHorizontalSpace = false;
gridData.verticalAlignment = GridData.CENTER;
gridData.grabExcessVerticalSpace = false;
vfiller.setLayoutData(gridData);
}
/**
* Disposes the path variables group.
* @see org.eclipse.jface.dialogs.IDialogPage#dispose()
*/
public void dispose() {
pathEntryVariablesGroup.dispose();
super.dispose();
}
/**
* Empty implementation. This page does not use the workbench.
*
* @see IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
*/
public void init(IWorkbench workbench) {
}
/**
* Commits the temporary state to the path variable manager in response to user
* confirmation.
*
* @see PreferencePage#performOk()
* @see PathVariablesGroup#performOk()
*/
public boolean performOk() {
return pathEntryVariablesGroup.performOk();
}
}

View file

@ -0,0 +1,562 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* IBM Corporation - initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.io.File;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.resources.IPathEntryVariableManager;
import org.eclipse.cdt.internal.ui.CPluginImages;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
public class PathEntryVariablesGroup {
/**
* Simple data structure that holds a path variable name/value pair.
*/
public static class PathEntryVariableElement {
public String name;
public String value;
}
// sizing constants
private static final int SIZING_SELECTION_PANE_WIDTH = 400;
// parent shell
private Shell shell;
private Label variableLabel;
private Table variableTable;
private Button addButton;
private Button editButton;
private Button removeButton;
// used to compute layout sizes
private FontMetrics fontMetrics;
// create a multi select table
private boolean multiSelect;
// IResource.FILE and/or IResource.FOLDER
private int variableType;
// External listener called when the table selection changes
protected Listener selectionListener;
// temporary collection for keeping currently defined variables
private SortedMap tempPathVariables;
// set of removed variables' names
private Set removedVariableNames;
// reference to the workspace's path variable manager
private IPathEntryVariableManager pathEntryVariableManager;
// file image
private final Image FILE_IMG = PlatformUI.getWorkbench().getSharedImages()
.getImage(ISharedImages.IMG_OBJ_FILE);
// folder image
private final Image FOLDER_IMG = PlatformUI.getWorkbench()
.getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
// unknown (non-existent) image. created locally, dispose locally
private Image imageUnkown;
/**
* Creates a new PathVariablesGroup.
*
* @param multiSelect create a multi select tree
* @param variableType the type of variables that are displayed in
* the widget group. <code>IResource.FILE</code> and/or <code>IResource.FOLDER</code>
* logically ORed together.
*/
public PathEntryVariablesGroup(boolean multiSelect, int variableType) {
this.multiSelect = multiSelect;
this.variableType = variableType;
pathEntryVariableManager = CCorePlugin.getDefault().getPathEntryVariableManager();
removedVariableNames = new HashSet();
tempPathVariables = new TreeMap();
// initialize internal model
initTemporaryState();
}
/**
* Creates a new PathVariablesGroup.
*
* @param multiSelect create a multi select tree
* @param variableType the type of variables that are displayed in
* the widget group. <code>IResource.FILE</code> and/or <code>IResource.FOLDER</code>
* logically ORed together.
* @param selectionListener listener notified when the selection changes
* in the variables list.
*/
public PathEntryVariablesGroup(boolean multiSelect, int variableType,
Listener selectionListener) {
this(multiSelect, variableType);
this.selectionListener = selectionListener;
}
/**
* Opens a dialog for creating a new variable.
*/
protected void addNewVariable() {
// constructs a dialog for editing the new variable's current name and value
PathEntryVariableDialog dialog = new PathEntryVariableDialog(shell,
PathEntryVariableDialog.NEW_VARIABLE, variableType, tempPathVariables.keySet());
// opens the dialog - just returns if the user cancels it
if (dialog.open() == Window.CANCEL)
return;
// otherwise, adds the new variable (or updates an existing one) in the
// temporary collection of currently defined variables
String newVariableName = dialog.getVariableName();
String newVariableValue = dialog.getVariableValue();
tempPathVariables.put(newVariableName, newVariableValue);
// the UI must be updated
updateWidgetState(newVariableName);
}
/**
* Creates the widget group.
* Callers must call <code>dispose</code> when the group is no
* longer needed.
*
* @param parent the widget parent
* @return container of the widgets
*/
public Control createContents(Composite parent) {
Font font = parent.getFont();
if (imageUnkown == null) {
ImageDescriptor descriptor = CPluginImages.DESC_OVR_WARNING;
imageUnkown = descriptor.createImage();
}
initializeDialogUnits(parent);
shell = parent.getShell();
// define container & its layout
Composite pageComponent = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
pageComponent.setLayout(layout);
GridData data = new GridData(GridData.FILL_BOTH);
data.widthHint = SIZING_SELECTION_PANE_WIDTH;
pageComponent.setLayoutData(data);
pageComponent.setFont(font);
// layout the table & its buttons
variableLabel = new Label(pageComponent, SWT.LEFT);
variableLabel.setText(PreferencesMessages
.getString("PathVariablesBlock.variablesLabel")); //$NON-NLS-1$
data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.horizontalSpan = 2;
variableLabel.setLayoutData(data);
variableLabel.setFont(font);
int tableStyle = SWT.BORDER | SWT.FULL_SELECTION;
if (multiSelect) {
tableStyle |= SWT.MULTI;
}
variableTable = new Table(pageComponent, tableStyle);
variableTable.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
updateEnabledState();
if (selectionListener != null)
selectionListener.handleEvent(new Event());
}
});
data = new GridData(GridData.FILL_BOTH);
data.heightHint = variableTable.getItemHeight() * 7;
variableTable.setLayoutData(data);
variableTable.setFont(font);
createButtonGroup(pageComponent);
// populate table with current internal state and set buttons' initial state
updateWidgetState(null);
return pageComponent;
}
/**
* Disposes the group's resources.
*/
public void dispose() {
if (imageUnkown != null) {
imageUnkown.dispose();
imageUnkown = null;
}
}
/**
* Opens a dialog for editing an existing variable.
*
* @see PathVariableDialog
*/
protected void editSelectedVariable() {
// retrieves the name and value for the currently selected variable
TableItem item = variableTable.getItem(variableTable
.getSelectionIndex());
String variableName = (String) item.getData();
String variableValue = (String) tempPathVariables.get(variableName);
// constructs a dialog for editing the variable's current name and value
PathEntryVariableDialog dialog = new PathEntryVariableDialog(shell,
PathEntryVariableDialog.EXISTING_VARIABLE, variableType, tempPathVariables.keySet());
dialog.setVariableName(variableName);
dialog.setVariableValue(variableValue);
// opens the dialog - just returns if the user cancels it
if (dialog.open() == Window.CANCEL)
return;
// the name can be changed, so we remove the current variable definition...
removedVariableNames.add(variableName);
tempPathVariables.remove(variableName);
String newVariableName = dialog.getVariableName();
String newVariableValue = dialog.getVariableValue();
// and add it again (maybe with a different name)
tempPathVariables.put(newVariableName, newVariableValue);
// now we must refresh the UI state
updateWidgetState(newVariableName);
}
/**
* Returns the enabled state of the group's widgets.
* Returns <code>true</code> if called prior to calling
* <code>createContents</code>.
*
* @return boolean the enabled state of the group's widgets.
* <code>true</code> if called prior to calling <code>createContents</code>.
*/
public boolean getEnabled() {
if (variableTable != null && !variableTable.isDisposed()) {
return variableTable.getEnabled();
}
return true;
}
/**
* Returns the selected variables.
*
* @return the selected variables. Returns an empty array if
* the widget group has not been created yet by calling
* <code>createContents</code>
*/
public PathEntryVariableElement[] getSelection() {
if (variableTable == null) {
return new PathEntryVariableElement[0];
}
TableItem[] items = variableTable.getSelection();
PathEntryVariableElement[] selection = new PathEntryVariableElement[items.length];
for (int i = 0; i < items.length; i++) {
String name = (String) items[i].getData();
selection[i] = new PathEntryVariableElement();
selection[i].name = name;
selection[i].value = (String)tempPathVariables.get(name);
}
return selection;
}
/**
* Creates the add/edit/remove buttons
*
* @param parent the widget parent
*/
private void createButtonGroup(Composite parent) {
Font font = parent.getFont();
Composite groupComponent = new Composite(parent, SWT.NULL);
GridLayout groupLayout = new GridLayout();
groupLayout.marginWidth = 0;
groupLayout.marginHeight = 0;
groupComponent.setLayout(groupLayout);
GridData data = new GridData();
data.verticalAlignment = GridData.FILL;
data.horizontalAlignment = GridData.FILL;
groupComponent.setLayoutData(data);
groupComponent.setFont(font);
addButton = new Button(groupComponent, SWT.PUSH);
addButton.setText(PreferencesMessages
.getString("PathVariablesBlock.addVariableButton")); //$NON-NLS-1$
addButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
addNewVariable();
}
});
addButton.setFont(font);
setButtonLayoutData(addButton);
editButton = new Button(groupComponent, SWT.PUSH);
editButton.setText(PreferencesMessages
.getString("PathVariablesBlock.editVariableButton")); //$NON-NLS-1$
editButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
editSelectedVariable();
}
});
editButton.setFont(font);
setButtonLayoutData(editButton);
removeButton = new Button(groupComponent, SWT.PUSH);
removeButton.setText(PreferencesMessages
.getString("PathVariablesBlock.removeVariableButton")); //$NON-NLS-1$
removeButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
removeSelectedVariables();
}
});
removeButton.setFont(font);
setButtonLayoutData(removeButton);
}
/**
* Initializes the computation of horizontal and vertical dialog units
* based on the size of current font.
* <p>
* This method must be called before <code>setButtonLayoutData</code>
* is called.
* </p>
*
* @param control a control from which to obtain the current font
*/
protected void initializeDialogUnits(Control control) {
// Compute and store a font metric
GC gc = new GC(control);
gc.setFont(control.getFont());
fontMetrics = gc.getFontMetrics();
gc.dispose();
}
/**
* (Re-)Initialize collections used to mantain temporary variable state.
*/
private void initTemporaryState() {
String[] varNames = pathEntryVariableManager.getVariableNames();
tempPathVariables.clear();
for (int i = 0; i < varNames.length; i++) {
String value = pathEntryVariableManager.getValue(varNames[i]);
// the value may not exist any more
if (value != null) {
boolean isFile = new File(value).isFile();
if ((isFile && (variableType & IResource.FILE) != 0)
|| (isFile == false && (variableType & IResource.FOLDER) != 0)) {
tempPathVariables.put(varNames[i], value);
}
}
}
removedVariableNames.clear();
}
/**
* Updates button enabled state, depending on the number of currently selected
* variables in the table.
*/
protected void updateEnabledState() {
int itemsSelectedCount = variableTable.getSelectionCount();
editButton.setEnabled(itemsSelectedCount == 1);
removeButton.setEnabled(itemsSelectedCount > 0);
}
/**
* Rebuilds table widget state with the current list of variables (reflecting
* any changes, additions and removals), and selects the item corresponding to
* the given variable name. If the variable name is <code>null</code>, the
* first item (if any) will be selected.
*
* @param selectedVarName the name for the variable to be selected (may be
* <code>null</code>)
* @see IPathVariableManager#getPathVariableNames()
* @see IPathVariableManager#getValue(String)
*/
private void updateVariableTable(String selectedVarName) {
variableTable.removeAll();
int selectedVarIndex = 0;
for (Iterator varNames = tempPathVariables.keySet().iterator(); varNames
.hasNext();) {
TableItem item = new TableItem(variableTable, SWT.NONE);
String varName = (String) varNames.next();
String value = (String) tempPathVariables.get(varName);
File file = new File(value);
item.setText(varName + " - " + value); //$NON-NLS-1$
// the corresponding variable name is stored in each table widget item
item.setData(varName);
item.setImage(file.exists() ? (file.isFile() ? FILE_IMG
: FOLDER_IMG) : imageUnkown);
if (varName.equals(selectedVarName))
selectedVarIndex = variableTable.getItemCount() - 1;
}
if (variableTable.getItemCount() > selectedVarIndex) {
variableTable.setSelection(selectedVarIndex);
if (selectionListener != null)
selectionListener.handleEvent(new Event());
} else if (variableTable.getItemCount() == 0
&& selectionListener != null)
selectionListener.handleEvent(new Event());
}
/**
* Commits the temporary state to the path variable manager in response to user
* confirmation.
*
* @see IPathVariableManager#setValue(String, IPath)
*/
public boolean performOk() {
try {
// first process removed variables
for (Iterator removed = removedVariableNames.iterator(); removed
.hasNext();) {
String removedVariableName = (String) removed.next();
// only removes variables that have not been added again
if (!tempPathVariables.containsKey(removedVariableName))
pathEntryVariableManager.setValue(removedVariableName, null);
}
// then process the current collection of variables, adding/updating them
for (Iterator current = tempPathVariables.entrySet().iterator(); current
.hasNext();) {
Map.Entry entry = (Map.Entry) current.next();
String variableName = (String) entry.getKey();
String variableValue = (String) entry.getValue();
pathEntryVariableManager.setValue(variableName, variableValue);
}
// re-initialize temporary state
initTemporaryState();
// performOk accepted
return true;
} catch (CoreException ce) {
ErrorDialog.openError(shell, null, null, ce.getStatus());
}
return false;
}
/**
* Removes the currently selected variables.
*/
protected void removeSelectedVariables() {
// remove each selected element
int[] selectedIndices = variableTable.getSelectionIndices();
for (int i = 0; i < selectedIndices.length; i++) {
TableItem selectedItem = variableTable.getItem(selectedIndices[i]);
String varName = (String) selectedItem.getData();
removedVariableNames.add(varName);
tempPathVariables.remove(varName);
}
updateWidgetState(null);
}
/**
* Sets the <code>GridData</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>GridData</code>
* @return the <code>GridData</code> set on the specified button
*/
private GridData setButtonLayoutData(Button button) {
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics,
IDialogConstants.BUTTON_WIDTH);
data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT,
SWT.DEFAULT, true).x);
button.setLayoutData(data);
return data;
}
/**
* Sets the enabled state of the group's widgets.
* Does nothing if called prior to calling <code>createContents</code>.
*
* @param enabled the new enabled state of the group's widgets
*/
public void setEnabled(boolean enabled) {
if (variableTable != null && !variableTable.isDisposed()) {
variableLabel.setEnabled(enabled);
variableTable.setEnabled(enabled);
addButton.setEnabled(enabled);
if (enabled)
updateEnabledState();
else {
editButton.setEnabled(enabled);
removeButton.setEnabled(enabled);
}
}
}
/**
* Updates the widget's current state: refreshes the table with the current
* defined variables, selects the item corresponding to the given variable
* (selects the first item if <code>null</code> is provided) and updates
* the enabled state for the Add/Remove/Edit buttons.
*
* @param selectedVarName the name of the variable to be selected (may be null)
*/
private void updateWidgetState(String selectedVarName) {
updateVariableTable(selectedVarName);
updateEnabledState();
}
}

View file

@ -210,3 +210,33 @@ FoldingConfigurationBlock.error.not_exist= The selected folding provider does no
#Code Formatting #Code Formatting
CodeFormatterPreferencePage.title=Code Formatter CodeFormatterPreferencePage.title=Code Formatter
CodeFormatterPreferencePage.description=Code Formatter CodeFormatterPreferencePage.description=Code Formatter
# --- Linked Resources ---
LinkedResourcesPreference.explanation = Path variables specify locations in the file system. The locations of linked resources\nmay be specified relative to these path variables.
LinkedResourcesPreference.enableLinkedResources = &Enable linked resources
LinkedResourcesPreference.linkedResourcesWarningTitle = Enabled Linked Resources
LinkedResourcesPreference.linkedResourcesWarningMessage = You have enabled a feature which may give rise to incompatibilities if projects are shared by users of different versions of the workbench. Please consult the documentation for further details.
# The following six keys are marked as unused by the NLS search, but they are indirectly used
# and should be removed.
PathVariableDialog.shellTitle.newVariable = New Variable
PathVariableDialog.shellTitle.existingVariable = Edit Variable
PathVariableDialog.dialogTitle.newVariable = Define a New Path Variable
PathVariableDialog.dialogTitle.existingVariable = Edit an Existing Path Variable
PathVariableDialog.message.newVariable = Enter a new variable name and its associated location.
PathVariableDialog.message.existingVariable = Edit variable's name and path value.
PathVariableDialog.variableName = &Name:
PathVariableDialog.variableValue = &Location:
PathVariableDialog.variableNameEmptyMessage = You must provide a variable name.
PathVariableDialog.variableValueEmptyMessage = You must provide a file or folder path as variable value.
PathVariableDialog.variableValueInvalidMessage = The provided value is not a valid path.
PathVariableDialog.file = &File...
PathVariableDialog.folder = F&older...
PathVariableDialog.selectFileTitle = File selection
PathVariableDialog.selectFolderTitle = Folder selection
PathVariableDialog.selectFolderMessage = Specify the folder to be represented by the variable.
PathVariableDialog.variableAlreadyExistsMessage = This variable name is already in use.
PathVariableDialog.pathIsRelativeMessage = Path must be absolute.
PathVariableDialog.pathDoesNotExistMessage = Path does not exist.