001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Jakub Jurkiewicz <jakub.jurkiewicz@gmail.com> - Fix for Bug 174737
011: * [IDE] New Plug-in Project wizard status handling is inconsistent
012: *******************************************************************************/package org.eclipse.ui.dialogs;
013:
014: import java.net.URI;
015:
016: import org.eclipse.core.resources.IProject;
017: import org.eclipse.core.resources.IResource;
018: import org.eclipse.core.resources.IWorkspace;
019: import org.eclipse.core.resources.ResourcesPlugin;
020: import org.eclipse.core.runtime.IPath;
021: import org.eclipse.core.runtime.IStatus;
022: import org.eclipse.core.runtime.Path;
023: import org.eclipse.jface.viewers.IStructuredSelection;
024: import org.eclipse.jface.wizard.WizardPage;
025: import org.eclipse.swt.SWT;
026: import org.eclipse.swt.layout.GridData;
027: import org.eclipse.swt.layout.GridLayout;
028: import org.eclipse.swt.widgets.Composite;
029: import org.eclipse.swt.widgets.Event;
030: import org.eclipse.swt.widgets.Label;
031: import org.eclipse.swt.widgets.Listener;
032: import org.eclipse.swt.widgets.Text;
033: import org.eclipse.ui.IWorkingSet;
034: import org.eclipse.ui.PlatformUI;
035: import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
036: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
037: import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
038: import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea;
039: import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMessageReporter;
040:
041: /**
042: * Standard main page for a wizard that is creates a project resource.
043: * <p>
044: * This page may be used by clients as-is; it may be also be subclassed to suit.
045: * </p>
046: * <p>
047: * Example usage:
048: * <pre>
049: * mainPage = new WizardNewProjectCreationPage("basicNewProjectPage");
050: * mainPage.setTitle("Project");
051: * mainPage.setDescription("Create a new project resource.");
052: * </pre>
053: * </p>
054: */
055: public class WizardNewProjectCreationPage extends WizardPage {
056:
057: // initial value stores
058: private String initialProjectFieldValue;
059:
060: // widgets
061: Text projectNameField;
062:
063: private Listener nameModifyListener = new Listener() {
064: public void handleEvent(Event e) {
065: setLocationForSelection();
066: boolean valid = validatePage();
067: setPageComplete(valid);
068:
069: }
070: };
071:
072: private ProjectContentsLocationArea locationArea;
073:
074: private WorkingSetGroup workingSetGroup;
075:
076: // constants
077: private static final int SIZING_TEXT_FIELD_WIDTH = 250;
078:
079: /**
080: * Creates a new project creation wizard page.
081: *
082: * @param pageName the name of this page
083: */
084: public WizardNewProjectCreationPage(String pageName) {
085: super (pageName);
086: setPageComplete(false);
087: }
088:
089: /**
090: * Creates a new project creation wizard page.
091: *
092: * @param pageName
093: * @param selection
094: * @param workingSetTypes
095: *
096: * @deprecated default placement of the working set group has been removed.
097: * If you wish to use the working set block please call
098: * {@link #createWorkingSetGroup(Composite, IStructuredSelection, String[])}
099: * in your overriden {@link #createControl(Composite)}
100: * implementation. This method will be removed before 3.4 ships.
101: * @since 3.4
102: */
103: public WizardNewProjectCreationPage(String pageName,
104: IStructuredSelection selection, String[] workingSetTypes) {
105: this (pageName);
106: }
107:
108: /** (non-Javadoc)
109: * Method declared on IDialogPage.
110: */
111: public void createControl(Composite parent) {
112: Composite composite = new Composite(parent, SWT.NULL);
113: composite.setFont(parent.getFont());
114:
115: initializeDialogUnits(parent);
116:
117: PlatformUI.getWorkbench().getHelpSystem().setHelp(composite,
118: IIDEHelpContextIds.NEW_PROJECT_WIZARD_PAGE);
119:
120: composite.setLayout(new GridLayout());
121: composite.setLayoutData(new GridData(GridData.FILL_BOTH));
122:
123: createProjectNameGroup(composite);
124: locationArea = new ProjectContentsLocationArea(
125: getErrorReporter(), composite);
126: if (initialProjectFieldValue != null) {
127: locationArea.updateProjectName(initialProjectFieldValue);
128: }
129:
130: // Scale the button based on the rest of the dialog
131: setButtonLayoutData(locationArea.getBrowseButton());
132:
133: setPageComplete(validatePage());
134: // Show description on opening
135: setErrorMessage(null);
136: setMessage(null);
137: setControl(composite);
138: }
139:
140: /**
141: * Create a working set group for this page. This method can only be called
142: * once.
143: *
144: * @param composite
145: * the composite in which to create the group
146: * @param selection
147: * the current workbench selection
148: * @param supportedWorkingSetTypes
149: * an array of working set type IDs that will restrict what types
150: * of working sets can be chosen in this group
151: * @return the created group. If this method has been called previously the
152: * original group will be returned.
153: * @since 3.4
154: */
155: public WorkingSetGroup createWorkingSetGroup(Composite composite,
156: IStructuredSelection selection,
157: String[] supportedWorkingSetTypes) {
158: if (workingSetGroup != null)
159: return workingSetGroup;
160: workingSetGroup = new WorkingSetGroup(composite, selection,
161: supportedWorkingSetTypes);
162: return workingSetGroup;
163: }
164:
165: /**
166: * Get an error reporter for the receiver.
167: * @return IErrorMessageReporter
168: */
169: private IErrorMessageReporter getErrorReporter() {
170: return new IErrorMessageReporter() {
171: /* (non-Javadoc)
172: * @see org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMessageReporter#reportError(java.lang.String)
173: */
174: public void reportError(String errorMessage) {
175: setErrorMessage(errorMessage);
176: boolean valid = errorMessage == null;
177: if (valid) {
178: valid = validatePage();
179: }
180:
181: setPageComplete(valid);
182: }
183: };
184: }
185:
186: /**
187: * Creates the project name specification controls.
188: *
189: * @param parent the parent composite
190: */
191: private final void createProjectNameGroup(Composite parent) {
192: // project specification group
193: Composite projectGroup = new Composite(parent, SWT.NONE);
194: GridLayout layout = new GridLayout();
195: layout.numColumns = 2;
196: projectGroup.setLayout(layout);
197: projectGroup.setLayoutData(new GridData(
198: GridData.FILL_HORIZONTAL));
199:
200: // new project label
201: Label projectLabel = new Label(projectGroup, SWT.NONE);
202: projectLabel
203: .setText(IDEWorkbenchMessages.WizardNewProjectCreationPage_nameLabel);
204: projectLabel.setFont(parent.getFont());
205:
206: // new project name entry field
207: projectNameField = new Text(projectGroup, SWT.BORDER);
208: GridData data = new GridData(GridData.FILL_HORIZONTAL);
209: data.widthHint = SIZING_TEXT_FIELD_WIDTH;
210: projectNameField.setLayoutData(data);
211: projectNameField.setFont(parent.getFont());
212:
213: // Set the initial value first before listener
214: // to avoid handling an event during the creation.
215: if (initialProjectFieldValue != null) {
216: projectNameField.setText(initialProjectFieldValue);
217: }
218: projectNameField.addListener(SWT.Modify, nameModifyListener);
219: }
220:
221: /**
222: * Returns the current project location path as entered by
223: * the user, or its anticipated initial value.
224: * Note that if the default has been returned the path
225: * in a project description used to create a project
226: * should not be set.
227: *
228: * @return the project location path or its anticipated initial value.
229: */
230: public IPath getLocationPath() {
231: return new Path(locationArea.getProjectLocation());
232: }
233:
234: /**
235: /**
236: * Returns the current project location URI as entered by
237: * the user, or <code>null</code> if a valid project location
238: * has not been entered.
239: *
240: * @return the project location URI, or <code>null</code>
241: * @since 3.2
242: */
243: public URI getLocationURI() {
244: return locationArea.getProjectLocationURI();
245: }
246:
247: /**
248: * Creates a project resource handle for the current project name field
249: * value. The project handle is created relative to the workspace root.
250: * <p>
251: * This method does not create the project resource; this is the
252: * responsibility of <code>IProject::create</code> invoked by the new
253: * project resource wizard.
254: * </p>
255: *
256: * @return the new project resource handle
257: */
258: public IProject getProjectHandle() {
259: return ResourcesPlugin.getWorkspace().getRoot().getProject(
260: getProjectName());
261: }
262:
263: /**
264: * Returns the current project name as entered by the user, or its anticipated
265: * initial value.
266: *
267: * @return the project name, its anticipated initial value, or <code>null</code>
268: * if no project name is known
269: */
270: public String getProjectName() {
271: if (projectNameField == null) {
272: return initialProjectFieldValue;
273: }
274:
275: return getProjectNameFieldValue();
276: }
277:
278: /**
279: * Returns the value of the project name field
280: * with leading and trailing spaces removed.
281: *
282: * @return the project name in the field
283: */
284: private String getProjectNameFieldValue() {
285: if (projectNameField == null) {
286: return ""; //$NON-NLS-1$
287: }
288:
289: return projectNameField.getText().trim();
290: }
291:
292: /**
293: * Sets the initial project name that this page will use when
294: * created. The name is ignored if the createControl(Composite)
295: * method has already been called. Leading and trailing spaces
296: * in the name are ignored.
297: * Providing the name of an existing project will not necessarily
298: * cause the wizard to warn the user. Callers of this method
299: * should first check if the project name passed already exists
300: * in the workspace.
301: *
302: * @param name initial project name for this page
303: *
304: * @see IWorkspace#validateName(String, int)
305: *
306: */
307: public void setInitialProjectName(String name) {
308: if (name == null) {
309: initialProjectFieldValue = null;
310: } else {
311: initialProjectFieldValue = name.trim();
312: if (locationArea != null) {
313: locationArea.updateProjectName(name.trim());
314: }
315: }
316: }
317:
318: /**
319: * Set the location to the default location if we are set to useDefaults.
320: */
321: void setLocationForSelection() {
322: locationArea.updateProjectName(getProjectNameFieldValue());
323: }
324:
325: /**
326: * Returns whether this page's controls currently all contain valid
327: * values.
328: *
329: * @return <code>true</code> if all controls are valid, and
330: * <code>false</code> if at least one is invalid
331: */
332: protected boolean validatePage() {
333: IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
334:
335: String projectFieldContents = getProjectNameFieldValue();
336: if (projectFieldContents.equals("")) { //$NON-NLS-1$
337: setErrorMessage(null);
338: setMessage(IDEWorkbenchMessages.WizardNewProjectCreationPage_projectNameEmpty);
339: return false;
340: }
341:
342: IStatus nameStatus = workspace.validateName(
343: projectFieldContents, IResource.PROJECT);
344: if (!nameStatus.isOK()) {
345: setErrorMessage(nameStatus.getMessage());
346: return false;
347: }
348:
349: IProject handle = getProjectHandle();
350: if (handle.exists()) {
351: setErrorMessage(IDEWorkbenchMessages.WizardNewProjectCreationPage_projectExistsMessage);
352: return false;
353: }
354:
355: IProject project = ResourcesPlugin.getWorkspace().getRoot()
356: .getProject(getProjectNameFieldValue());
357: locationArea.setExistingProject(project);
358:
359: String validLocationMessage = locationArea.checkValidLocation();
360: if (validLocationMessage != null) { // there is no destination location given
361: setErrorMessage(validLocationMessage);
362: return false;
363: }
364:
365: setErrorMessage(null);
366: setMessage(null);
367: return true;
368: }
369:
370: /*
371: * see @DialogPage.setVisible(boolean)
372: */
373: public void setVisible(boolean visible) {
374: super .setVisible(visible);
375: if (visible) {
376: projectNameField.setFocus();
377: }
378: }
379:
380: /**
381: * Returns the useDefaults.
382: * @return boolean
383: */
384: public boolean useDefaults() {
385: return locationArea.isDefault();
386: }
387:
388: /**
389: * Return the selected working sets, if any. If this page is not configured
390: * to interact with working sets this will be an empty array.
391: *
392: * @return the selected working sets
393: * @since 3.4
394: */
395: public IWorkingSet[] getSelectedWorkingSets() {
396: return workingSetGroup == null ? new IWorkingSet[0]
397: : workingSetGroup.getSelectedWorkingSets();
398: }
399: }
|