/* * Copyright 2012 Google Inc. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.ui.internal.projects; import com.google.dart.tools.core.DartCore; import com.google.dart.tools.core.generator.AbstractSample; import com.google.dart.tools.core.generator.DartIdentifierUtil; import com.google.dart.tools.core.internal.util.StatusUtil; import com.google.dart.tools.ui.DartToolsPlugin; import com.google.dart.tools.ui.internal.util.DirectoryVerification; import com.google.dart.tools.ui.internal.util.GridDataFactory; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusAdapter; import org.eclipse.swt.events.FocusEvent; 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.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.util.ArrayList; import java.util.List; /** * New project creation page. */ public class NewApplicationCreationPage extends WizardPage { public static enum ProjectType { NONE, SERVER, WEB } static final String NEW_APPPLICATION_SETTINGS = "newApplicationWizard.settings"; //$NON-NLS-1$ static final String PARENT_DIR = "parentDir"; //$NON-NLS-1$ private Text projectNameField; private Text projectLocationField; private String defaultLocation; private TableViewer samplesViewer; /** * Creates a new project creation wizard page. */ public NewApplicationCreationPage() { super("newApplication"); //$NON-NLS-1$ setPageComplete(false); setTitle(ProjectMessages.OpenNewApplicationWizardAction_text); setDescription(ProjectMessages.OpenNewApplicationWizardAction_desc); setImageDescriptor(DartToolsPlugin.getImageDescriptor("icons/full/wizban/newprj_wiz.png")); //$NON-NLS-1$ defaultLocation = getParentDirectory(); } @Override public void createControl(Composite parent) { Composite container = new Composite(parent, SWT.NULL); setControl(container); GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1); container.setLayoutData(gridData); container.setLayout(new GridLayout(1, false)); Group nameGroup = new Group(container, SWT.NONE); nameGroup.setText("Name and location"); GridDataFactory.create(nameGroup).grabHorizontal().fill(); GridLayoutFactory.fillDefaults().numColumns(3).margins(8, 8).applyTo(nameGroup); Label nameLabel = new Label(nameGroup, SWT.NONE); nameLabel.setText(ProjectMessages.NewApplicationWizardPage_project_name_label); projectNameField = new Text(nameGroup, SWT.BORDER); projectNameField.setText(""); //$NON-NLS-1$ projectNameField.setToolTipText(ProjectMessages.NewApplicationWizardPage_project_name_tooltip); projectNameField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); projectNameField.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { projectNameField.selectAll(); } }); projectNameField.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { updateName(); } }); Label locationLabel = new Label(nameGroup, SWT.NONE); locationLabel.setText(ProjectMessages.NewApplicationWizardPage_directory_label); projectLocationField = new Text(nameGroup, SWT.BORDER); projectLocationField.setText(defaultLocation); projectLocationField.setToolTipText(ProjectMessages.NewApplicationWizardPage_directory_tooltip); projectLocationField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); projectLocationField.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { projectLocationField.selectAll(); } }); projectLocationField.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { updateLocation(); } }); Button browseButton = new Button(nameGroup, SWT.NONE); browseButton.setText(ProjectMessages.NewApplicationWizardPage_browse_label); browseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleBrowseButton(projectLocationField); } }); GridDataFactory.create(browseButton).hintWidthUnits(IDialogConstants.BUTTON_WIDTH); projectNameField.setFocus(); Group contentGroup = new Group(container, SWT.NONE); contentGroup.setText("Project templates"); GridDataFactory.create(contentGroup).indent(0, 10).span(3, 1).grab().fill(); GridLayoutFactory.fillDefaults().margins(8, 8).applyTo(contentGroup); samplesViewer = new TableViewer(contentGroup, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION); samplesViewer.setLabelProvider(new SamplesLabelProvider()); samplesViewer.setContentProvider(new ArrayContentProvider()); samplesViewer.setInput(new ArrayList<AbstractSample>()); GridDataFactory.create(samplesViewer.getControl()).grab().fill().hintChars(90, 8); samplesViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { updateMessageAndEnablement(); } }); samplesViewer.getTable().setEnabled(true); updateMessageAndEnablement(); setPageComplete(false); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { populateSamplesList(); } }); } /** * Returns the current project location URI as entered by the user, or <code>null</code> if a * valid project location has not been entered. * * @return the project location URI, or <code>null</code> */ public URI getLocationURI() { String path = getLocationPath().toOSString(); return URIUtil.toURI(path); } /** * Creates a project resource handle for the current project name field value. The project handle * is created relative to the workspace root. * <p> * This method does not create the project resource; this is the responsibility of * <code>IProject::create</code> invoked by the new project resource wizard. * </p> * * @return the new project resource handle */ public IProject getProjectHandle(String name) { return ResourcesPlugin.getWorkspace().getRoot().getProject(name); } /** * Returns the current project name as entered by the user. * * @return the project name, its anticipated initial value, or <code>null</code> if no project * name is known */ public String getProjectName() { return getProjectNameFieldValue(); } protected AbstractSample getCurrentSample() { IStructuredSelection selection = (IStructuredSelection) samplesViewer.getSelection(); if (selection.isEmpty()) { return null; } else { return (AbstractSample) selection.getFirstElement(); } } protected void handleBrowseButton(Text locationField) { DirectoryDialog directoryDialog = new DirectoryDialog(getShell()); String location = locationField.getText().trim(); if (!new File(location).exists()) { if (new File(defaultLocation).exists()) { location = defaultLocation; } else { location = new Path(defaultLocation).removeLastSegments(1).toString(); } } directoryDialog.setFilterPath(location); String directory = directoryDialog.open(); if (directory != null) { locationField.setText(directory); } } protected void updateLocation() { update(); } protected void updateName() { update(); } private boolean doesProjectExist() { IPath path = getLocationPath(); File file = path.toFile(); return file.exists(); } private AbstractSample getDefaultSample(List<AbstractSample> samples) { for (AbstractSample sample : samples) { if (sample.shouldBeDefault()) { return sample; } } return samples.get(0); } private IPath getLocationPath() { return new Path(projectLocationField.getText()).append(getProjectName()); } private String getParentDirectory() { IDialogSettings settings = DartToolsPlugin.getDefault().getDialogSettingsSection( NEW_APPPLICATION_SETTINGS); String path = settings.get(PARENT_DIR); if (path != null) { return path; } return DartCore.getUserDefaultDartFolder(); } /** * Returns the value of the project name field with leading and trailing spaces removed. * * @return the project name in the field */ private String getProjectNameFieldValue() { if (projectNameField == null) { return ""; //$NON-NLS-1$ } return projectNameField.getText().trim(); } private void populateSamplesList() { try { getContainer().run(true, false, new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask("", IProgressMonitor.UNKNOWN); final List<AbstractSample> samples = AbstractSample.getAllSamples(); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { samplesViewer.setInput(samples); samplesViewer.setSelection(new StructuredSelection(getDefaultSample(samples))); } }); monitor.done(); } }); } catch (InvocationTargetException e) { DartToolsPlugin.log(e); } catch (InterruptedException e) { DartToolsPlugin.log(e); } } private void update() { if (getProjectNameFieldValue().isEmpty()) { setMessage(ProjectMessages.OpenNewApplicationWizardAction_desc); setPageComplete(false); return; } IStatus status = validate(); if (status.isOK()) { setPageComplete(true); setErrorMessage(null); setMessage(NLS.bind(ProjectMessages.NewApplicationWizardPage_create_new, getProjectName())); } else { setPageComplete(false); setErrorMessage(status.getMessage()); } } private void updateMessageAndEnablement() { AbstractSample sample = getCurrentSample(); setMessage(sample == null ? null : sample.getDescription()); } private IStatus validate() { IStatus status = StatusUtil.getMoreSevere(Status.OK_STATUS, validateLocation()); status = StatusUtil.getMoreSevere(status, validateName()); return status; } private IStatus validateLocation() { String location = projectLocationField.getText(); IPath locationPath = new Path(location); if (!locationPath.isValidPath(getProjectName())) { return new Status( IStatus.ERROR, DartToolsPlugin.PLUGIN_ID, ProjectMessages.NewProjectCreationPage_invalid_loc); } // TODO(scheglov) check after Pub issue fixed // https://code.google.com/p/dart/issues/detail?id=10439 if (locationPath.isUNC()) { return new Status( IStatus.ERROR, DartToolsPlugin.PLUGIN_ID, ProjectMessages.NewProjectCreationPage_invalid_loc_unc); } if (doesProjectExist()) { return new Status(IStatus.ERROR, DartToolsPlugin.PLUGIN_ID, NLS.bind( ProjectMessages.NewApplicationWizardPage_error_existing, getProjectName())); } IStatus status = DirectoryVerification.getOpenDirectoryLocationStatus(new File(location)); if (!status.isOK()) { return status; } return Status.OK_STATUS; } private IStatus validateName() { AbstractSample sample = getCurrentSample(); if (sample != null) { if (sample.isValidProjectName(projectNameField.getText())) { return DartIdentifierUtil.validateIdentifier(projectNameField.getText()); } else { return new Status(IStatus.ERROR, DartCore.PLUGIN_ID, "Invalid project name"); } } return DartIdentifierUtil.validateIdentifier(projectNameField.getText()); } }