From b511195dc4a8fc55c55a1812a9086db95cca9a2b Mon Sep 17 00:00:00 2001 From: lonnen Date: Thu, 7 Oct 2010 20:17:44 +0000 Subject: [PATCH] Pushing v1.3.0 to update site. New sketch import wizard and improved wizards in general. --- .../Processing Plugin for Eclipse/feature.xml | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../builder/IncrementalChangeProcessor.java | 4 +- .../plugin/core/builder/SketchBuilder.java | 2 +- .../plugin/core/builder/SketchProject.java | 13 +- .../processing.plugin.ui/META-INF/MANIFEST.MF | 2 +- editor/processing.plugin.ui/plugin.xml | 15 +- .../ui/wizards/ExportAsAppletWizard.java | 16 -- .../plugin/ui/wizards/ImportSketchWizard.java | 112 +++++++++++ .../ui/wizards/ImportSketchWizardPage.java | 186 ++++++++++++++++++ .../plugin/ui/wizards/NewSketchWizard.java | 11 +- .../ui/wizards/NewSketchWizardPage.java | 46 +++-- editor/processing.plugin.updateSite/site.xml | 3 + 13 files changed, 357 insertions(+), 57 deletions(-) create mode 100644 editor/processing.plugin.ui/src/processing/plugin/ui/wizards/ImportSketchWizard.java create mode 100644 editor/processing.plugin.ui/src/processing/plugin/ui/wizards/ImportSketchWizardPage.java diff --git a/editor/Processing Plugin for Eclipse/feature.xml b/editor/Processing Plugin for Eclipse/feature.xml index 65868ef4c..4854406d3 100644 --- a/editor/Processing Plugin for Eclipse/feature.xml +++ b/editor/Processing Plugin for Eclipse/feature.xml @@ -2,7 +2,7 @@ diff --git a/editor/processing.plugin.core/META-INF/MANIFEST.MF b/editor/processing.plugin.core/META-INF/MANIFEST.MF index f83e1d0a0..074e5767c 100644 --- a/editor/processing.plugin.core/META-INF/MANIFEST.MF +++ b/editor/processing.plugin.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Processing Plugin Core Bundle-SymbolicName: processing.plugin.core;singleton:=true -Bundle-Version: 0.2.3.0 +Bundle-Version: 0.2.3.3 Bundle-Activator: processing.plugin.core.ProcessingCore Bundle-Vendor: Processing.org Require-Bundle: org.eclipse.core.runtime, diff --git a/editor/processing.plugin.core/src/processing/plugin/core/builder/IncrementalChangeProcessor.java b/editor/processing.plugin.core/src/processing/plugin/core/builder/IncrementalChangeProcessor.java index c0502ad0d..bb9ed0db7 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/builder/IncrementalChangeProcessor.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/builder/IncrementalChangeProcessor.java @@ -58,7 +58,7 @@ public class IncrementalChangeProcessor { /** Process an IResourceChangeEvent */ public boolean resourceChanged(IResourceChangeEvent event){ - printEvent(event); + //Event(event); IResourceDelta delta = event.getDelta(); return this.resourceChanged(delta); } @@ -66,7 +66,7 @@ public class IncrementalChangeProcessor { /** Process an IResourceDelta */ public boolean resourceChanged(IResourceDelta delta){ if (delta == null) return false; - printResourceChanges(delta); + //printResourceChanges(delta); IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() { public boolean visit(IResourceDelta delta) throws CoreException { diff --git a/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchBuilder.java b/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchBuilder.java index 6a5cc8ac2..a049101a2 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchBuilder.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchBuilder.java @@ -426,7 +426,7 @@ public class SketchBuilder extends IncrementalProjectBuilder{ } boolean importProblems = false; - sketchProject.libraryPaths = null; + sketchProject.libraryPaths.clear(); for (int i=0; i < result.extraImports.size(); i++){ String importPackage = result.extraImports.get(i); int dot = importPackage.lastIndexOf('.'); diff --git a/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchProject.java b/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchProject.java index 2cd757966..72e82b3a7 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchProject.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchProject.java @@ -52,7 +52,7 @@ import processing.plugin.core.ProcessingLog; * This also holds state information about the sketch itself * that is generated and collected from the sketch files, the * builder, a thorough background check, and maybe a little - * dumpster diving. It acs as an ad-hoc model of a sketch project. + * dumpster diving. It acts as an ad-hoc model of a sketch project. */ public class SketchProject implements IProjectNature { @@ -73,7 +73,7 @@ public class SketchProject implements IProjectNature { protected boolean wasLastBuildSuccessful = false; - protected ArrayList libraryPaths = null; + protected ArrayList libraryPaths = new ArrayList(); /** * Return the SketchProject associated with the given IProject, or null @@ -156,7 +156,14 @@ public class SketchProject implements IProjectNature { /** Associate the sketch builder with this nature's project */ public void configure() throws CoreException { if (!project.isOpen()) return; - + + /* When the workspace is out of date after an import, + * but before the background refresh is finished these will + * fail iff the folder already exists, so we expect a logged + * error but no real negative consequences. The first build + * after the refresh is finished will align everything + * properly again. + */ getCodeFolder(); getDataFolder(); getBuildFolder(); diff --git a/editor/processing.plugin.ui/META-INF/MANIFEST.MF b/editor/processing.plugin.ui/META-INF/MANIFEST.MF index e0abbd325..bccfc12ea 100644 --- a/editor/processing.plugin.ui/META-INF/MANIFEST.MF +++ b/editor/processing.plugin.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Processing Plugin User Interface Elements Bundle-SymbolicName: processing.plugin.ui;singleton:=true -Bundle-Version: 0.2.2.1 +Bundle-Version: 0.2.3.0 Bundle-Activator: processing.plugin.ui.ProcessingPlugin Bundle-Vendor: Processing.org Require-Bundle: org.eclipse.ui, diff --git a/editor/processing.plugin.ui/plugin.xml b/editor/processing.plugin.ui/plugin.xml index daef80b4f..89e2e4ed8 100644 --- a/editor/processing.plugin.ui/plugin.xml +++ b/editor/processing.plugin.ui/plugin.xml @@ -34,7 +34,6 @@ + + + + + + + + * Contains a single page the requests the directory of the sketch + * and runs a check to make sure that the sketch contains a *.pde + * file with the same name as the directory before allowing import. + * Also, warns the user if it does not appear to be in a sketchbook, + * but does not require it to be. + */ +public class ImportSketchWizard extends Wizard implements IImportWizard { + + /** The single page in the wizard */ + private ImportSketchWizardPage page; + + /** The project to be created */ + private IProject project; + + /** A boring ol' constructor */ + public ImportSketchWizard() {} + + /** Does nothing */ + public void init(IWorkbench workbench, IStructuredSelection selection) {} + + /** Initialize the single page and add it to the wizard. */ + public void addPages(){ + setWindowTitle("New Sketch Wizard"); + page = new ImportSketchWizardPage(); + addPage(page); + } + + /** + * When the finish button is clicked, create the project. + *

+ * The wizard page validates the fields before the finish button + * is enabled, so there is no validation here. The creation of the + * project is wrapped in a runnable object so it can be monitored + * and potentially canceled by the user if it runs long and ties + * up the system. + */ + public boolean performFinish() { + final IPath sketchPath = page.getSketchPath(); + final String sketchName = sketchPath.lastSegment(); + project = ResourcesPlugin.getWorkspace().getRoot().getProject(sketchName); + + final IProjectDescription sketchDescription = ResourcesPlugin.getWorkspace().newProjectDescription(project.getName()); + sketchDescription.setLocation(sketchPath); + + WorkspaceModifyOperation op = new WorkspaceModifyOperation(){ + protected void execute(IProgressMonitor monitor) throws CoreException{ + createNewProject(sketchDescription, project, monitor); + } + }; + + try{ + getContainer().run(true, true, op); + } catch (InvocationTargetException e){ + Throwable realException = e.getTargetException(); + MessageDialog.openError(getShell(), "Error!", realException.getMessage()); + return false; + } catch (InterruptedException e){ // "shut it down" + return false; + } + return true; + } + + /** Creates the project in the workspace */ + protected void createNewProject(IProjectDescription description, IProject proj, + IProgressMonitor monitor) throws CoreException, OperationCanceledException{ + monitor.beginTask("Creating a new Sketch", 2); + try{ + proj.create(description, new SubProgressMonitor(monitor, 1)); + proj.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1)); + } finally{ + monitor.done(); + } + SketchProject.addSketchNature(proj); + } + + +} \ No newline at end of file diff --git a/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/ImportSketchWizardPage.java b/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/ImportSketchWizardPage.java new file mode 100644 index 000000000..76eccfc11 --- /dev/null +++ b/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/ImportSketchWizardPage.java @@ -0,0 +1,186 @@ +/** + * Copyright (c) 2010 Chris Lonnen. 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.opensource.org/licenses/eclipse-1.0.php + * + * Contributors: + * Chris Lonnen - initial API and implementation + */ +package processing.plugin.ui.wizards; + +import java.io.File; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.wizard.WizardPage; +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; + +import processing.plugin.core.ProcessingCorePreferences; + +public class ImportSketchWizardPage extends WizardPage { + + /** field containing the path to the existing sketch folder */ + private Text sketchPathField; + + public ImportSketchWizardPage() { + super("Import Sketch"); + setTitle("Import Sketch Wizard"); + setDescription("Import an existing Processing sketch to the workspace."); + } + + /* awt stuff. @see the javadoc for WizardPage */ + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + final GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 3; + container.setLayout(gridLayout); + setControl(container); + + final Label sketchPathLabel = new Label(container, SWT.NONE); + final GridData sketchPathLabelPos = new GridData(); + sketchPathLabelPos.horizontalSpan = 3; + sketchPathLabel.setLayoutData(sketchPathLabelPos); + sketchPathLabel.setText("Select the root folder of the sketch to import"); + + final Label sketchPathBoxLabel = new Label(container, SWT.NONE); + final GridData sketchPathBoxLabelPos = new GridData(GridData.HORIZONTAL_ALIGN_END); +// sketchPathBoxLabelPos.horizontalIndent = 20; + sketchPathBoxLabel.setLayoutData(sketchPathBoxLabelPos); + sketchPathBoxLabel.setText("Sketch Folder:"); + + sketchPathField = new Text(container, SWT.BORDER); + sketchPathField.addModifyListener( + new ModifyListener() { + public void modifyText(ModifyEvent e){ + updatePageComplete(); + } + }); + sketchPathField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + final Button browseButton = new Button(container, SWT.NONE); + browseButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e){ + browseForDestinationFolder(); + } + }); + browseButton.setText("Browse..."); + initContents(); + } + + /** + * Initialize the contents of the sketch book path. + *

+ * If the user has specified a sketchbook, the sketchbook + * populates the field initially for convenience, even + * though the sketchbook is not itself a valid import. + */ + private void initContents() { + IPath sketchbook = ProcessingCorePreferences.current().getSketchbookPath(); + if(sketchbook != null) + sketchPathField.setText(sketchbook.toString()); + updatePageComplete(); + } + + /** + * Browse button functionality to find a destination folder. + *

+ * If the path happens to be workspace relative, this will + * prettify the path. + */ + protected void browseForDestinationFolder() { + IPath path = browse(getSketchPath()); + if (path == null) return; + IPath rootLoc = ResourcesPlugin.getWorkspace().getRoot().getLocation(); + if (rootLoc.isPrefixOf(path)) + path = path.setDevice(null).removeFirstSegments(rootLoc.segmentCount()); + sketchPathField.setText(path.toString()); + } + + /** + * Sets up a dialog box allowing the user to browse the file system and + * select a directory. + * + * @param path the path to be investigated + * @return the chosen path from the dialog box + */ + private IPath browse(IPath path){ + DirectoryDialog dialog = new DirectoryDialog(getShell()); + if (path != null){ + if(path.segmentCount() > 1) + dialog.setFilterPath(path.toOSString()); + } + String result = dialog.open(); + if (result == null) + return null; + return new Path(result); + } + + /** + * Does some validation of the selected path before enabling the + * finish button. + */ + private void updatePageComplete() { + setPageComplete(false); + + // check path first + // If it contains the sketchbook path, treat it as empty + IPath sketchLoc = getSketchPath(); + IPath sketchbook = ProcessingCorePreferences.current().getSketchbookPath(); + if (sketchLoc == null + || !sketchLoc.toFile().exists() + || (sketchbook != null + && sketchLoc.makeAbsolute().equals(sketchbook.makeAbsolute()))){ + setErrorMessage(null); + setMessage("Please specify a folder containing a sketch."); + return; + } + + + // ensure the path contains the expected folderName.pde file + String sketchName = sketchLoc.lastSegment(); + //System.out.println(sketchName + ".pde"); + File mainFile = new File(sketchLoc.toFile(), sketchName+".pde"); + if(!mainFile.exists()){ + setMessage(null); + setErrorMessage("The sketch folder does not appear to be valid. " + + "Could not find " + sketchName + ".pde"); + return; + } + + // if nothing was caught, enable the finish button + setPageComplete(true); + setMessage("Press Finish to import the sketch"); + setErrorMessage(null); + } + + /** + * Tries to resolve the contents of the sketch path field to an IPath, + * and returns it. If the field contains a relative path it will be + * resolved relative to the Eclipse workspace folder. + * + * @return an absolute IPath or null + */ + protected IPath getSketchPath() { + String text = sketchPathField.getText().trim(); + if (text.length() == 0) return null; + IPath path = new Path(text); + if (!path.isAbsolute()) // relative paths are relative to the Eclipse workspace + path = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(path); + return path; + } + +} diff --git a/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizard.java b/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizard.java index 3fefaf16f..db9b4509f 100644 --- a/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizard.java +++ b/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizard.java @@ -40,8 +40,6 @@ import processing.plugin.ui.wizards.NewSketchWizardPage; *

* Contains a single page the requests the name of the sketch * and the sketch book folder to put the sketch in. - * - * @author lonnen */ public class NewSketchWizard extends Wizard implements INewWizard { @@ -65,7 +63,6 @@ public class NewSketchWizard extends Wizard implements INewWizard { * and potentially canceled by the user. */ public boolean performFinish() { - final String sketchName = page.getSketchName(); final IPath sketchbookPath = page.getSketchbookLoc().append(sketchName); project = ResourcesPlugin.getWorkspace().getRoot().getProject(sketchName); @@ -104,18 +101,18 @@ public class NewSketchWizard extends Wizard implements INewWizard { */ protected void createNewProject(IProjectDescription description, IProject proj, IProgressMonitor monitor) throws CoreException, OperationCanceledException{ - monitor.beginTask("Creating a new Sketch", 400); + monitor.beginTask("Creating a new Sketch", 4); try{ // create the project root - proj.create(description, new SubProgressMonitor(monitor, 100)); - proj.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 100)); + proj.create(description, new SubProgressMonitor(monitor, 1)); + proj.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1)); if (monitor.isCanceled()){throw new OperationCanceledException();} IContainer container = (IContainer) proj; //create the default sketch file - addFileToContainer(container, new Path(project.getName() + ".pde"), null, new SubProgressMonitor(monitor, 100)); + addFileToContainer(container, new Path(project.getName() + ".pde"), null, new SubProgressMonitor(monitor, 1)); } finally{ monitor.done(); } diff --git a/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizardPage.java b/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizardPage.java index 2e9dfba41..5c9543c21 100644 --- a/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizardPage.java +++ b/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizardPage.java @@ -51,18 +51,18 @@ public class NewSketchWizardPage extends WizardPage { gridLayout.numColumns = 3; container.setLayout(gridLayout); setControl(container); - + final Label label = new Label(container, SWT.NONE); final GridData gridData = new GridData(); gridData.horizontalSpan = 3; label.setLayoutData(gridData); - label.setText("Select a name for the new sketch."); - + label.setText("Select a name for the new sketch"); + final Label label_1 = new Label(container, SWT.NONE); final GridData gridData_1 = new GridData(GridData.HORIZONTAL_ALIGN_END); label_1.setLayoutData(gridData_1); label_1.setText("Sketch Name:"); - + sketchNameField = new Text(container, SWT.BORDER); sketchNameField.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e){ @@ -70,19 +70,18 @@ public class NewSketchWizardPage extends WizardPage { } }); sketchNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - + final Label label_2 = new Label(container, SWT.NONE); final GridData gridData_2 = new GridData(); gridData_2.horizontalSpan = 3; label_2.setLayoutData(gridData_2); - + final Label label_3 = new Label(container, SWT.NONE); final GridData gridData_3 = new GridData(); gridData_3.horizontalSpan = 3; label_3.setLayoutData(gridData_3); - label_3.setLayoutData(gridData_3); - label_3.setText("Select the sketchbook folder that will contain the sketch:"); - + label_3.setText("Select the sketchbook folder that will contain the sketch"); + final Label label_4 = new Label(container, SWT.NONE); final GridData gridData_4 = new GridData(); gridData_4.horizontalIndent = 20; @@ -97,14 +96,14 @@ public class NewSketchWizardPage extends WizardPage { } }); sketchbookPathField.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); - + final Button button_1 = new Button(container, SWT.NONE); button_1.addSelectionListener(new SelectionAdapter(){ public void widgetSelected(SelectionEvent e){browseForDestinationFolder(); } }); button_1.setText("Browse..."); - + initContents(); } @@ -148,13 +147,13 @@ public class NewSketchWizardPage extends WizardPage { return null; return new Path(result); } - + /** * Verifies that the sketchbook path exists and does not already contain a sketch with that name. - */ + */ private void updatePageComplete() { setPageComplete(false); - + // check the sketchbook path first IPath sketchbookLoc = getSketchbookLoc(); if (sketchbookLoc == null || !sketchbookLoc.toFile().exists()){ @@ -162,20 +161,19 @@ public class NewSketchWizardPage extends WizardPage { setErrorMessage("Please specify a sketchbook folder."); return; } - + // ensure the sketch isn't already present in the sketchbook String sketchName = getSketchName(); - for( File child : sketchbookLoc.toFile().listFiles()){ - if (child.isDirectory() && child.getName().equals(sketchName)){ - setMessage(null); - setErrorMessage("A sketch with that name already exists. Please choose another."); - return; - } + File child = (sketchName == null) ? null : new File(sketchbookLoc.toFile(), sketchName); + if (child != null && child.exists() && child.isDirectory()){ + setMessage(null); + setErrorMessage("A sketch with that name already exists in that location. Please choose another."); + return; } - + // if nothing was caught, enable the finish button setPageComplete(true); - setMessage(null); + setMessage("Press finish to create a new sketch"); setErrorMessage(null); } @@ -210,5 +208,5 @@ public class NewSketchWizardPage extends WizardPage { path = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(path); return path; } - + } diff --git a/editor/processing.plugin.updateSite/site.xml b/editor/processing.plugin.updateSite/site.xml index beea91f80..11a280a50 100644 --- a/editor/processing.plugin.updateSite/site.xml +++ b/editor/processing.plugin.updateSite/site.xml @@ -3,6 +3,9 @@ + + + Provides integration for the Processing programming language to the Eclipse platform. See http://www.processing.org to learn more.