From 733f00d3a88f53c26e02e31f453299c15e14c271 Mon Sep 17 00:00:00 2001 From: Oleg Krasilnikov Date: Tue, 3 Apr 2007 13:33:08 +0000 Subject: [PATCH] New Project Location area: full rework. --- .../META-INF/MANIFEST.MF | 3 +- .../ui/properties/messages.properties | 14 + .../ui/wizards/CMainWizardPage.java | 35 +- .../ui/wizards/ProjectContentsArea.java | 364 ++++++++++++++++++ 4 files changed, 391 insertions(+), 25 deletions(-) create mode 100644 build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/ProjectContentsArea.java diff --git a/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF index cc8b235bd5b..85f13cf3359 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF @@ -19,5 +19,6 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)", org.eclipse.ui.navigator;bundle-version="[3.2.0,4.0.0)";resolution:=optional, org.eclipse.cdt.make.core, - org.eclipse.cdt.make.ui + org.eclipse.cdt.make.ui, + org.eclipse.core.filesystem Eclipse-LazyStart: true diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/messages.properties b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/messages.properties index e56d9338a9d..caf2456e0e8 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/messages.properties +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/messages.properties @@ -90,12 +90,15 @@ CConfigWizardPage.12=Use "Advanced settings" button to edit project's properties CConfigWizardPage.13=Advanced settings... CMainWizardPage.0=Project types: CMainWizardPage.1=Show project types and toolchains only if they are supported on the platform +CMainWizardPage.10=A project with that name already exists in the workspace. CMainWizardPage.2=Edit properties after project creation CMainWizardPage.3=No project types available. Project cannot be created CMainWizardPage.4=At least one toolchain should be selected \! CMainWizardPage.5=Cannot create ICProjectTypeHandler : CMainWizardPage.6=File with specified name already exists \! CMainWizardPage.7=Directory with specified name already exists \! +CMainWizardPage.8=Project name: +CMainWizardPage.9=Project name is empty WizardNewProjectCreationPage_nameLabel= WizardNewProjectCreationPage_projectNameEmpty= WizardNewProjectCreationPage_projectExistsMessage= @@ -114,3 +117,14 @@ NewModelProjectWizard.3=Create C++ project of selected type NewModelProjectWizard.4=C project NewModelProjectWizard.5=Create C project of selected type StdBuildWizard.0=Makefile project +ProjectContentsArea.0=Browse... +ProjectContentsArea.1=Use default location +ProjectContentsArea.2=Location: +ProjectContentsArea.3=Choose file system: +ProjectContentsArea.3=Invalid location path +ProjectContentsArea.4=Project contents directory must be specified +ProjectContentsArea.5=Select directory: +ProjectContentsArea.6=Project path should be absolute +ProjectContentsArea.7=Project path is not valid +ProjectContentsArea.8=Cannot create given path +ProjectContentsArea.9=File with given name already exists diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/CMainWizardPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/CMainWizardPage.java index 5784c8e43a7..05053ff4f21 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/CMainWizardPage.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/CMainWizardPage.java @@ -16,6 +16,7 @@ import java.util.TreeSet; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.ui.properties.Messages; import org.eclipse.cdt.managedbuilder.ui.properties.PageLayout; +import org.eclipse.cdt.managedbuilder.ui.wizards.ProjectContentsArea.IErrorMessageReporter; import org.eclipse.cdt.ui.newui.CDTPrefUtil; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -45,11 +46,6 @@ import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; -import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; -import org.eclipse.ui.internal.ide.IIDEHelpContextIds; -import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea; -import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMessageReporter; public class CMainWizardPage extends WizardPage implements IToolChainListListener { @@ -58,7 +54,7 @@ import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMes public static final String CLASS_NAME = "class"; //$NON-NLS-1$ public static final String PAGE_ID = "org.eclipse.cdt.managedbuilder.ui.wizard.NewModelProjectWizardPage"; //$NON-NLS-1$ - + private static final String HELP_CTX = "org.eclipse.ui.ide.new_project_wizard_page_context"; //$NON-NLS-1$ // initial value stores private String initialProjectFieldValue; @@ -79,7 +75,7 @@ import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMes } }; - private ProjectContentsLocationArea locationArea; + private ProjectContentsArea locationArea; // constants private static final int SIZING_TEXT_FIELD_WIDTH = 250; @@ -103,15 +99,13 @@ import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMes composite.setFont(parent.getFont()); initializeDialogUnits(parent); - - PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, - IIDEHelpContextIds.NEW_PROJECT_WIZARD_PAGE); + PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, HELP_CTX); composite.setLayout(new GridLayout()); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); createProjectNameGroup(composite); - locationArea = new ProjectContentsLocationArea(getErrorReporter(), composite); + locationArea = new ProjectContentsArea(getErrorReporter(), composite); if(initialProjectFieldValue != null) { locationArea.updateProjectName(initialProjectFieldValue); } @@ -180,25 +174,18 @@ import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMes */ private IErrorMessageReporter getErrorReporter() { return new IErrorMessageReporter(){ - /* (non-Javadoc) - * @see org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMessageReporter#reportError(java.lang.String) - */ public void reportError(String errorMessage) { setErrorMessage(errorMessage); boolean valid = errorMessage == null; - if(valid) { - valid = validatePage(); - } - + if(valid) valid = validatePage(); setPageComplete(valid); } }; } - + public IWizardPage getNextPage() { if (h_selected == null || h_selected.isDummy()) // cannot continue return null; -// MBSCustomPageManager.setPageHideStatus(next.pageID, false); return next; } /** @@ -216,7 +203,7 @@ import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMes // new project label Label projectLabel = new Label(projectGroup, SWT.NONE); - projectLabel.setText(IDEWorkbenchMessages.WizardNewProjectCreationPage_nameLabel); + projectLabel.setText(Messages.getString("CMainWizardPage.8")); //$NON-NLS-1$ projectLabel.setFont(parent.getFont()); // new project name entry field @@ -323,12 +310,12 @@ import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMes * false if at least one is invalid */ protected boolean validatePage() { - IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); setMessage(null); String projectFieldContents = getProjectNameFieldValue(); if (projectFieldContents.length() == 0) { - setErrorMessage(IDEWorkbenchMessages.WizardNewProjectCreationPage_projectNameEmpty); + setErrorMessage(Messages.getString("CMainWizardPage.9")); //$NON-NLS-1$ return false; } @@ -349,7 +336,7 @@ import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMes bad = false; } if (bad) { - setErrorMessage(IDEWorkbenchMessages.WizardNewProjectCreationPage_projectExistsMessage); + setErrorMessage(Messages.getString("CMainWizardPage.10")); //$NON-NLS-1$ return false; } } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/ProjectContentsArea.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/ProjectContentsArea.java new file mode 100644 index 00000000000..570c61571d0 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/ProjectContentsArea.java @@ -0,0 +1,364 @@ +/******************************************************************************* + * Copyright (c) 2005, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Intel corporation - cloned to CDT UI, to avoid discouraged access + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.ui.wizards; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.cdt.managedbuilder.ui.properties.Messages; +import org.eclipse.cdt.ui.newui.AbstractPage; +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.util.TextProcessor; +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.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.DirectoryDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +/** + * + */ +public class ProjectContentsArea { + private static final String ERROR_INVALID_PATH = Messages.getString("ProjectContentsArea.3"); //$NON-NLS-1$ + private static final String ERROR_PATH_EMPTY = Messages.getString("ProjectContentsArea.4"); //$NON-NLS-1$ + private static final String ERROR_NOT_ABSOLUTE = Messages.getString("ProjectContentsArea.6"); //$NON-NLS-1$ + private static final String ERROR_NOT_VALID = Messages.getString("ProjectContentsArea.7"); //$NON-NLS-1$ + private static final String ERROR_CANNOT_CREATE = Messages.getString("ProjectContentsArea.8"); //$NON-NLS-1$ + private static final String ERROR_FILE_EXISTS = Messages.getString("ProjectContentsArea.9"); //$NON-NLS-1$ + + private static final String BROWSE_LABEL = Messages.getString("ProjectContentsArea.0"); //$NON-NLS-1$ + private static final int SIZING_TEXT_FIELD_WIDTH = 250; + private static final String FILE_SCHEME = "file"; //$NON-NLS-1$ + private Label locationLabel; + private Text locationPathField; + private Button browseButton; + private IErrorMessageReporter errorReporter; + private String projectName = AbstractPage.EMPTY_STR; + private String userPath = AbstractPage.EMPTY_STR; + private Button useDefaultsButton; + private IProject existingProject; + + /** + * Create a new instance of a ProjectContentsLocationArea. + * + * @param composite + */ + public ProjectContentsArea(IErrorMessageReporter er, Composite composite) { + errorReporter = er; + createContents(composite, true); + } + + /** + * Create the contents of the receiver. + * + * @param composite + * @param defaultEnabled + */ + private void createContents(Composite composite, boolean defaultEnabled) { + // project specification group + Composite projectGroup = new Composite(composite, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 4; + projectGroup.setLayout(layout); + projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + useDefaultsButton = new Button(projectGroup, SWT.CHECK | SWT.RIGHT); + useDefaultsButton.setText(Messages.getString("ProjectContentsArea.1")); //$NON-NLS-1$ + useDefaultsButton.setSelection(defaultEnabled); + GridData buttonData = new GridData(); + buttonData.horizontalSpan = 4; + useDefaultsButton.setLayoutData(buttonData); + + createUserEntryArea(projectGroup, defaultEnabled); + + useDefaultsButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + boolean useDefaults = useDefaultsButton.getSelection(); + + if (useDefaults) { + userPath = locationPathField.getText(); + locationPathField.setText(TextProcessor + .process(getDefaultPathDisplayString())); + } else { + locationPathField.setText(TextProcessor.process(userPath)); + } + setUserAreaEnabled(!useDefaults); + } + }); + setUserAreaEnabled(!defaultEnabled); + } + + /** + * Return whether or not we are currently showing the default location for + * the project. + * + * @return boolean + */ + public boolean isDefault() { + return useDefaultsButton.getSelection(); + } + + /** + * Create the area for user entry. + * + * @param composite + * @param defaultEnabled + */ + private void createUserEntryArea(Composite composite, boolean defaultEnabled) { + // location label + locationLabel = new Label(composite, SWT.NONE); + locationLabel.setText(Messages.getString("ProjectContentsArea.2")); //$NON-NLS-1$ + + // project location entry field + locationPathField = new Text(composite, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = SIZING_TEXT_FIELD_WIDTH; + data.horizontalSpan = 2; + locationPathField.setLayoutData(data); + + // browse button + browseButton = new Button(composite, SWT.PUSH); + browseButton.setText(BROWSE_LABEL); + browseButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + handleLocationBrowseButtonPressed(); + } + }); + + if (defaultEnabled) { + locationPathField.setText(TextProcessor + .process(getDefaultPathDisplayString())); + } else { + if (existingProject == null) { + locationPathField.setText(AbstractPage.EMPTY_STR); + } else { + locationPathField.setText(TextProcessor.process(existingProject + .getLocation().toString())); + } + } + + locationPathField.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + errorReporter.reportError(checkValidLocation()); + } + }); + } + + /** + * Return the path we are going to display. If it is a file URI then remove + * the file prefix. + * + * @return String + */ + private String getDefaultPathDisplayString() { + + URI defaultURI = null; + if (existingProject != null) { + defaultURI = existingProject.getLocationURI(); + } + + // Handle files specially. Assume a file if there is no project to query + if (defaultURI == null || defaultURI.getScheme().equals(FILE_SCHEME)) { + return Platform.getLocation().append(projectName).toString(); + } + return defaultURI.toString(); + + } + + /** + * Set the enablement state of the receiver. + * + * @param enabled + */ + private void setUserAreaEnabled(boolean enabled) { + locationLabel.setEnabled(enabled); + locationPathField.setEnabled(enabled); + browseButton.setEnabled(enabled); + } + + /** + * Return the browse button. Usually referenced in order to set the layout + * data for a dialog. + * + * @return Button + */ + public Button getBrowseButton() { + return browseButton; + } + + /** + * Open an appropriate directory browser + */ + private void handleLocationBrowseButtonPressed() { + + String selectedDirectory = null; + String dirName = getPathFromLocationField(); + + if (!dirName.equals(AbstractPage.EMPTY_STR)) { + File f = new Path(dirName).toFile(); + if (!f.exists()) dirName = AbstractPage.EMPTY_STR; + } + + DirectoryDialog dialog = new DirectoryDialog(locationPathField.getShell()); + dialog.setMessage(Messages.getString("ProjectContentsArea.5")); //$NON-NLS-1$ + dialog.setFilterPath(dirName); + selectedDirectory = dialog.open(); + + if (selectedDirectory != null) + updateLocationField(selectedDirectory); + } + + /** + * Update the location field based on the selected path. + * + * @param selectedPath + */ + private void updateLocationField(String selectedPath) { + locationPathField.setText(TextProcessor.process(selectedPath)); + } + + /** + * Return the path on the location field. + * + * @return String + */ + private String getPathFromLocationField() { + URI fieldURI; + try { + fieldURI = new URI(locationPathField.getText()); + } catch (URISyntaxException e) { + return locationPathField.getText(); + } + return fieldURI.getPath(); + } + + /** + * Check if the entry in the widget location is valid. If it is valid return + * null. Otherwise return a string that indicates the problem. + * + * @return String + */ + public String checkValidLocation() { + + if (isDefault()) return null; + + String locationFieldContents = locationPathField.getText(); + + if (locationFieldContents.length() == 0) + return ERROR_PATH_EMPTY; + + URI newPath = getProjectLocationURI(); + + if (newPath == null) + return ERROR_INVALID_PATH; + + if (!Path.EMPTY.isValidPath(locationFieldContents)) + return ERROR_NOT_VALID; + + Path p = new Path(locationFieldContents); + + if (!p.isAbsolute()) + return ERROR_NOT_ABSOLUTE; + + // try to create dummy file + File f = p.toFile(); + if (!f.exists()) { + boolean result = false; + try { + result = f.createNewFile(); + } catch (IOException e) {} + + if (result) + f.delete(); + else + return ERROR_CANNOT_CREATE; + } else { + if (f.isFile()) + return ERROR_FILE_EXISTS; + } + + //create a dummy project for the purpose of validation if necessary + IProject project = existingProject; + if (project == null) { + String name = new Path(locationFieldContents).lastSegment(); + if (name != null && Path.EMPTY.isValidSegment(name)) + project = ResourcesPlugin.getWorkspace().getRoot().getProject(name); + else + return ERROR_INVALID_PATH; + } + IStatus locationStatus = project.getWorkspace().validateProjectLocationURI(project, newPath); + + if (!locationStatus.isOK()) { + return locationStatus.getMessage(); + } + if (existingProject != null) { + URI projectPath = existingProject.getLocationURI(); + if (projectPath != null && URIUtil.equals(projectPath, newPath)) + return ERROR_INVALID_PATH; + } + + return null; + } + + /** + * Get the URI for the location field if possible. + * @return URI or null if it is not valid. + */ + public URI getProjectLocationURI() { + return URIUtil.toURI(locationPathField.getText()); + } + + /** + * Set the text to the default or clear it if not using the defaults. + * @param newName + * the name of the project to use. If null use the + * existing project name. + */ + public void updateProjectName(String newName) { + projectName = newName; + if (isDefault()) + locationPathField.setText(TextProcessor.process(getDefaultPathDisplayString())); + } + + /** + * Return the location for the project. If we are using defaults then return + * the workspace root so that core creates it with default values. + * + * @return String + */ + public String getProjectLocation() { + return isDefault() ? + Platform.getLocation().toString(): + locationPathField.getText(); + } + + /** + * IErrorMessageReporter is an interface for type that allow message + * reporting. Null means "clear error messages area". + */ + public interface IErrorMessageReporter { + public void reportError(String errorMessage); + } +}