diff --git a/editor/processing.plugin.core/Resources/export/application.exe b/editor/processing.plugin.core/Resources/export/application.exe new file mode 100644 index 000000000..ea70a3a2d Binary files /dev/null and b/editor/processing.plugin.core/Resources/export/application.exe differ diff --git a/editor/processing.plugin.core/Resources/export/loading.gif b/editor/processing.plugin.core/Resources/export/loading.gif new file mode 100644 index 000000000..eccd56712 Binary files /dev/null and b/editor/processing.plugin.core/Resources/export/loading.gif differ diff --git a/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/MacOS/JavaApplicationStub b/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/MacOS/JavaApplicationStub new file mode 100644 index 000000000..9ae8d5554 Binary files /dev/null and b/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/MacOS/JavaApplicationStub differ diff --git a/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/MacOS/JavaApplicationStub64 b/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/MacOS/JavaApplicationStub64 new file mode 100644 index 000000000..a8fbda5e2 Binary files /dev/null and b/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/MacOS/JavaApplicationStub64 differ diff --git a/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/PkgInfo b/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/PkgInfo new file mode 100644 index 000000000..bd04210fb --- /dev/null +++ b/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/Resources/sketch.icns b/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/Resources/sketch.icns new file mode 100644 index 000000000..8ffb8d7de Binary files /dev/null and b/editor/processing.plugin.core/Resources/export/skeleton.app/Contents/Resources/sketch.icns differ diff --git a/editor/processing.plugin.core/Resources/export/template.plist b/editor/processing.plugin.core/Resources/export/template.plist new file mode 100644 index 000000000..fb10ceb70 --- /dev/null +++ b/editor/processing.plugin.core/Resources/export/template.plist @@ -0,0 +1,75 @@ + + + + + CFBundleName + @@sketch@@ + CFBundleVersion + 1.0 + CFBundleAllowMixedLocalizations + true + CFBundleExecutable + JavaApplicationStub + CFBundleDevelopmentRegion + English + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleInfoDictionaryVersion + 6.0 + CFBundleIconFile + sketch.icns + CFBundleIdentifier + @@sketch@@ + + + LSUIPresentationMode + @@lsuipresentationmode@@ + + + LSArchitecturePriority + + i386 + ppc + + + Java + + VMOptions + @@vmoptions@@ + MainClass + @@sketch@@ + JVMVersion + 1.5* + JVMArchs + + i386 + ppc + + ClassPath + @@classpath@@ + + + Properties + + apple.laf.useScreenMenuBar + true + apple.awt.showGrowBox + false + com.apple.smallTabs + true + apple.awt.Antialiasing + false + apple.awt.TextAntialiasing + true + com.apple.hwaccel + true + apple.awt.use-file-dialog-packages + false + + + + diff --git a/editor/processing.plugin.core/plugin.xml b/editor/processing.plugin.core/plugin.xml index bc5743ca8..31f74a2c7 100644 --- a/editor/processing.plugin.core/plugin.xml +++ b/editor/processing.plugin.core/plugin.xml @@ -45,7 +45,7 @@ delegate="processing.plugin.core.launching.ProcessingSketchLaunchConfigurationDelegate" id="processing.plugin.core.launching.processingSketch" modes="run" - name="Processing Sketch"> + name="Processing Sketch Applet"> diff --git a/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCore.java b/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCore.java index 438843f6d..2ef8d8a6b 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCore.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCore.java @@ -22,6 +22,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Plugin; import processing.plugin.core.builder.Utilities; @@ -75,19 +76,30 @@ public final class ProcessingCore extends Plugin { /* public void start(BundleContext context) throws Exception {} */ /* public void stop(BundleContext context) throws Exception {} */ - /** * Gets a URL to a file or folder in the plug-in's Resources folder. - * Returns null if something went wrong. + * Returns null if the path results in a bad URL. + * + * @param path relative path from the Resources folder */ - public URL getPluginResource(String fileName){ + public URL getPluginResource(String path){ try{ - return new URL(this.getBundle().getEntry("/"), "Resources/" + fileName); + return new URL(this.getBundle().getEntry("/"), "Resources/" + path); } catch (MalformedURLException e){ return null; } } + /** + * Returns a URL to a file or folder in the plug-in's Resources folder. + * Returns null if the path results in a bad URL. + * + * @param path relative from the Resources folder + */ + public URL getPluginResource(IPath path){ + return getPluginResource(path.toOSString()); + } + /** * Resolves the plug-in resources folder to a File and returns it. This will include the * Processing libraries and the core libraries folder. @@ -95,7 +107,7 @@ public final class ProcessingCore extends Plugin { * @return File reference to the core resources */ public File getPluginResourceFolder(){ - URL fileLocation = ProcessingCore.getProcessingCore().getPluginResource(""); + URL fileLocation = getPluginResource(""); try { File folder = new File(FileLocator.toFileURL(fileLocation).getPath()); if (folder.exists()) diff --git a/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCorePreferences.java b/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCorePreferences.java index 5394fff45..ea2db1558 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCorePreferences.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCorePreferences.java @@ -19,6 +19,7 @@ import org.eclipse.core.runtime.Preferences; * be done by preferences pages in processing.plugin.ui plug-in, but * may be programatically accessed in the case of headless operation. */ +@SuppressWarnings("deprecation") public class ProcessingCorePreferences { private static ProcessingCorePreferences current; 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 664c68f2e..9ca08f661 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 @@ -226,6 +226,45 @@ public class SketchBuilder extends IncrementalProjectBuilder{ StringWriter stream = new StringWriter(); result = preproc.write(stream, bigCode.toString(), codeFolderPackages); + + String scrubbed = Utilities.scrubComments(stream.toString()); + String[] matches = Utilities.match(scrubbed, Utilities.SIZE_REGEX); + + if(matches != null){ + try { + int wide = Integer.parseInt(matches[1]); + int high = Integer.parseInt(matches[2]); + + if (high > 0){ + SketchProject.sketch_height = high; + } else { + SketchProject.sketch_height = -1; + } + if( wide > 0) { + SketchProject.sketch_width = wide; + } else { + SketchProject.sketch_width = -1; + } + + } catch (NumberFormatException e) { + // found a reference to size, but it didn't + // seem to contain numbers + +// final String message = +// "The size of this applet could not automatically be\n" + +// "determined from your code. You'll have to edit the\n" + +// "HTML file to set the size of the applet.\n" + +// "Use only numeric values (not variables) for the size()\n" + +// "command. See the size() reference for an explanation."; + + // set these back to null + SketchProject.sketch_height = -1; + SketchProject.sketch_width = -1; + + ProcessingLog.logInfo("Could not find applet size"); + } + } // else no size() command found + ByteArrayInputStream inStream = new ByteArrayInputStream(stream.toString().getBytes()); try{ if (!output.exists()){ 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 bbc3444e3..40f2fd284 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 @@ -29,12 +29,19 @@ import processing.plugin.core.ProcessingLog; public class SketchProject implements IProjectNature { - /** value: "processing.plugin.core.processingnature" */ + /** value: "processing.plugin.core.sketchNature" */ public static final String NATURE_ID = ProcessingCore.PLUGIN_ID + ".sketchNature"; /** The basic project entry being managed */ protected IProject project; + // TODO make these a preference + public static final int DEFAULT_WIDTH = 100; + public static final int DEFAULT_HEIGHT = 100; + + // set every build + protected static int sketch_width = -1; + protected static int sketch_height = -1; /** * Return the SketchProject associated with the given IProject, or null @@ -434,4 +441,20 @@ public class SketchProject implements IProjectNature { JavaCore.setOptions(options); } + + /** Return the sketch's height, or the default height if size() has not been specified */ + public int getHeight() { + return (sketch_height == -1) ? DEFAULT_HEIGHT : sketch_height; + } + + /** Return the sketch's width, or the default width if size() has not been specified */ + public int getWidth(){ + return (sketch_width == -1) ? DEFAULT_WIDTH : sketch_width; + } + + /** Returns the name of the main type of the compiled sketch*/ + public String getMainType() { + return project.getName(); + } + } \ No newline at end of file diff --git a/editor/processing.plugin.core/src/processing/plugin/core/builder/Utilities.java b/editor/processing.plugin.core/src/processing/plugin/core/builder/Utilities.java index abcaf487d..bfc6e6815 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/builder/Utilities.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/builder/Utilities.java @@ -18,6 +18,7 @@ import java.util.zip.ZipFile; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; + import processing.plugin.core.ProcessingCore; import processing.plugin.core.ProcessingCorePreferences; import processing.plugin.core.ProcessingLog; @@ -37,7 +38,9 @@ import processing.plugin.core.ProcessingLog; public class Utilities { public static final String PACKAGE_REGEX = "(?:^|\\s|;)package\\s+(\\S+)\\;"; - + public static final String SIZE_REGEX = + "(?:^|\\s|;)size\\s*\\(\\s*(\\S+)\\s*,\\s*([^\\s,\\)]+),?\\s*([^\\)]*)\\s*\\)\\s*\\;"; + /** * Read in a file and return it as a string * @@ -496,5 +499,53 @@ public class Utilities { } } } + + static public String scrubComments(String what) { + char p[] = what.toCharArray(); + + int index = 0; + while (index < p.length) { + // for any double slash comments, ignore until the end of the line + if ((p[index] == '/') && + (index < p.length - 1) && + (p[index+1] == '/')) { + p[index++] = ' '; + p[index++] = ' '; + while ((index < p.length) && + (p[index] != '\n')) { + p[index++] = ' '; + } + + // check to see if this is the start of a new multiline comment. + // if it is, then make sure it's actually terminated somewhere. + } else if ((p[index] == '/') && + (index < p.length - 1) && + (p[index+1] == '*')) { + p[index++] = ' '; + p[index++] = ' '; + boolean endOfRainbow = false; + while (index < p.length - 1) { + if ((p[index] == '*') && (p[index+1] == '/')) { + p[index++] = ' '; + p[index++] = ' '; + endOfRainbow = true; + break; + + } else { + // continue blanking this area + p[index++] = ' '; + } + } + if (!endOfRainbow) { + throw new RuntimeException("Missing the */ from the end of a " + + "/* comment */"); + } + } else { // any old character, move along + index++; + } + } + return new String(p); + } + } diff --git a/editor/processing.plugin.core/src/processing/plugin/core/launching/ProcessingClasspathProvider.java b/editor/processing.plugin.core/src/processing/plugin/core/launching/ProcessingClasspathProvider.java deleted file mode 100644 index fd04cfda9..000000000 --- a/editor/processing.plugin.core/src/processing/plugin/core/launching/ProcessingClasspathProvider.java +++ /dev/null @@ -1,13 +0,0 @@ -package processing.plugin.core.launching; - -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.jdt.launching.IRuntimeClasspathEntry; -import org.eclipse.jdt.launching.StandardClasspathProvider; - -public class ProcessingClasspathProvider extends StandardClasspathProvider{ - - public IRuntimeClasspathEntry[] computeUnresolvedClasspath(ILaunchConfiguration configuration) { - return null; - } - -} diff --git a/editor/processing.plugin.core/src/processing/plugin/core/launching/ProcessingSketchLaunchConfigurationDelegate.java b/editor/processing.plugin.core/src/processing/plugin/core/launching/ProcessingSketchLaunchConfigurationDelegate.java index 8d099682c..2881d9451 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/launching/ProcessingSketchLaunchConfigurationDelegate.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/launching/ProcessingSketchLaunchConfigurationDelegate.java @@ -1,34 +1,65 @@ +/******************************************************************************* + * 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.opensource.org/licenses/cpl1.0.php + * + * Contributors: + * IBM Corporation - initial API and implementation + * Chris Lonnen - adaptation for Processing + *******************************************************************************/ package processing.plugin.core.launching; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; import java.util.Map; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; - import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; -import org.eclipse.jdt.launching.IRuntimeClasspathEntry; -import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.JavaLaunchDelegate; import org.eclipse.jdt.launching.JavaRuntime; /** * The launch configuration delegate for Processing Sketches. It is really a customized Java * launch configuration delegate, as Processing Sketches are compiled down and ultimately run - * as Java applications (shhh! dont tell anyone) + * as Java applications (shhh! don't tell anyone). */ -public class ProcessingSketchLaunchConfigurationDelegate extends JavaLaunchDelegate { - - public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { - String workingDirectory = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, ""); - launch.setAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, workingDirectory); - super.launch(configuration, mode, launch, monitor); - } +public class ProcessingSketchLaunchConfigurationDelegate extends JavaLaunchDelegate implements IDebugEventSetListener { /** - * If this is being started in run mode return true, otherwise return false to indicate it shouldn't be run + * Maps ILaunch objects to File objects that represent the .html file initiating the + * applet launch. This is used to delete the .html file when the launch terminates. + */ + private static Map fgLaunchToFileMap = new HashMap(); + + /** Used to map temp file to launch object. */ + private ILaunch fLaunch; + + /* (non-Javadoc) Makes sure to cleanup the leftovers if things break. */ + public synchronized void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { + try{ + fLaunch = launch; + super.launch(configuration, mode, launch, monitor); + } catch (CoreException e){ + cleanup(launch); + throw e; + } + fLaunch = null; + } + + /** + * Called first in the launch sequence. Checks to make sure this launcher is being executed + * in run mode, and returns true to indicate that things can proceed. If it is being executed + * in debug mode or some other unsupported mode, return false to abort the launch. */ public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { if(mode.equals(ILaunchManager.RUN_MODE)){ @@ -36,21 +67,141 @@ public class ProcessingSketchLaunchConfigurationDelegate extends JavaLaunchDeleg } return false; } - - /** Returns the default VMInstall object. */ - public IVMInstall getVMInstall(ILaunchConfiguration configuration) throws CoreException { - return JavaRuntime.getDefaultVMInstall(); + + // public String getJavaPolicyFile() ?? + + /** Clean up the temp files and listeners after a launch */ + public void cleanup(ILaunch launch){ + File temp = (File) fgLaunchToFileMap.get(launch); + if (temp != null){ + try { + fgLaunchToFileMap.remove(launch); + temp.delete(); + } finally { + // unregister any listeners? there shouldn't be any + // because we don't support debugging + } + } + + } + + // URL fileLocation = ProcessingCore.getProcessingCore().getPluginResource(""); + // try { + // File folder = new File(FileLocator.toFileURL(fileLocation).getPath()); + // if (folder.exists()) + // return folder; + // } catch (Exception e) { + // ProcessingLog.logError(e); + // } + + public File buildHTMLFile(ILaunchConfiguration configuration, File dir) { + FileWriter writer = null; + File tempFile = null; + try { + String name = getAppletMainTypeName(configuration); + tempFile = new File(dir, name + System.currentTimeMillis() + ".html"); //$NON-NLS-1$ + writer = new FileWriter(tempFile); + writer.write("\n"); + writer.write("\n"); + writer.write("\n"); + Map parameters = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_PARAMETERS, new HashMap()); + if (parameters.size() != 0) { + Iterator iterator= parameters.entrySet().iterator(); + while(iterator.hasNext()) { + Map.Entry next = (Map.Entry) iterator.next(); + writer.write("\n"); + } + } + writer.write("\n"); + writer.write("\n"); + writer.write("\n"); + } catch(IOException e) { + } catch(CoreException e) { + } finally { + if (writer != null) { + try { + writer.close(); + } catch(IOException e) { + } + } + } + + return tempFile; } - public Map getVMSpecificAttributesMap(ILaunchConfiguration configuration) throws CoreException{ - return null; + public String getQuotedString(String string) { + if (string.indexOf('"') == -1) { + return '"' + string + '"'; + } + return '\'' + string + '\''; } - - public String[] getClassPath(ILaunchConfiguration configuration) throws CoreException{ - IRuntimeClasspathEntry[] entries = new ProcessingClasspathProvider().computeUnresolvedClasspath(configuration); - //TODO pickup here http://www.eclipse.org/articles/Article-Launch-Framework/launch.html - return null; + + + /* @see org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate#getProgramArguments(org.eclipse.debug.core.ILaunchConfiguration) */ + public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException{ + File workingDir = verifyWorkingDirectory(configuration); + File htmlFile = buildHTMLFile(configuration, workingDir); + if(htmlFile == null){ + abort("Could not build HTML for applet launch.", null, IJavaLaunchConfigurationConstants.ERR_COULD_NOT_BUILD_HTML); + } + // add a mapping of the launch to the html file + fgLaunchToFileMap.put(fLaunch, htmlFile); + return htmlFile.getName(); } - - + + // Uncomment if we end up using javaPolicyFile + // public String getVMArguments(ILaunchConfiguration configuration) throws CoreException { + // StringBuffer arguments = new StringBuffer(super.getVMArguments(configuration)); + // File workingDir = verifyWorkingDirectory(configuration); + // String javaPolicyFile = getJavaPolicyFile(workingDir); + // arguments.append(javaPolicyFile); + // return arguments.toString(); + // } + + + public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException{ + return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_APPLETVIEWER_CLASS, IJavaLaunchConfigurationConstants.DEFAULT_APPLETVIEWER_CLASS); + } + + /** + * Returns the applet's main type name. + * + * @param configuration + * @throws CoreException + */ + public String getAppletMainTypeName(ILaunchConfiguration configuration) throws CoreException{ + return super.getMainTypeName(configuration); + } + + /* @see org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate#getDefaultWorkingDirectory(org.eclipse.debug.core.ILaunchConfiguration) */ + public File getDefaultWorkingDirectory(ILaunchConfiguration configuration) throws CoreException{ + // default working dir for applets is the project's output directory + String outputDir = JavaRuntime.getProjectOutputDirectory(configuration); + if (outputDir == null) { + // if no project attribute, default to eclipse directory + return new File(System.getProperty("user.dir")); + } + IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(outputDir); + if (resource == null || !resource.exists()) { + //default to eclipse directory + return new File(System.getProperty("user.dir")); + } + return resource.getLocation().toFile(); + } + } diff --git a/editor/processing.plugin.ui/META-INF/MANIFEST.MF b/editor/processing.plugin.ui/META-INF/MANIFEST.MF index f5c5b2b0a..ce1279e3f 100644 --- a/editor/processing.plugin.ui/META-INF/MANIFEST.MF +++ b/editor/processing.plugin.ui/META-INF/MANIFEST.MF @@ -12,8 +12,11 @@ Require-Bundle: org.eclipse.ui, org.eclipse.jface.text;bundle-version="3.6.0", org.eclipse.ui.editors;bundle-version="3.6.0", org.eclipse.core.resources;bundle-version="3.6.0", - processing.plugin.core;bundle-version="0.1.0" - + processing.plugin.core;bundle-version="0.1.0", + org.eclipse.debug.ui, + org.eclipse.jdt.launching;bundle-version="3.5.100", + org.eclipse.ui.ide;bundle-version="3.6.0", + org.eclipse.jdt.core;bundle-version="3.6.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Import-Package: org.eclipse.ui.actions diff --git a/editor/processing.plugin.ui/Resources/16x16_icon.gif b/editor/processing.plugin.ui/Resources/16x16_icon.gif new file mode 100644 index 000000000..76a462f44 Binary files /dev/null and b/editor/processing.plugin.ui/Resources/16x16_icon.gif differ diff --git a/editor/processing.plugin.ui/plugin.xml b/editor/processing.plugin.ui/plugin.xml index fb5c326b8..13efb4e57 100644 --- a/editor/processing.plugin.ui/plugin.xml +++ b/editor/processing.plugin.ui/plugin.xml @@ -43,5 +43,43 @@ + + + + Hides the generated folder and its contents from the UI. + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/editor/processing.plugin.ui/src/processing/plugin/ui/launching/RunSketchAsAppletShortcut.java b/editor/processing.plugin.ui/src/processing/plugin/ui/launching/RunSketchAsAppletShortcut.java new file mode 100644 index 000000000..164d39fce --- /dev/null +++ b/editor/processing.plugin.ui/src/processing/plugin/ui/launching/RunSketchAsAppletShortcut.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * 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.opensource.org/licenses/cpl1.0.php + * + * Contributors: + * IBM Corporation - initial API + * Chris Lonnen - implementation for Processing + *******************************************************************************/ +package processing.plugin.ui.launching; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.ILaunchShortcut; +import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.ide.ResourceUtil; + +import processing.plugin.core.builder.SketchProject; +import processing.plugin.ui.ProcessingLog; + +public class RunSketchAsAppletShortcut implements ILaunchShortcut { + + protected ILaunchConfiguration createConfiguration(IProject project){ + if (project == null) return null; + SketchProject sketch = SketchProject.forProject(project); + ILaunchConfiguration config = null; + try{ + ILaunchConfigurationType configType = getConfigurationType(); + ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, project.getName()); + wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, sketch.getMainType()); + wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName()); + wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_WIDTH, sketch.getWidth()); + wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_HEIGHT, sketch.getHeight()); + wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_NAME, "Processing Sketch"); + wc.setMappedResources(new IResource[] { sketch.getJavaProject().getUnderlyingResource() }); +// config =wc.doSave(); + config = wc; // this prevents a run config from being saved and sticking around. + } catch (CoreException ce) { + ProcessingLog.logError(ce); + } + return config; + } + + protected ILaunchConfigurationType getConfigurationType(){ + ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); + return lm.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLET); + } + + public void launch(ISelection selection, String mode) { + if (selection instanceof IStructuredSelection) { + Object element = ((IStructuredSelection)selection).getFirstElement(); + + if (element instanceof IResource){ + IProject proj = ((IResource)element).getProject(); + try{ + if (proj.hasNature("processing.plugin.core.sketchNature")){ + launch(createConfiguration(proj), mode); + } else { + ProcessingLog.logInfo("Sketch could not be launched. The selected project does not have the required Sketch nature."); + } + } catch (CoreException e){ + ProcessingLog.logError("Launch aborted.", e); + } + } else { + ProcessingLog.logInfo("Sketch could not be launched. Launcher was provided with a non-resource selection."); + } + } + } + + // have to implement. log a warning. + // there isn't a great way to launch this without a model + public void launch(IEditorPart editor, String mode) { + IFile file = ResourceUtil.getFile(editor.getEditorInput()); + if(file != null){ + IProject proj = file.getProject(); + try{ + if (proj.hasNature("processing.plugin.core.sketchNature")){ + launch(createConfiguration(proj), mode); + } else { + ProcessingLog.logInfo("Sketch could not be launched. The editor contains a file that is not part of a project with a Sketch nature."); + } + } catch (CoreException e){ + ProcessingLog.logError("Launch aborted.", e); + } + } else { + ProcessingLog.logInfo("Launch aborted. Editor contents are not part of a Sketch Project in the workspace"); + } + } + + private void launch(ILaunchConfiguration config, String mode) { + if (config != null) + DebugUITools.launch(config, mode); + } + + +}