From d1c47c1215c026c1fc3552217ac37b63f6928465 Mon Sep 17 00:00:00 2001 From: benfry Date: Mon, 13 Oct 2008 00:10:43 +0000 Subject: [PATCH] add registry keys for .pde files --- app/src/processing/app/Base.java | 70 +++++----- app/src/processing/app/windows/Platform.java | 79 ++++++++++++ app/src/processing/app/windows/Registry.java | 127 ++++++++++--------- 3 files changed, 178 insertions(+), 98 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 17ac17109..1c55ec919 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -45,8 +45,8 @@ public class Base { static final int VERSION = 149; static final String VERSION_NAME = "0149 Beta"; - static final int[] platforms = new int[] { - PConstants.WINDOWS, PConstants.MACOSX, PConstants.LINUX + static final int[] platforms = new int[] { + PConstants.WINDOWS, PConstants.MACOSX, PConstants.LINUX }; static HashMap platformNames = new HashMap(); @@ -65,7 +65,7 @@ public class Base { static Platform platform; static private boolean commandLine; - + // A single instance of the preferences window Preferences preferencesFrame; @@ -135,7 +135,7 @@ public class Base { // Use native popups so they don't look so crappy on osx JPopupMenu.setDefaultLightWeightPopupEnabled(false); - // Don't put anything above this line that might make GUI, + // Don't put anything above this line that might make GUI, // because the platform has to be inited properly first. // Make sure a full JDK is installed @@ -146,26 +146,26 @@ public class Base { Preferences.init(null); // } catch (Exception e) { // e.printStackTrace(); -// } +// } // Create a location for untitled sketches untitledFolder = createTempFolder("untitled"); untitledFolder.deleteOnExit(); - + new Base(args); } - - + + static protected void setCommandLine() { commandLine = true; } - - + + static protected boolean isCommandLine() { return commandLine; } - - + + static protected void initPlatform() { try { Class platformClass = Class.forName("processing.app.Platform"); @@ -181,8 +181,8 @@ public class Base { "platform-specific code for your machine.", e); } } - - + + static protected void initRequirements() { try { Class.forName("com.sun.jdi.VirtualMachine"); @@ -194,8 +194,8 @@ public class Base { "More information can be found in the reference.", cnfe); } } - - + + public Base(String[] args) { platform.init(this); @@ -801,7 +801,7 @@ public class Base { // reset the table mapping imports to libraries importToLibraryTable = new HashMap(); - + // Add libraries found in the sketchbook folder try { File sketchbookLibraries = new File(getSketchbookFolder(), "libraries"); @@ -1046,24 +1046,24 @@ public class Base { static public int[] getPlatforms() { return platforms; } - - + + /** * Map a platform constant to its name. - * @param which PConstants.WINDOWS, PConstants.MACOSX, PConstants.LINUX + * @param which PConstants.WINDOWS, PConstants.MACOSX, PConstants.LINUX * @return one of "windows", "macosx", or "linux" */ static public String getPlatformName(int which) { return platformNames.get(which); } - - + + static public int getPlatformIndex(String what) { Integer entry = platformIndices.get(what); return (entry == null) ? -1 : entry.intValue(); } - - + + /** * returns true if Processing is running on a Mac OS X machine. */ @@ -1438,10 +1438,10 @@ public class Base { */ static public void showMessage(String title, String message) { if (title == null) title = "Message"; - + if (commandLine) { System.out.println(title + ": " + message); - + } else { JOptionPane.showMessageDialog(new Frame(), message, title, JOptionPane.INFORMATION_MESSAGE); @@ -1457,7 +1457,7 @@ public class Base { if (commandLine) { System.out.println(title + ": " + message); - + } else { JOptionPane.showMessageDialog(new Frame(), message, title, JOptionPane.WARNING_MESSAGE); @@ -1473,10 +1473,10 @@ public class Base { */ static public void showError(String title, String message, Throwable e) { if (title == null) title = "Error"; - + if (commandLine) { System.err.println(title + ": " + message); - + } else { JOptionPane.showMessageDialog(new Frame(), message, title, JOptionPane.ERROR_MESSAGE); @@ -1525,17 +1525,17 @@ public class Base { return null; } */ - + static public File getContentFile(String name) { String path = System.getProperty("user.dir"); - + // Get a path to somewhere inside the .app folder if (PApplet.platform == PConstants.MACOSX) { // javaroot // $JAVAROOT String javaroot = System.getProperty("javaroot"); if (javaroot != null) { - path = javaroot; + path = javaroot; } } File working = new File(path); @@ -1573,9 +1573,9 @@ public class Base { // ................................................................... - + /** - * Get the number of lines in a file by counting the number of newline + * Get the number of lines in a file by counting the number of newline * characters inside a String (and adding 1). */ static public int countLines(String what) { @@ -1585,7 +1585,7 @@ public class Base { } return count; } - + /** * Same as PApplet.loadBytes(), however never does gzip decoding. diff --git a/app/src/processing/app/windows/Platform.java b/app/src/processing/app/windows/Platform.java index a52278030..52a49868f 100644 --- a/app/src/processing/app/windows/Platform.java +++ b/app/src/processing/app/windows/Platform.java @@ -23,7 +23,9 @@ package processing.app.windows; import java.io.*; +import javax.swing.*; +import processing.app.Base; import processing.app.windows.Registry.REGISTRY_ROOT_KEY; @@ -35,6 +37,83 @@ import processing.app.windows.Registry.REGISTRY_ROOT_KEY; public class Platform extends processing.app.Platform { + static final String openCommand = + System.getProperty("user.dir").replace('/', '\\') + + "\\processing.exe \"%1\""; + static final String doc = "Processing.Document"; + + public void init(Base base) { + super.init(base); + + try { + String knownCommand = + Registry.getStringValue(REGISTRY_ROOT_KEY.CLASSES_ROOT, + doc + "\\shell\\open\\command", ""); + //System.out.println("known is " + knownCommand); + if (knownCommand == null) { + String prompt = + "Processing is not set to handle .pde files.\n" + + "Would you like to make it the default?"; + int result = + JOptionPane.showConfirmDialog(this, prompt, "Reassign .pde files", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (result == JOptionPane.YES_OPTION) { + setAssociations(); + } + + } else if (!knownCommand.equals(openCommand)) { + // If the value is set differently, just change the registry setting. + + String prompt = + "This version of Processing is not the default application\n" + + "to open .pde files. Would you like to make it the default?"; + int result = + JOptionPane.showConfirmDialog(this, prompt, "Reassign .pde files", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (result == JOptionPane.YES_OPTION) { + setAssociations(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + + /** + * Associate .pde files with this version of Processing. + */ + protected void setAssociations() throws UnsupportedEncodingException { + if (Registry.createKey(REGISTRY_ROOT_KEY.CLASSES_ROOT, + "", ".pde") && + Registry.setStringValue(REGISTRY_ROOT_KEY.CLASSES_ROOT, + ".pde", "", doc) && + + Registry.createKey(REGISTRY_ROOT_KEY.CLASSES_ROOT, "", doc) && + Registry.setStringValue(REGISTRY_ROOT_KEY.CLASSES_ROOT, doc, "", + "Processing Source Code") && + + Registry.createKey(REGISTRY_ROOT_KEY.CLASSES_ROOT, + doc, "shell") && + Registry.createKey(REGISTRY_ROOT_KEY.CLASSES_ROOT, + doc + "\\shell", "open") && + Registry.createKey(REGISTRY_ROOT_KEY.CLASSES_ROOT, + doc + "\\shell\\open", "command") && + Registry.setStringValue(REGISTRY_ROOT_KEY.CLASSES_ROOT, + doc + "\\shell\\open\\command", "", + openCommand)) { + // everything ok + + } else { + // not ok + } + } + + // looking for Documents and Settings/blah/Application Data/Processing public File getSettingsFolder() throws Exception { // HKEY_CURRENT_USER\Software\Microsoft diff --git a/app/src/processing/app/windows/Registry.java b/app/src/processing/app/windows/Registry.java index 177ebefc8..71fa5eebe 100644 --- a/app/src/processing/app/windows/Registry.java +++ b/app/src/processing/app/windows/Registry.java @@ -13,14 +13,14 @@ import com.sun.jna.ptr.IntByReference; public class Registry { public static enum REGISTRY_ROOT_KEY{CLASSES_ROOT, CURRENT_USER, LOCAL_MACHINE, USERS}; private final static HashMap rootKeyMap = new HashMap(); - + static { rootKeyMap.put(REGISTRY_ROOT_KEY.CLASSES_ROOT, WINREG.HKEY_CLASSES_ROOT); rootKeyMap.put(REGISTRY_ROOT_KEY.CURRENT_USER, WINREG.HKEY_CURRENT_USER); rootKeyMap.put(REGISTRY_ROOT_KEY.LOCAL_MACHINE, WINREG.HKEY_LOCAL_MACHINE); rootKeyMap.put(REGISTRY_ROOT_KEY.USERS, WINREG.HKEY_USERS); } - + /** * Testing. * @@ -40,16 +40,16 @@ public class Registry { Advapi32 advapi32; IntByReference pHandle; int handle = 0; - + advapi32 = Advapi32.INSTANCE; pHandle = new IntByReference(); - + if(advapi32.RegOpenKeyEx(rootKeyMap.get(key), null, 0, 0, pHandle) == WINERROR.ERROR_SUCCESS) { handle = pHandle.getValue(); } return(handle); } - + /** * Opens a key. * @@ -62,19 +62,19 @@ public class Registry { Advapi32 advapi32; IntByReference pHandle; int rootKeyHandle; - + advapi32 = Advapi32.INSTANCE; rootKeyHandle = getRegistryRootKey(rootKey); pHandle = new IntByReference(); - + if(advapi32.RegOpenKeyEx(rootKeyHandle, subKeyName, 0, access, pHandle) == WINERROR.ERROR_SUCCESS) { return(pHandle.getValue()); - + } else { return(0); } } - + /** * Converts a Windows buffer to a Java String. * @@ -85,7 +85,7 @@ public class Registry { private static String convertBufferToString(byte[] buf) throws UnsupportedEncodingException { return(new String(buf, 0, buf.length - 2, "UTF-16LE")); } - + /** * Converts a Windows buffer to an int. * @@ -93,9 +93,9 @@ public class Registry { * @return int */ private static int convertBufferToInt(byte[] buf) { - return(((int)(buf[0] & 0xff)) + (((int)(buf[1] & 0xff)) << 8) + (((int)(buf[2] & 0xff)) << 16) + (((int)(buf[3] & 0xff)) << 24)); + return(((int)(buf[0] & 0xff)) + (((int)(buf[1] & 0xff)) << 8) + (((int)(buf[2] & 0xff)) << 16) + (((int)(buf[3] & 0xff)) << 24)); } - + /** * Read a String value. * @@ -111,14 +111,14 @@ public class Registry { byte[] lpData = new byte[1]; int handle = 0; String ret = null; - + advapi32 = Advapi32.INSTANCE; pType = new IntByReference(); lpcbData = new IntByReference(); handle = openKey(rootKey, subKeyName, WINNT.KEY_READ); - + if(handle != 0) { - + if(advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_MORE_DATA) { lpData = new byte[lpcbData.getValue()]; @@ -133,8 +133,8 @@ public class Registry { /** * Read an int value. - * - * + * + * * @return int or 0 * @param rootKey root key * @param subKeyName key name @@ -146,14 +146,14 @@ public class Registry { byte[] lpData = new byte[1]; int handle = 0; int ret = 0; - + advapi32 = Advapi32.INSTANCE; pType = new IntByReference(); lpcbData = new IntByReference(); handle = openKey(rootKey, subKeyName, WINNT.KEY_READ); - + if(handle != 0) { - + if(advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_MORE_DATA) { lpData = new byte[lpcbData.getValue()]; @@ -165,7 +165,7 @@ public class Registry { } return(ret); } - + /** * Delete a value. * @@ -178,11 +178,11 @@ public class Registry { Advapi32 advapi32; int handle; boolean ret = true; - + advapi32 = Advapi32.INSTANCE; - + handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE); - + if(handle != 0) { if(advapi32.RegDeleteValue(handle, name) == WINERROR.ERROR_SUCCESS) { ret = true; @@ -191,7 +191,7 @@ public class Registry { } return(ret); } - + /** * Writes a String value. * @@ -207,15 +207,16 @@ public class Registry { int handle; byte[] data; boolean ret = false; - + // appears to be Java 1.6 syntax, removing [fry] //data = Arrays.copyOf(value.getBytes("UTF-16LE"), value.length() * 2 + 2); data = new byte[value.length() * 2 + 2]; - System.arraycopy(value.getBytes("UTF-16LE"), 0, data, 0, data.length); - + byte[] src = value.getBytes("UTF-16LE"); + System.arraycopy(src, 0, data, 0, src.length); + advapi32 = Advapi32.INSTANCE; handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE); - + if(handle != 0) { if(advapi32.RegSetValueEx(handle, name, 0, WINNT.REG_SZ, data, data.length) == WINERROR.ERROR_SUCCESS) { ret = true; @@ -224,11 +225,11 @@ public class Registry { } return(ret); } - + /** * Writes an int value. - * - * + * + * * @return true on success * @param rootKey root key * @param subKeyName key name @@ -240,7 +241,7 @@ public class Registry { int handle; byte[] data; boolean ret = false; - + data = new byte[4]; data[0] = (byte)(value & 0xff); data[1] = (byte)((value >> 8) & 0xff); @@ -248,9 +249,9 @@ public class Registry { data[3] = (byte)((value >> 24) & 0xff); advapi32 = Advapi32.INSTANCE; handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE); - + if(handle != 0) { - + if(advapi32.RegSetValueEx(handle, name, 0, WINNT.REG_DWORD, data, data.length) == WINERROR.ERROR_SUCCESS) { ret = true; } @@ -258,7 +259,7 @@ public class Registry { } return(ret); } - + /** * Check for existence of a value. * @@ -273,17 +274,17 @@ public class Registry { byte[] lpData = new byte[1]; int handle = 0; boolean ret = false; - + advapi32 = Advapi32.INSTANCE; pType = new IntByReference(); lpcbData = new IntByReference(); handle = openKey(rootKey, subKeyName, WINNT.KEY_READ); - + if(handle != 0) { - + if(advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) != WINERROR.ERROR_FILE_NOT_FOUND) { ret = true; - + } else { ret = false; } @@ -291,7 +292,7 @@ public class Registry { } return(ret); } - + /** * Create a new key. * @@ -305,19 +306,19 @@ public class Registry { IntByReference hkResult, dwDisposition; int handle = 0; boolean ret = false; - + advapi32 = Advapi32.INSTANCE; hkResult = new IntByReference(); dwDisposition = new IntByReference(); handle = openKey(rootKey, parent, WINNT.KEY_READ); - + if(handle != 0) { - + if(advapi32.RegCreateKeyEx(handle, name, 0, null, WINNT.REG_OPTION_NON_VOLATILE, WINNT.KEY_READ, null, hkResult, dwDisposition) == WINERROR.ERROR_SUCCESS) { ret = true; advapi32.RegCloseKey(hkResult.getValue()); - + } else { ret = false; } @@ -325,7 +326,7 @@ public class Registry { } return(ret); } - + /** * Delete a key. * @@ -338,15 +339,15 @@ public class Registry { Advapi32 advapi32; int handle = 0; boolean ret = false; - + advapi32 = Advapi32.INSTANCE; handle = openKey(rootKey, parent, WINNT.KEY_READ); - + if(handle != 0) { - + if(advapi32.RegDeleteKey(handle, name) == WINERROR.ERROR_SUCCESS) { ret = true; - + } else { ret = false; } @@ -354,7 +355,7 @@ public class Registry { } return(ret); } - + /** * Get all sub keys of a key. * @@ -369,16 +370,16 @@ public class Registry { IntByReference lpcName; WINBASE.FILETIME lpftLastWriteTime; TreeSet subKeys = new TreeSet(); - + advapi32 = Advapi32.INSTANCE; handle = openKey(rootKey, parent, WINNT.KEY_READ); lpName = new char[256]; lpcName = new IntByReference(256); lpftLastWriteTime = new WINBASE.FILETIME(); - + if(handle != 0) { dwIndex = 0; - + while(advapi32.RegEnumKeyEx(handle, dwIndex, lpName, lpcName, null, null, null, lpftLastWriteTime) == WINERROR.ERROR_SUCCESS) { subKeys.add(new String(lpName, 0, lpcName.getValue())); @@ -387,10 +388,10 @@ public class Registry { } advapi32.RegCloseKey(handle); } - + return(subKeys.toArray(new String[]{})); } - + /** * Get all values under a key. * @@ -407,7 +408,7 @@ public class Registry { IntByReference lpcchValueName, lpType, lpcbData; String name; TreeMap values = new TreeMap(String.CASE_INSENSITIVE_ORDER); - + advapi32 = Advapi32.INSTANCE; handle = openKey(rootKey, key, WINNT.KEY_READ); lpValueName = new char[16384]; @@ -415,24 +416,24 @@ public class Registry { lpType = new IntByReference(); lpData = new byte[1]; lpcbData = new IntByReference(); - + if(handle != 0) { dwIndex = 0; - + do { lpcbData.setValue(0); result = advapi32.RegEnumValue(handle, dwIndex, lpValueName, lpcchValueName, null, lpType, lpData, lpcbData); - + if(result == WINERROR.ERROR_MORE_DATA) { lpData = new byte[lpcbData.getValue()]; lpcchValueName = new IntByReference(16384); result = advapi32.RegEnumValue(handle, dwIndex, lpValueName, lpcchValueName, null, lpType, lpData, lpcbData); - + if(result == WINERROR.ERROR_SUCCESS) { name = new String(lpValueName, 0, lpcchValueName.getValue()); - + switch(lpType.getValue()) { case WINNT.REG_SZ: values.put(name, convertBufferToString(lpData)); @@ -447,7 +448,7 @@ public class Registry { } dwIndex++; } while(result == WINERROR.ERROR_SUCCESS); - + advapi32.RegCloseKey(handle); } return(values);