From c2f54ba973b8ce6564b33107f824a652fe527442 Mon Sep 17 00:00:00 2001 From: Shigeru KANEMOTO Date: Sat, 9 Jun 2012 17:07:39 +0900 Subject: [PATCH 1/2] Portable Arduino Use Arduino on USB flash stick and without affecting anything on your PC. To use this feature, simply make a folder named "portable" in the application root folder where there are "hardware", "examples", "lib" and others. In this mode, file association setting is disabled in the preferences dialog. The sketch book folder is inside the "portable" folder. This may be confusing especially for Mac OSX "Arduino.app" folder. --- app/src/processing/app/Base.java | 60 ++++++++++++++++++- app/src/processing/app/Preferences.java | 19 +++++- app/src/processing/app/RelativePath.java | 74 ++++++++++++++++++++++++ app/src/processing/app/Sketch.java | 2 +- 4 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 app/src/processing/app/RelativePath.java diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 3c8ef92fd9a..0243a47bfba 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -111,6 +111,9 @@ public class Base { List editors = Collections.synchronizedList(new ArrayList()); Editor activeEditor; + static File portableFolder = null; + static final String portableSketchbookFolder = "sketchbook"; + static public void main(String args[]) throws Exception { initPlatform(); @@ -156,6 +159,13 @@ static public void main(String args[]) throws Exception { } */ + initPlatform(); + + // Portable folder + portableFolder = getContentFile("portable"); + if (!portableFolder.exists()) + portableFolder = null; + // // Set the look and feel before opening the window // try { // platform.setLookAndFeel(); @@ -249,8 +259,12 @@ public Base(String[] args) throws Exception { // If a value is at least set, first check to see if the folder exists. // If it doesn't, warn the user that the sketchbook folder is being reset. if (sketchbookPath != null) { - File skechbookFolder = new File(sketchbookPath); - if (!skechbookFolder.exists()) { + File sketchbookFolder; + if (portableFolder != null) + sketchbookFolder = new File(portableFolder, sketchbookPath); + else + sketchbookFolder = new File(sketchbookPath); + if (!sketchbookFolder.exists()) { Base.showWarning(_("Sketchbook folder disappeared"), _("The sketchbook folder no longer exists.\n" + "Arduino will switch to the default sketchbook\n" + @@ -264,7 +278,10 @@ public Base(String[] args) throws Exception { // If no path is set, get the default sketchbook folder for this platform if (sketchbookPath == null) { File defaultFolder = getDefaultSketchbookFolder(); - Preferences.set("sketchbook.path", defaultFolder.getAbsolutePath()); + if (portableFolder != null) + Preferences.set("sketchbook.path", portableSketchbookFolder); + else + Preferences.set("sketchbook.path", defaultFolder.getAbsolutePath()); if (!defaultFolder.exists()) { defaultFolder.mkdirs(); } @@ -422,6 +439,15 @@ protected boolean restoreSketches() { int opened = 0; for (int i = 0; i < count; i++) { String path = Preferences.get("last.sketch" + i + ".path"); + if (portableFolder != null) { + File absolute = new File(portableFolder, path); + try { + path = absolute.getCanonicalPath(); + } + catch (IOException e) { + // path unchanged. + } + } int[] location; if (windowPositionValid) { String locationStr = Preferences.get("last.sketch" + i + ".location"); @@ -460,6 +486,11 @@ protected void storeSketches() { !editor.getSketch().isModified()) { continue; } + if (portableFolder != null) { + path = RelativePath.relativePath(portableFolder.toString(), path); + if (path == null) + continue; + } Preferences.set("last.sketch" + index + ".path", path); int[] location = editor.getPlacement(); @@ -478,6 +509,11 @@ protected void storeSketchPath(Editor editor, int index) { String untitledPath = untitledFolder.getAbsolutePath(); if (path.startsWith(untitledPath)) { path = ""; + } else + if (portableFolder != null) { + path = RelativePath.relativePath(portableFolder.toString(), path); + if (path == null) + path = ""; } Preferences.set("last.sketch" + index + ".path", path); } @@ -1759,6 +1795,9 @@ static public boolean isLinux() { static public File getSettingsFolder() { + if (portableFolder != null) + return portableFolder; + File settingsFolder = null; String preferencesPath = Preferences.get("settings.path"); @@ -1938,7 +1977,19 @@ static public Map getBoardPreferences() { return boardPreferences; } + static public File getPortableFolder() { + return portableFolder; + } + + + static public String getPortableSketchbookFolder() { + return portableSketchbookFolder; + } + + static public File getSketchbookFolder() { + if (portableFolder != null) + return new File(portableFolder, Preferences.get("sketchbook.path")); return new File(Preferences.get("sketchbook.path")); } @@ -1971,6 +2022,9 @@ static public File getSketchbookHardwareFolder() { protected File getDefaultSketchbookFolder() { + if (portableFolder != null) + return new File(portableFolder, portableSketchbookFolder); + File sketchbookFolder = null; try { sketchbookFolder = platform.getDefaultSketchbookFolder(); diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index be7c64dc0af..0661c08f9af 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -326,7 +326,14 @@ public void actionPerformed(ActionEvent e) { File file = Base.selectFolder(_("Select new sketchbook location"), dflt, dialog); if (file != null) { - sketchbookLocationField.setText(file.getAbsolutePath()); + String path = file.getAbsolutePath(); + if (Base.getPortableFolder() != null) { + path = RelativePath.relativePath(Base.getPortableFolder().toString(), path); + if (path == null) { + path = Base.getPortableSketchbookFolder(); + } + } + sketchbookLocationField.setText(path); } } }); @@ -439,6 +446,10 @@ public void actionPerformed(ActionEvent e) { autoAssociateBox.setBounds(left, top, d.width + 10, d.height); right = Math.max(right, left + d.width); top += d.height + GUI_BETWEEN; + + // If using portable mode, it's bad manner to change PC setting. + if (Base.getPortableFolder() != null) + autoAssociateBox.setEnabled(false); } // More preferences are in the ... @@ -591,6 +602,12 @@ protected void applyFrame() { // if the sketchbook path has changed, rebuild the menus String oldPath = get("sketchbook.path"); String newPath = sketchbookLocationField.getText(); + if (newPath.isEmpty()) { + if (Base.getPortableFolder() == null) + newPath = editor.base.getDefaultSketchbookFolder().toString(); + else + newPath = Base.getPortableSketchbookFolder(); + } if (!newPath.equals(oldPath)) { editor.base.rebuildSketchbookMenus(); set("sketchbook.path", newPath); diff --git a/app/src/processing/app/RelativePath.java b/app/src/processing/app/RelativePath.java new file mode 100644 index 00000000000..7daeb990e15 --- /dev/null +++ b/app/src/processing/app/RelativePath.java @@ -0,0 +1,74 @@ +/* + * by Shigeru KANEMOTO at SWITCHSCIENCE. + */ + +package processing.app; + +import java.io.File; +import java.io.IOException; + +class RelativePath { + // + // Compute relative path to "target" from a directory "origin". + // + // If "origin" is not absolute, it is relative from the current directory. + // If "target" is not absolute, it is relative from "origin". + // + public static String relativePath(String origin, String target) { + try { + origin = (new File(origin)).getCanonicalPath(); + File targetFile = new File(target); + if (targetFile.isAbsolute()) + target = targetFile.getCanonicalPath(); + else + target = (new File(origin, target)).getCanonicalPath(); + } + catch (IOException e) { + return null; + } + + if (origin.equals(target)) { + // origin and target is identical. + return "."; + } + + if (origin.equals(File.separator)) { + // origin is root. + return "." + target; + } + + String prefix = ""; + String root = File.separator; + + if (System.getProperty("os.name").indexOf("Windows") != -1) { + if (origin.startsWith("\\\\") || target.startsWith("\\\\")) { + // Windows UNC path not supported. + return null; + } + + char originLetter = origin.charAt(0); + char targetLetter = target.charAt(0); + if (Character.isLetter(originLetter) && Character.isLetter(targetLetter)) { + // Windows only + if (originLetter != targetLetter) { + // Drive letters differ + return null; + } + } + + prefix = "" + originLetter + ':'; + root = prefix + File.separator; + } + + String relative = ""; + while (!target.startsWith(origin + File.separator)) { + origin = (new File(origin)).getParent(); + if (origin.equals(root)) + origin = prefix; + relative += ".."; + relative += File.separator; + } + + return relative + target.substring(origin.length() + 1); + } +} diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 64c6bc048f1..b8500854cf9 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -826,7 +826,7 @@ protected boolean saveAs() throws IOException { FileDialog.SAVE); if (isReadOnly() || isUntitled()) { // default to the sketchbook folder - fd.setDirectory(Preferences.get("sketchbook.path")); + fd.setDirectory(Base.getSketchbookFolder().getAbsolutePath()); } else { // default to the parent folder of where this was fd.setDirectory(folder.getParent()); From 0fede503c485ae730191df3032fc917da6a82531 Mon Sep 17 00:00:00 2001 From: Shigeru KANEMOTO Date: Wed, 16 Jan 2013 20:25:57 +0900 Subject: [PATCH 2/2] fixed a bug introduced by my rebase after 24bef6b. --- app/src/processing/app/Base.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 0243a47bfba..eb647c7075c 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -118,6 +118,11 @@ public class Base { static public void main(String args[]) throws Exception { initPlatform(); + // Portable folder + portableFolder = getContentFile("portable"); + if (!portableFolder.exists()) + portableFolder = null; + // run static initialization that grabs all the prefs Preferences.init(null); @@ -159,13 +164,6 @@ static public void main(String args[]) throws Exception { } */ - initPlatform(); - - // Portable folder - portableFolder = getContentFile("portable"); - if (!portableFolder.exists()) - portableFolder = null; - // // Set the look and feel before opening the window // try { // platform.setLookAndFeel();