Index: core/src/org/netbeans/core/ShortcutsFolder.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/ShortcutsFolder.java,v retrieving revision 1.20 diff -u -u -r1.20 ShortcutsFolder.java --- core/src/org/netbeans/core/ShortcutsFolder.java 8 Sep 2004 17:09:03 -0000 1.20 +++ core/src/org/netbeans/core/ShortcutsFolder.java 2 Oct 2004 15:53:45 -0000 @@ -56,7 +56,7 @@ private static final String KEYS_EXT = "keys"; // NOI18N /** Folder name under the system folder.*/ - static final String SHORTCUTS_FOLDER = "Shortcuts"; // NOI18N + private static final String SHORTCUTS_FOLDER = "Shortcuts"; // NOI18N /** Info for old XML file.*/ private static final String XML_BINDING = "Binding"; // NOI18N @@ -421,6 +421,7 @@ public static void applyChanges(java.util.List changes) { FileObject fo = Repository.getDefault().getDefaultFileSystem() .getRoot().getFileObject(SHORTCUTS_FOLDER); + DataFolder f = DataFolder.findFolder(fo); Iterator it = changes.listIterator(); while (it.hasNext()) { @@ -470,6 +471,7 @@ foAdd.setAttribute("originalFile", originalFilePath); // NOI18N } else { FileObject foRemove = root.getFileObject(r.instanceName(), "shadow"); // NOI18N + if(foRemove != null) { foRemove.delete(); } @@ -484,6 +486,7 @@ foRemove.delete(); break; } + } } } @@ -518,10 +521,18 @@ //ANY CHANGES MADE HERE SHOULD ALSO BE MADE THERE! String key = KeyEvent.META_MASK == Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() ? "M" : "C"; //NOI18N - + + String ctrlWildcard = "D"; //NOI18N + + String altKey = Utilities.getOperatingSystem() == Utilities.OS_MAC ? + "C" : "A"; //NOI18N + + String altWildcard = "O"; //NOI18N + + int pos = name.lastIndexOf ("-"); //NOI18N String keyPart = name.substring (pos); - String modsPart = Utilities.replaceString (name.substring (0, pos), "-", ""); + String modsPart = Utilities.replaceString (name.substring (0, pos), "-", ""); //NOI18N if (modsPart.length() > 1) { Collection perms = new HashSet(modsPart.length() * modsPart.length()); int idx = name.indexOf(key); @@ -529,26 +540,77 @@ //First, try with the wildcard key. Remove all hyphens - we'll //put them back later StringBuffer sb = new StringBuffer(modsPart); - sb.replace(idx, idx+1, "D"); + sb.replace(idx, idx+1, ctrlWildcard); perms.add (sb.toString() + keyPart); getAllPossibleOrderings (sb.toString(), keyPart, perms); createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + idx = name.indexOf (altKey); + if (idx != -1) { + sb.replace (idx, idx+1, altWildcard); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } else { + idx = name.indexOf(altWildcard); + if (idx != -1) { + sb.replace (idx, idx+1, altKey); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } + } } else { - idx = name.indexOf ("D"); //NOI18N + idx = name.indexOf (ctrlWildcard); //NOI18N if (idx != -1) { StringBuffer sb = new StringBuffer(modsPart); sb.replace(idx, idx+1, key); perms.add (sb.toString() + keyPart); getAllPossibleOrderings (sb.toString(), keyPart, perms); createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + idx = name.indexOf (altKey); + if (idx != -1) { + sb.replace (idx, idx+1, altWildcard); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + } else { + idx = name.indexOf(altWildcard); + if (idx != -1) { + sb.replace (idx, idx+1, altKey); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } + } } } + + idx = name.indexOf (altKey); + if (idx != -1) { + StringBuffer sb = new StringBuffer(modsPart); + sb.replace (idx, idx+1, altWildcard); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } else { + StringBuffer sb = new StringBuffer(modsPart); + idx = name.indexOf(altWildcard); + if (idx != -1) { + sb.replace (idx, idx+1, altKey); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } + } + getAllPossibleOrderings (modsPart, keyPart, perms); createHyphenatedPermutation(modsPart.toCharArray(), perms, keyPart); return (String[]) perms.toArray(new String[perms.size()]); } else { return key.equals (modsPart) ? - new String[] {"D" + keyPart} : new String[0]; + new String[] {ctrlWildcard + keyPart} : altKey.equals(modsPart) ? + new String[]{altWildcard + keyPart} : altWildcard.equals(modsPart) ? + new String[] {altKey + keyPart} : + new String[0]; } } Index: core/src/org/netbeans/core/ShortcutsPanel.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/ShortcutsPanel.java,v retrieving revision 1.23 diff -u -u -r1.23 ShortcutsPanel.java --- core/src/org/netbeans/core/ShortcutsPanel.java 1 Oct 2004 15:55:48 -0000 1.23 +++ core/src/org/netbeans/core/ShortcutsPanel.java 2 Oct 2004 15:53:46 -0000 @@ -60,12 +60,6 @@ shortcutsList.setSelectedIndices(new int[0]); updateButtons (); } - - public void addNotify() { - super.addNotify(); - //Turn off remapping so keys will be read sanely - System.setProperty ("nb.mac.swap.ctrl.and.alt", "false"); - } /** This method is called from within the constructor to * initialize the form. Index: core/test/unit/src/org/netbeans/core/ShortcutsFolderTest.java =================================================================== RCS file: /cvs/core/test/unit/src/org/netbeans/core/ShortcutsFolderTest.java,v retrieving revision 1.3 diff -u -u -r1.3 ShortcutsFolderTest.java --- core/test/unit/src/org/netbeans/core/ShortcutsFolderTest.java 29 Sep 2004 09:44:17 -0000 1.3 +++ core/test/unit/src/org/netbeans/core/ShortcutsFolderTest.java 2 Oct 2004 15:53:56 -0000 @@ -18,6 +18,8 @@ import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -30,10 +32,12 @@ import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.KeyStroke; +import javax.swing.text.Keymap; import junit.framework.*; import org.netbeans.junit.*; import org.openide.ErrorManager; import org.openide.cookies.InstanceCookie; +import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileSystem; import org.openide.filesystems.LocalFileSystem; @@ -63,15 +67,61 @@ super(s); } + ShortcutsFolder sf = null; + FileSystem fs = null; + FileObject fld = null; + FileObject fo = null; + + static Repository repository = null; + protected void setUp () { + kmap = new NbKeymap(); + fs = createTestingFilesystem(); + fo = getFolderForShortcuts(fs); + sf = createShortcutsFolder(fs); + sf.waitShortcutsFinished(); + } + + protected void tearDown() { + try { + FileLock lock = fo.lock(); + fo.delete(lock); + lock.releaseLock(); + } catch (Exception ioe) { + } + + ShortcutsFolder.shortcutsFolder = null; + sf = null; + fs = null; + fld = null; + fo = null; + try { + if (dir.exists()) { + File[] f = dir.listFiles(); + for (int i=0; i < f.length; i++) { + f[i].delete(); + } + dir.delete(); + } + dir = null; + folderName = null; + repository = null; + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + public void testHyphenation (String s) { + System.out.println("testHyphenation"); HashSet set = new HashSet(); char[] c = new String("ABCD").toCharArray(); ShortcutsFolder.createHyphenatedPermutation (c, set, "-F5"); assertTrue (set.contains("A-B-C-D-F5")); } - + public void testPermutations () { + System.out.println("testPermutations"); HashSet set = new HashSet(); ShortcutsFolder.getAllPossibleOrderings("BANG", "-F5", set); @@ -89,6 +139,7 @@ } public void testPermutationsIncludeHyphenatedVariants() { + System.out.println("testPermutationsIncludeHyphenatedVariants"); HashSet set = new HashSet(); ShortcutsFolder.getAllPossibleOrderings("BANG", "-F5", set); @@ -106,6 +157,7 @@ } public void testPermutationsContainConvertedWildcard () { + System.out.println("testPermutationsContainConvertedWildcard "); String targetChar = (Utilities.getOperatingSystem() & Utilities.OS_MAC) != 0 ? "M" : "C"; @@ -127,6 +179,7 @@ } public void testPermutationsIncludeWildcardIfSpecifiedKeyIsToolkitAccelerator () { + System.out.println("testPermutationsIncludeWildcardIfSpecifiedKeyIsToolkitAccelerator "); String targetChar = (Utilities.getOperatingSystem() & Utilities.OS_MAC) != 0 ? "M" : "C"; @@ -147,14 +200,146 @@ } } + public void testPermutationsContainConvertedAltWildcard () { + System.out.println("testPermutationsContainConvertedWildcard"); + String cmdChar = (Utilities.getOperatingSystem() & Utilities.OS_MAC) != 0 + ? "M" : "C"; + + String altKey = Utilities.getOperatingSystem() == Utilities.OS_MAC ? + "C" : "A"; //NOI18N + + String[] s = ShortcutsFolder.getPermutations("DO-F5"); + HashSet set = new HashSet (Arrays.asList(s)); + set.add ("DO-F5"); //Permutations will not contain the passed value + + String[] permutations = new String[] { + "OD-F5", + "O" + cmdChar + "-F5", + "DO-F5", + "D-O-F5", + "O-D-F5", + altKey + "-D-F5", + altKey + "-" + cmdChar + "-F5", + altKey + "D-F5", + }; + + for (int i=0; i < permutations.length; i++) { + assertTrue ("Permutation of D"+ altKey + "-F5 not generated:" + + permutations[i] + "; (generated:" + set + ")", + set.contains(permutations[i])); + } + } + + public void testDualWildcardPermutations() { + System.out.println("testDualWildcardPermutations"); + String cmdChar = (Utilities.getOperatingSystem() & Utilities.OS_MAC) != 0 + ? "M" : "C"; + + String altKey = Utilities.getOperatingSystem() == Utilities.OS_MAC ? + "C" : "A"; //NOI18N + + String[] s = ShortcutsFolder.getPermutations("OD-F5"); + HashSet set = new HashSet (Arrays.asList(s)); + set.add ("OD-F5"); //Permutations will not contain the passed value + + String[] permutations = new String[] { + "OD-F5", "O" + cmdChar + "-F5", "DO-F5", "D-O-F5", + "O-D-F5", altKey + "-D-F5", altKey + "-" + cmdChar + "-F5", altKey + "D-F5", + altKey + cmdChar + "-F5" + }; + + for (int i=0; i < permutations.length; i++) { + assertTrue ("Permutation of OD-F5 not generated:" + + permutations[i] + "; (generated:" + set + ")", + set.contains(permutations[i])); + } + } + + public void testOPermutationOfAlt () throws Exception { + System.out.println("testOPermutationOfAlt"); +// FileSystem fs = createTestingFilesystem(); +// FileObject fo = getFolderForShortcuts(fs); + +// assertEquals (lastDir, repository.getDefaultFileSystem().getRoot().getPath()); + + FileObject data1 = fo.createData("OD-F6.instance"); + assertNotNull(data1); + data1.setAttribute("instanceClass", "org.netbeans.core.ShortcutsFolderTest$TestAction"); + + FileObject data2 = fo.createData("OS-F6.instance"); + assertNotNull(data2); + data2.setAttribute("instanceClass", "org.netbeans.core.ShortcutsFolderTest$TestAction"); + + File file = new File (lastDir + folderName + File.separator + "OD-F6.instance"); + assertTrue ("Actual file not created: " + file.getPath(), file.exists()); + + sf.refreshGlobalMap(); + + DataObject ob = DataObject.find (data1); + assertNotNull("Data object not found: " + data1.getPath(), ob); + + InstanceCookie ck = (InstanceCookie) ob.getCookie(InstanceCookie.class); + Object obj = ck.instanceCreate(); + + assertTrue ("InstanceCookie was not an instanceof TestAction - " + obj, obj instanceof TestAction); + + int mask = System.getProperty("mrj.version") == null ? KeyEvent.ALT_MASK : + KeyEvent.CTRL_MASK; + + KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_F6, mask | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); + Action action = (Action) obj; + + ShortcutsFolder.applyChanges(Arrays.asList(new Object[] {new ShortcutsFolder.ChangeRequest (stroke, action, false)})); + + ShortcutsFolder.refreshGlobalMap(); + + FileObject now = fo.getFileObject ("OD-F6.instance"); + //XXX WTF?? + assertNull ("File object should be deleted - but is " + (now == null ? " null " : now.getPath()), now); + + assertFalse ("File still exists: " + lastDir + "OD-F6.instance", file.exists()); + + file = new File (lastDir + "Shortcuts" + File.separator + "OS-F6.instance"); + assertTrue ("File should not have been deleted: " + file.getPath(), file.exists()); + + } + + + + private static String lastDir = null; + private static File dir = null; + private File getTempDir() { + String outdir = System.getProperty("java.io.tmpdir"); //NOI18N + if (!outdir.endsWith(File.separator)) { + outdir += File.separator; + } + String dirname = Long.toHexString(System.currentTimeMillis()); + lastDir = outdir + dirname + File.separator; + dir = new File (outdir + dirname); + try { + dir.mkdir(); + } catch (Exception ioe) { + ioe.printStackTrace(); + fail ("Exception creating temporary dir for tests " + dirname + " - " + ioe.getMessage()); + } + dir.deleteOnExit(); + + return dir; + } + private FileSystem createTestingFilesystem () { FileObject root = Repository.getDefault ().getDefaultFileSystem ().getRoot (); try { + LocalFileSystem result = new LocalFileSystem(); + result.setRootDirectory(getTempDir()); + repository = new Repository (result); + fixDefaultRepository(); + System.setProperty ("org.openide.util.Lookup", "org.netbeans.core.ShortcutsFolderTest$LKP"); FileObject[] arr = root.getChildren (); for (int i = 0; i < arr.length; i++) { arr[i].delete (); } - return root.getFileSystem (); + return result; } catch (Exception e) { e.printStackTrace(); fail (e.getMessage()); @@ -162,12 +347,24 @@ return null; } + private void fixDefaultRepository () { + try { + Class c = ClassLoader.getSystemClassLoader().loadClass("org.openide.filesystems.ExternalUtil"); + Method m = c.getDeclaredMethod ("setRepository", new Class[] {Repository.class}); + m.setAccessible(true); + m.invoke (null, new Object[] { repository }); + } catch (Exception e) { + throw new RuntimeException (e); + } + } + private FileObject getFolderForShortcuts(FileSystem fs) { FileObject result = null; try { - result = fs.getRoot().getFileObject("Shortcuts"); + folderName = "Shortcuts"; + result = fs.getRoot().getFileObject(folderName); if (result == null) { - result = fs.getRoot().createFolder("Shortcuts"); + result = fs.getRoot().createFolder(folderName); } } catch (Exception e) { e.printStackTrace(); @@ -176,6 +373,7 @@ return result; } + private String folderName = null; private ShortcutsFolder createShortcutsFolder(FileSystem fs) { try { DataObject dob = DataObject.find(getFolderForShortcuts(fs)); @@ -202,20 +400,17 @@ data2.setAttribute("instanceClass", "org.netbeans.core.ShortcutsFolderTest$TestAction"); ShortcutsFolder sf = createShortcutsFolder(fs); - System.err.println("Created shortcuts folder " + sf); sf.waitShortcutsFinished(); DataObject ob = DataObject.find (data1); assertNotNull("Data object not found: " + data1.getPath(), ob); - System.err.println("Found data object " + data1); InstanceCookie ck = (InstanceCookie) ob.getCookie(InstanceCookie.class); Object obj = ck.instanceCreate(); assertTrue ("InstanceCookie was not an instanceof TestAction - " + obj, obj instanceof TestAction); - System.err.println("Got an instance: " + obj); KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_F5, KeyEvent.ALT_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); Action action = (Action) obj; @@ -223,7 +418,6 @@ ShortcutsFolder.applyChanges(Arrays.asList(new Object[] {new ShortcutsFolder.ChangeRequest (stroke, action, false)})); ShortcutsFolder.refreshGlobalMap(); - FileObject now = fo.getFileObject ("AD-F5.instance"); assertNull ("File object should be deleted - ", now); @@ -234,6 +428,7 @@ public void actionPerformed (ActionEvent ae) {} } + static NbKeymap kmap = null; public static class LKP extends Lookup { private javax.swing.text.Keymap keymap = new NbKeymap (); @@ -241,8 +436,8 @@ if (ErrorManager.class == clazz) { return new EM(); } - if (javax.swing.text.Keymap.class == clazz) { - return keymap; + if (Keymap.class == clazz) { + return kmap; } return null; } @@ -252,6 +447,8 @@ public Collection allInstances() { if (tpl.getType() == ErrorManager.class) { return Arrays.asList(new Object[] { new EM()}); + } else if (tpl.getType() == Keymap.class) { + return Arrays.asList(new Object[] {kmap}); } else { return Collections.EMPTY_LIST; } Index: core/ui/src/org/netbeans/core/ui/resources/layer.xml =================================================================== RCS file: /cvs/core/ui/src/org/netbeans/core/ui/resources/layer.xml,v retrieving revision 1.76 diff -u -u -r1.76 layer.xml --- core/ui/src/org/netbeans/core/ui/resources/layer.xml 1 Oct 2004 15:55:48 -0000 1.76 +++ core/ui/src/org/netbeans/core/ui/resources/layer.xml 2 Oct 2004 15:53:58 -0000 @@ -144,11 +144,9 @@ - - - - - + + + @@ -304,7 +302,7 @@ - + Index: core/windows/src/org/netbeans/core/windows/ShortcutAndMenuKeyEventProcessor.java =================================================================== RCS file: /cvs/core/windows/src/org/netbeans/core/windows/ShortcutAndMenuKeyEventProcessor.java,v retrieving revision 1.8 diff -u -u -r1.8 ShortcutAndMenuKeyEventProcessor.java --- core/windows/src/org/netbeans/core/windows/ShortcutAndMenuKeyEventProcessor.java 1 Oct 2004 15:55:48 -0000 1.8 +++ core/windows/src/org/netbeans/core/windows/ShortcutAndMenuKeyEventProcessor.java 2 Oct 2004 15:54:00 -0000 @@ -87,6 +87,9 @@ private char lastKeyChar; private boolean lastSampled = false; + private static final boolean isMac = Utilities.getOperatingSystem() == + Utilities.OS_MAC; + public boolean postProcessKeyEvent(KeyEvent ev) { if (ev.isConsumed()) return false; @@ -107,6 +110,7 @@ if (mb == null) return false; boolean pressed = (ev.getID() == KeyEvent.KEY_PRESSED); + boolean res = invokeProcessKeyBindingsForAllComponents(ev, mw, pressed); if (res) @@ -114,7 +118,6 @@ return res; } - private static boolean wasMacSwap = false; public boolean dispatchKeyEvent(KeyEvent ev) { // XXX(-ttran) Sun JDK 1.4 on Linux: pressing Alt key produces // KeyEvent.VK_ALT, but Alt+ produces Meta+ @@ -124,40 +127,6 @@ mods = (mods & ~ InputEvent.META_MASK) | InputEvent.ALT_MASK; ev.setModifiers(mods); } - } - - if (Utilities.getOperatingSystem() == Utilities.OS_MAC) { - boolean macSwap = Boolean.getBoolean ( - "nb.mac.swap.ctrl.and.alt"); //NOI18N - if (macSwap) { - //Allows international keyboards to use the Alt key as the Compose - //key - int mods = ev.getModifiers(); - System.setProperty ("lastKeyModifiers", Integer.toString(mods)); //NOI18N - boolean isCtrl = (mods & InputEvent.CTRL_MASK) != 0; - boolean isAlt = (mods & InputEvent.ALT_MASK) != 0; - int code = ev.getKeyCode(); - boolean skip = code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN || - code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_LEFT || - code == KeyEvent.VK_ENTER || code == KeyEvent.VK_SPACE; - if (isCtrl != isAlt && !skip) { - if (isAlt) { - mods ^= InputEvent.ALT_MASK; - mods |= InputEvent.CTRL_MASK; - } - if (isCtrl) { - mods ^= InputEvent.CTRL_MASK; - mods |= InputEvent.ALT_MASK; - } - ev.setModifiers (mods); - } - } - if (wasMacSwap != macSwap) { - if (!macSwap) { - System.getProperties().remove ("lastKeyModifiers"); //NOI18N - } - } - wasMacSwap = macSwap; } if (ev.getID() == KeyEvent.KEY_PRESSED Index: debuggercore/src/org/netbeans/modules/debugger/resources/mf-layer.xml =================================================================== RCS file: /cvs/debuggercore/src/org/netbeans/modules/debugger/resources/mf-layer.xml,v retrieving revision 1.68 diff -u -u -r1.68 mf-layer.xml --- debuggercore/src/org/netbeans/modules/debugger/resources/mf-layer.xml 27 Jul 2004 06:29:14 -0000 1.68 +++ debuggercore/src/org/netbeans/modules/debugger/resources/mf-layer.xml 2 Oct 2004 15:54:06 -0000 @@ -69,22 +69,22 @@ - + - + - + - + - + - + Index: debuggerjpda/ui/src/org/netbeans/modules/debugger/jpda/resources/mf-layer.xml =================================================================== RCS file: /cvs/debuggerjpda/ui/src/org/netbeans/modules/debugger/jpda/resources/mf-layer.xml,v retrieving revision 1.23 diff -u -u -r1.23 mf-layer.xml --- debuggerjpda/ui/src/org/netbeans/modules/debugger/jpda/resources/mf-layer.xml 8 Sep 2004 17:09:05 -0000 1.23 +++ debuggerjpda/ui/src/org/netbeans/modules/debugger/jpda/resources/mf-layer.xml 2 Oct 2004 15:54:14 -0000 @@ -199,7 +199,7 @@ - + @@ -220,10 +220,10 @@ - + - + Index: editor/libsrc/org/netbeans/editor/BaseKit.java =================================================================== RCS file: /cvs/editor/libsrc/org/netbeans/editor/BaseKit.java,v retrieving revision 1.119 diff -u -u -r1.119 BaseKit.java --- editor/libsrc/org/netbeans/editor/BaseKit.java 1 Oct 2004 15:55:49 -0000 1.119 +++ editor/libsrc/org/netbeans/editor/BaseKit.java 2 Oct 2004 15:54:17 -0000 @@ -780,39 +780,10 @@ int mod = evt.getModifiers(); boolean ctrl = ((mod & ActionEvent.CTRL_MASK) != 0); // On the mac, norwegian and french keyboards use Alt to do bracket characters. - boolean alt = ((mod & ActionEvent.ALT_MASK) != 0); + // This replicates Apple's modification DefaultEditorKit.DefaultKeyTypedAction + boolean alt = isMac ? ((mod & ActionEvent.META_MASK) != 0) : + ((mod & ActionEvent.ALT_MASK) != 0); - if (isMac) { - boolean macSwap = Boolean.getBoolean ( - "nb.mac.swap.ctrl.and.alt"); //NOI18N - - if (alt && !macSwap) { - //Ugly, but without IDE-wide global keybinding registry, there - //simply is no way to find out if it's a character we want - //or not, so filter for commonly used characters and otherwise - //handle normally. The problem is really Apple's, that they - //use Alt- as the compose key in some locales. Eventually - //perhaps the applemenu module could detect this and provide alternate - //bindings with a line switch for all Alt- bindings. For - //4.0, this will have to do. - // - //Original patch replicated what Apple does in DefaultKeyAction, - //(check META instead of ALT) but this broke all Alt- - //shortcuts. So we do it the ugly way. - // - //This *does* break Alt-8/9 key combinations on norwegian and - //french keyboards, but that's better than not being able to - //type brackets - String cmd = evt.getActionCommand(); - alt &= !"{".equals(cmd) && !"}".equals(cmd) && !"[".equals(cmd) && //NOI18N - !"]".equals(cmd) && !"(".equals(cmd) && !")".equals(cmd); //NOI18N - } else if (macSwap) { - //Allow alt keys through if the flag is set - replicate - //Apple's hack in DefaultKeyAction. - alt = false; - ctrl = false; - } - } if ((alt && !ctrl) || (ctrl && !alt)) { return; Index: editor/libsrc/org/netbeans/editor/SettingsDefaults.java =================================================================== RCS file: /cvs/editor/libsrc/org/netbeans/editor/SettingsDefaults.java,v retrieving revision 1.39 diff -u -u -r1.39 SettingsDefaults.java --- editor/libsrc/org/netbeans/editor/SettingsDefaults.java 8 Sep 2004 17:09:06 -0000 1.39 +++ editor/libsrc/org/netbeans/editor/SettingsDefaults.java 2 Oct 2004 15:54:21 -0000 @@ -211,6 +211,9 @@ //Default behavior on mac is that alt+arrows is word jumps private static final int WORD_SELECT_MASK = System.getProperty("mrj.version") == null ? InputEvent.CTRL_DOWN_MASK : InputEvent.ALT_DOWN_MASK; + + private static final int ALT_MASK = System.getProperty("mrj.version") == null ? + InputEvent.ALT_DOWN_MASK : InputEvent.CTRL_DOWN_MASK; public static MultiKeyBinding[] defaultKeyBindings = new MultiKeyBinding[] { @@ -446,7 +449,7 @@ ), new MultiKeyBinding( //53 new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_E, 0), }, BaseKit.endWordAction @@ -488,7 +491,7 @@ BaseKit.findSelectionAction ), new MultiKeyBinding( //63 - KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_H, ALT_MASK | InputEvent.SHIFT_MASK), BaseKit.toggleHighlightSearchAction ), new MultiKeyBinding( //64 @@ -518,36 +521,36 @@ new MultiKeyBinding( //70 new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_T, 0), }, BaseKit.adjustWindowTopAction ), new MultiKeyBinding( //71 new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_M, 0), }, BaseKit.adjustWindowCenterAction ), new MultiKeyBinding( //72 new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_B, 0), }, BaseKit.adjustWindowBottomAction ), new MultiKeyBinding( //73 - KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.SHIFT_MASK | InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.SHIFT_MASK | ALT_MASK), BaseKit.adjustCaretTopAction ), new MultiKeyBinding( //74 - KeyStroke.getKeyStroke(KeyEvent.VK_M, InputEvent.SHIFT_MASK | InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_M, InputEvent.SHIFT_MASK | ALT_MASK), BaseKit.adjustCaretCenterAction ), new MultiKeyBinding( //75 - KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.SHIFT_MASK | InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.SHIFT_MASK | ALT_MASK), BaseKit.adjustCaretBottomAction ), @@ -556,42 +559,42 @@ BaseKit.formatAction ), new MultiKeyBinding( //77 - KeyStroke.getKeyStroke(KeyEvent.VK_J, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_J, ALT_MASK), BaseKit.selectIdentifierAction ), new MultiKeyBinding( //78 - KeyStroke.getKeyStroke(KeyEvent.VK_K, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_K, ALT_MASK), BaseKit.jumpListPrevAction ), new MultiKeyBinding( //79 - KeyStroke.getKeyStroke(KeyEvent.VK_L, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_L, ALT_MASK), BaseKit.jumpListNextAction ), new MultiKeyBinding( //80 - KeyStroke.getKeyStroke(KeyEvent.VK_K, InputEvent.SHIFT_MASK | InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_K, InputEvent.SHIFT_MASK | ALT_MASK), BaseKit.jumpListPrevComponentAction ), new MultiKeyBinding( //81 - KeyStroke.getKeyStroke(KeyEvent.VK_L, InputEvent.SHIFT_MASK | InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_L, InputEvent.SHIFT_MASK | ALT_MASK), BaseKit.jumpListNextComponentAction ), new MultiKeyBinding( //82 new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_U, 0), }, BaseKit.toUpperCaseAction ), new MultiKeyBinding( //83 new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_L, 0), }, BaseKit.toLowerCaseAction ), new MultiKeyBinding( //84 new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_R, 0), }, BaseKit.switchCaseAction @@ -669,7 +672,7 @@ ), new MultiKeyBinding( //98 - KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_Q, ALT_MASK | InputEvent.SHIFT_MASK), "dump-view-hierarchy" // NOI18N ) Index: editor/libsrc/org/netbeans/editor/ext/ExtKit.java =================================================================== RCS file: /cvs/editor/libsrc/org/netbeans/editor/ext/ExtKit.java,v retrieving revision 1.51 diff -u -u -r1.51 ExtKit.java --- editor/libsrc/org/netbeans/editor/ext/ExtKit.java 1 Oct 2004 15:55:49 -0000 1.51 +++ editor/libsrc/org/netbeans/editor/ext/ExtKit.java 2 Oct 2004 15:54:23 -0000 @@ -15,7 +15,6 @@ import java.awt.Rectangle; import java.awt.event.ActionEvent; -import java.awt.event.InputEvent; import java.io.IOException; import java.util.List; import java.util.Iterator; @@ -398,35 +397,12 @@ } public void actionPerformed(ActionEvent evt, JTextComponent target) { - //Hack: On the mac, we provide an action to globally swap - //Ctrl and Alt, so Alt can be used as a control character. But - //Goto is bound to Ctrl-G even on mac, so we need to suppress it, - //or Alt-G when swapped will not insert an international character. - //We provide the alternate binding AS-G so Goto can work even in - //swapped mode. See - //org.netbeans.core.windows.ShortcutKeyAndMenuEventProcessor - - if (isMac) { - String lastMods = System.getProperty("lastKeyModifiers"); //NOI18N - if (lastMods != null) { - try { - int mods = Integer.parseInt(lastMods); - if ((mods & InputEvent.ALT_MASK) != 0) { - return; - } - } catch (NumberFormatException e) { - //do nothing - } - } - } - if (target != null) { new GotoDialogSupport().showGotoDialog(new KeyEventBlocker(target, false)); } } } - private static final boolean isMac = System.getProperty("mrj.version") != null; //NOI18N /** Action to go to the declaration of the variable under the caret. */ Index: editor/libsrc/org/netbeans/editor/ext/ExtSettingsDefaults.java =================================================================== RCS file: /cvs/editor/libsrc/org/netbeans/editor/ext/ExtSettingsDefaults.java,v retrieving revision 1.36 diff -u -u -r1.36 ExtSettingsDefaults.java --- editor/libsrc/org/netbeans/editor/ext/ExtSettingsDefaults.java 1 Oct 2004 15:55:49 -0000 1.36 +++ editor/libsrc/org/netbeans/editor/ext/ExtSettingsDefaults.java 2 Oct 2004 15:54:23 -0000 @@ -73,7 +73,7 @@ public static final Dimension defaultJavaDocPreferredSize = new Dimension(500, 300); public static final Boolean defaultJavaDocAutoPopup = Boolean.TRUE; private static int MENU_MASK = java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - private static boolean IS_MAC = System.getProperty("mrj.version") != null; + public static final MultiKeyBinding[] defaultExtKeyBindings = new MultiKeyBinding[] { @@ -91,29 +91,19 @@ ExtKit.findAction ), new MultiKeyBinding( - KeyStroke.getKeyStroke(IS_MAC ? KeyEvent.VK_R : KeyEvent.VK_H, MENU_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_H, MENU_MASK), ExtKit.replaceAction ), new MultiKeyBinding( KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_MASK), ExtKit.gotoAction ), - //Next entry is to handle suppression of Ctrl-G on mac when - //ctrl and alt are swapped (alt is the compose key for international - //keyboards on mac, so we allow swapping of Alt and G keys via a - //shortcut so users have full use of their keyboard when necessary. - //In swap mode, this binding is actually invoked on Ctrl-Shift-G, - //not Alt-Shift-G. Wish there were a better way to solve it. - new MultiKeyBinding( - KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK), - ExtKit.gotoAction - ), new MultiKeyBinding( KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK), ExtKit.completionShowAction ), new MultiKeyBinding( // Japanese Solaris uses CTRL+SPACE for IM - KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SLASH, MENU_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SLASH, InputEvent.CTRL_MASK), ExtKit.completionShowAction ), new MultiKeyBinding( Index: editor/src/org/netbeans/modules/editor/java/NbJavaSettingsInitializer.java =================================================================== RCS file: /cvs/editor/src/org/netbeans/modules/editor/java/NbJavaSettingsInitializer.java,v retrieving revision 1.31 diff -u -u -r1.31 NbJavaSettingsInitializer.java --- editor/src/org/netbeans/modules/editor/java/NbJavaSettingsInitializer.java 8 Sep 2004 17:09:07 -0000 1.31 +++ editor/src/org/netbeans/modules/editor/java/NbJavaSettingsInitializer.java 2 Oct 2004 15:54:23 -0000 @@ -55,6 +55,9 @@ super(NAME); } + private static final int ALT_MASK = System.getProperty("mrj.version") != null ? + InputEvent.CTRL_MASK : InputEvent.ALT_MASK; + /** Update map filled with the settings. * @param kitClass kit class for which the settings are being updated. * It is always non-null value. @@ -71,11 +74,11 @@ SettingsUtil.updateListSetting(settingsMap, SettingsNames.KEY_BINDING_LIST, new MultiKeyBinding[] { new MultiKeyBinding( - KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_O, ALT_MASK), JavaKit.gotoSourceAction ), new MultiKeyBinding( - KeyStroke.getKeyStroke(KeyEvent.VK_F1, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_F1, ALT_MASK), JavaKit.gotoHelpAction ), } @@ -100,31 +103,32 @@ public MultiKeyBinding[] getJavaKeyBindings() { int mask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + boolean isMac = System.getProperty("mrj.version") != null; return new MultiKeyBinding[] { new MultiKeyBinding( new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_G, 0) }, JavaKit.makeGetterAction ), new MultiKeyBinding( new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_S, 0) }, JavaKit.makeSetterAction ), new MultiKeyBinding( new KeyStroke[] { - KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_U, ALT_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_I, 0) }, JavaKit.makeIsAction ), new MultiKeyBinding( KeyStroke.getKeyStroke(KeyEvent.VK_I, - InputEvent.ALT_MASK | InputEvent.SHIFT_MASK), + ALT_MASK | InputEvent.SHIFT_MASK), JavaKit.fastImportAction ), new MultiKeyBinding( @@ -134,16 +138,16 @@ ), new MultiKeyBinding( KeyStroke.getKeyStroke(KeyEvent.VK_F, - InputEvent.ALT_MASK | InputEvent.SHIFT_MASK), + ALT_MASK | InputEvent.SHIFT_MASK), JavaKit.fixImportsAction ), // new MultiKeyBinding( // KeyStroke.getKeyStroke(KeyEvent.VK_S, -// InputEvent.ALT_MASK | mask), +// ALT_MASK | mask), // JavaKit.tryCatchAction // ), new MultiKeyBinding( - KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.ALT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_G, ALT_MASK | (isMac ? InputEvent.SHIFT_MASK : 0)), org.netbeans.editor.ext.ExtKit.gotoDeclarationAction ), new MultiKeyBinding( @@ -154,13 +158,13 @@ new MultiKeyBinding( KeyStroke.getKeyStroke(KeyEvent.VK_A, - mask | InputEvent.ALT_MASK), + mask | ALT_MASK), JavaKit.selectNextElementAction ), new MultiKeyBinding( KeyStroke.getKeyStroke(KeyEvent.VK_A, - mask | InputEvent.ALT_MASK | InputEvent.SHIFT_MASK), + mask | ALT_MASK | InputEvent.SHIFT_MASK), JavaKit.selectPreviousElementAction ) Index: editor/src/org/netbeans/modules/editor/options/KeyBindingsMIMEOptionFile.java =================================================================== RCS file: /cvs/editor/src/org/netbeans/modules/editor/options/KeyBindingsMIMEOptionFile.java,v retrieving revision 1.9 diff -u -u -r1.9 KeyBindingsMIMEOptionFile.java --- editor/src/org/netbeans/modules/editor/options/KeyBindingsMIMEOptionFile.java 8 Sep 2004 17:09:07 -0000 1.9 +++ editor/src/org/netbeans/modules/editor/options/KeyBindingsMIMEOptionFile.java 2 Oct 2004 15:54:25 -0000 @@ -271,14 +271,23 @@ * */ static String[] getPermutations (String name) { - //IMPORTANT: THIS IS A COPY OF THE SAME CODE IN org.netbeans.core.ShortcutsFolder. + //IMPORTANT: THERE IS A COPY OF THE SAME CODE IN + //org.netbeans.core.ShortcutsFolder (it has unit tests there) //ANY CHANGES MADE HERE SHOULD ALSO BE MADE THERE! String key = KeyEvent.META_MASK == Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() ? "M" : "C"; //NOI18N - + + String ctrlWildcard = "D"; //NOI18N + + String altKey = System.getProperty ("mrj.version") != null ? + "C" : "A"; //NOI18N + + String altWildcard = "O"; //NOI18N + + int pos = name.lastIndexOf ("-"); //NOI18N String keyPart = name.substring (pos); - String modsPart = org.openide.util.Utilities.replaceString (name.substring (0, pos), "-", ""); + String modsPart = org.openide.util.Utilities.replaceString (name.substring (0, pos), "-", ""); //NOI18N if (modsPart.length() > 1) { Collection perms = new HashSet(modsPart.length() * modsPart.length()); int idx = name.indexOf(key); @@ -286,26 +295,77 @@ //First, try with the wildcard key. Remove all hyphens - we'll //put them back later StringBuffer sb = new StringBuffer(modsPart); - sb.replace(idx, idx+1, "D"); + sb.replace(idx, idx+1, ctrlWildcard); perms.add (sb.toString() + keyPart); getAllPossibleOrderings (sb.toString(), keyPart, perms); createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + idx = name.indexOf (altKey); + if (idx != -1) { + sb.replace (idx, idx+1, altWildcard); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } else { + idx = name.indexOf(altWildcard); + if (idx != -1) { + sb.replace (idx, idx+1, altKey); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } + } } else { - idx = name.indexOf ("D"); //NOI18N + idx = name.indexOf (ctrlWildcard); //NOI18N if (idx != -1) { StringBuffer sb = new StringBuffer(modsPart); sb.replace(idx, idx+1, key); perms.add (sb.toString() + keyPart); getAllPossibleOrderings (sb.toString(), keyPart, perms); createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + idx = name.indexOf (altKey); + if (idx != -1) { + sb.replace (idx, idx+1, altWildcard); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + } else { + idx = name.indexOf(altWildcard); + if (idx != -1) { + sb.replace (idx, idx+1, altKey); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } + } + } + } + + idx = name.indexOf (altKey); + if (idx != -1) { + StringBuffer sb = new StringBuffer(modsPart); + sb.replace (idx, idx+1, altWildcard); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); + } else { + StringBuffer sb = new StringBuffer(modsPart); + idx = name.indexOf(altWildcard); + if (idx != -1) { + sb.replace (idx, idx+1, altKey); + perms.add (sb.toString() + keyPart); + getAllPossibleOrderings (sb.toString(), keyPart, perms); + createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); } } + getAllPossibleOrderings (modsPart, keyPart, perms); createHyphenatedPermutation(modsPart.toCharArray(), perms, keyPart); return (String[]) perms.toArray(new String[perms.size()]); } else { return key.equals (modsPart) ? - new String[] {"D" + keyPart} : new String[0]; + new String[] {ctrlWildcard + keyPart} : altKey.equals(modsPart) ? + new String[]{altWildcard + keyPart} : altWildcard.equals(modsPart) ? + new String[] {altKey + keyPart} : + new String[0]; } } Index: editor/src/org/netbeans/modules/editor/resources/layer.xml =================================================================== RCS file: /cvs/editor/src/org/netbeans/modules/editor/resources/layer.xml,v retrieving revision 1.59 diff -u -u -r1.59 layer.xml --- editor/src/org/netbeans/modules/editor/resources/layer.xml 17 Aug 2004 07:15:33 -0000 1.59 +++ editor/src/org/netbeans/modules/editor/resources/layer.xml 2 Oct 2004 15:54:28 -0000 @@ -93,7 +93,7 @@ - + Index: editor/src/org/netbeans/modules/editor/resources/XMLs/DefaultGlobalKeyBindings.xml =================================================================== RCS file: /cvs/editor/src/org/netbeans/modules/editor/resources/XMLs/DefaultGlobalKeyBindings.xml,v retrieving revision 1.12 diff -u -u -r1.12 DefaultGlobalKeyBindings.xml --- editor/src/org/netbeans/modules/editor/resources/XMLs/DefaultGlobalKeyBindings.xml 1 Oct 2004 15:55:50 -0000 1.12 +++ editor/src/org/netbeans/modules/editor/resources/XMLs/DefaultGlobalKeyBindings.xml 2 Oct 2004 15:54:29 -0000 @@ -12,13 +12,13 @@ - - + + - + - + @@ -42,23 +42,23 @@ - + - - + + - + - + - - - - + + + + @@ -87,9 +87,9 @@ - + - + @@ -97,9 +97,6 @@ - - Index: editor/src/org/netbeans/modules/editor/resources/XMLs/DefaultKeyBindings.xml =================================================================== RCS file: /cvs/editor/src/org/netbeans/modules/editor/resources/XMLs/DefaultKeyBindings.xml,v retrieving revision 1.11 diff -u -u -r1.11 DefaultKeyBindings.xml --- editor/src/org/netbeans/modules/editor/resources/XMLs/DefaultKeyBindings.xml 8 Sep 2004 17:09:07 -0000 1.11 +++ editor/src/org/netbeans/modules/editor/resources/XMLs/DefaultKeyBindings.xml 2 Oct 2004 15:54:29 -0000 @@ -6,19 +6,19 @@ this file, with minor diffs, in ide/applemenu. Any changes made here should be made there too --> - - - + + + - - - + + + - - - + + + Index: ide/applemenu/src/org/netbeans/modules/applemenu/Bundle.properties =================================================================== RCS file: /cvs/ide/applemenu/src/org/netbeans/modules/applemenu/Bundle.properties,v retrieving revision 1.2 diff -u -u -r1.2 Bundle.properties --- ide/applemenu/src/org/netbeans/modules/applemenu/Bundle.properties 1 Oct 2004 15:55:50 -0000 1.2 +++ ide/applemenu/src/org/netbeans/modules/applemenu/Bundle.properties 2 Oct 2004 15:54:47 -0000 @@ -18,6 +18,3 @@ and moves some standard menu items there - Tools | Options becomes \ Preferences, Help | About becomes about, File | Exit becomes Quit. -LBL_SwapCtrlAlt=Swap Ctrl and Alt -MSG_Swapped=Ctrl and Alt swapped -MSG_NotSwapped=Ctrl and Alt swapping off Index: ide/applemenu/src/org/netbeans/modules/applemenu/DefaultGlobalKeyBindings.xml =================================================================== RCS file: /cvs/ide/applemenu/src/org/netbeans/modules/applemenu/DefaultGlobalKeyBindings.xml,v retrieving revision 1.2 diff -u -u -r1.2 DefaultGlobalKeyBindings.xml --- ide/applemenu/src/org/netbeans/modules/applemenu/DefaultGlobalKeyBindings.xml 1 Oct 2004 15:55:50 -0000 1.2 +++ ide/applemenu/src/org/netbeans/modules/applemenu/DefaultGlobalKeyBindings.xml 2 Oct 2004 15:54:48 -0000 @@ -34,13 +34,13 @@ - - + + - + - + @@ -64,23 +64,23 @@ - + - - + + - + - + - - - - + + + + @@ -109,9 +109,9 @@ - - - + + + @@ -120,7 +120,7 @@ - + Index: ide/applemenu/src/org/netbeans/modules/applemenu/DefaultKeyBindings.xml =================================================================== RCS file: ide/applemenu/src/org/netbeans/modules/applemenu/DefaultKeyBindings.xml diff -N ide/applemenu/src/org/netbeans/modules/applemenu/DefaultKeyBindings.xml --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ide/applemenu/src/org/netbeans/modules/applemenu/DefaultKeyBindings.xml 2 Oct 2004 15:54:48 -0000 @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + Index: ide/applemenu/src/org/netbeans/modules/applemenu/SwapCtrlAltAction.java =================================================================== RCS file: ide/applemenu/src/org/netbeans/modules/applemenu/SwapCtrlAltAction.java diff -N ide/applemenu/src/org/netbeans/modules/applemenu/SwapCtrlAltAction.java --- ide/applemenu/src/org/netbeans/modules/applemenu/SwapCtrlAltAction.java 1 Oct 2004 15:55:50 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,84 +0,0 @@ -/* - * Sun Public License Notice - * - * The contents of this file are subject to the Sun Public License - * Version 1.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://www.sun.com/ - * - * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun - * Microsystems, Inc. All Rights Reserved. - */ -/* - * SwapCtrlAltAction.java - * - * Created on October 1, 2004, 1:48 PM - */ - -package org.netbeans.modules.applemenu; - -import org.openide.awt.StatusDisplayer; -import org.openide.util.HelpCtx; -import org.openide.util.NbBundle; -import org.openide.util.actions.BooleanStateAction; - -/** - * Apple uses Alt- as the compose key on international keyboards. This causes - * a bunch of conflicts with key bindings. There are low level patches in the - * editor and window system to swap Ctrl- and Alt- if a system property is set - * to true. - *

- * This action toggles the system property nb.mac.swap.ctrl.and.alt, - * so that international keyboard users can switch between having alt bindings - * and having full use of Alt as a compose key on the mac. - *

- * In a perfect world, we would simply not have any Alt- bindings on the mac, and - * use Ctrl as an appropriate substitute. Currently, that is not a realistic - * option, as there is no way to detect when an international keyboard is - * present, and using Alt- for bindings on U.S. keyboards is very likely the - * most intuitive choice (not to mention the docs issues it would cause). - * - * @author Tim Boudreau - * @see org.netbeans.core.windows.ShortcutAndMenuKeyEventProcessor#dispatchKeyEvent - * @see org.netbeans.editor.BaseKit.DefaultKeyTypedAction#actionPerformed - */ -public class SwapCtrlAltAction extends BooleanStateAction { - private static final String PROP_KEY = "nb.mac.swap.ctrl.and.alt"; //NOI18N - - /** Creates a new instance of SwapCtrlAltAction */ - public SwapCtrlAltAction() { - - } - - public void actionPerformed (java.awt.event.ActionEvent ev) { - super.actionPerformed (ev); - boolean hasProp = propSet(); - if (hasProp) { - System.setProperty(PROP_KEY, "false"); //NOI18N - StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage( - SwapCtrlAltAction.class, "MSG_NotSwapped")); //NOI18N - } else { - System.setProperty(PROP_KEY, "true"); //NOI18N - StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage( - SwapCtrlAltAction.class, "MSG_Swapped")); //NOI18N - } - } - - private boolean propSet () { - return Boolean.getBoolean (PROP_KEY); - } - - protected void initialize () { - super.initialize(); - putProperty(PROP_BOOLEAN_STATE, propSet() ? Boolean.TRUE : Boolean.FALSE); - } - - public HelpCtx getHelpCtx() { - return HelpCtx.DEFAULT_HELP; - } - - public String getName() { - return NbBundle.getMessage (SwapCtrlAltAction.class, "LBL_SwapCtrlAlt"); //NOI18N - } -} Index: ide/applemenu/src/org/netbeans/modules/applemenu/layer.xml =================================================================== RCS file: /cvs/ide/applemenu/src/org/netbeans/modules/applemenu/layer.xml,v retrieving revision 1.3 diff -u -u -r1.3 layer.xml --- ide/applemenu/src/org/netbeans/modules/applemenu/layer.xml 1 Oct 2004 15:55:50 -0000 1.3 +++ ide/applemenu/src/org/netbeans/modules/applemenu/layer.xml 2 Oct 2004 15:54:48 -0000 @@ -34,11 +34,7 @@ ---> - - - - +--> @@ -64,14 +60,15 @@ + + - + + + - - - @@ -79,6 +76,7 @@ + Index: openide/loaders/src/org/openide/awt/MenuBar.java =================================================================== RCS file: /cvs/openide/loaders/src/org/openide/awt/MenuBar.java,v retrieving revision 1.8 diff -u -u -r1.8 MenuBar.java --- openide/loaders/src/org/openide/awt/MenuBar.java 14 Sep 2004 10:14:45 -0000 1.8 +++ openide/loaders/src/org/openide/awt/MenuBar.java 2 Oct 2004 15:56:10 -0000 @@ -16,9 +16,11 @@ import java.awt.Component; import java.awt.EventQueue; import java.awt.event.*; +import java.awt.event.KeyEvent; import java.io.*; import java.util.*; import javax.swing.*; +import javax.swing.KeyStroke; import org.openide.ErrorManager; import org.openide.loaders.*; @@ -26,6 +28,7 @@ import org.openide.filesystems.FileObject; import org.openide.filesystems.Repository; import org.openide.nodes.*; +import org.openide.util.Utilities; import org.openide.util.actions.Presenter; import org.openide.util.*; @@ -73,7 +76,7 @@ * If the parameter is null, default menu folder is obtained. */ public MenuBar(DataFolder folder) { - super(); + this(); setBorder (javax.swing.BorderFactory.createEmptyBorder()); DataFolder theFolder = folder; if (theFolder == null) { @@ -100,6 +103,56 @@ } super.addImpl (c, constraint, idx); } + + /** + * Overridden to handle mac conversion from Alt to Ctrl and vice versa so + * Alt can be used as the compose character on international keyboards. + */ + protected boolean processKeyBinding(KeyStroke ks, + KeyEvent e, + int condition, + boolean pressed) { + if (Utilities.getOperatingSystem() == Utilities.OS_MAC) { + int mods = e.getModifiers(); + boolean isCtrl = (mods & KeyEvent.CTRL_MASK) != 0; + boolean isAlt = (mods & KeyEvent.ALT_MASK) != 0; + if (isAlt) { + return false; + } + if (isAlt && !isCtrl) { + mods = mods & ~ KeyEvent.ALT_MASK; + mods = mods & ~ KeyEvent.ALT_DOWN_MASK; + mods |= KeyEvent.CTRL_MASK; + mods |= KeyEvent.CTRL_DOWN_MASK; + } else if (!isAlt && isCtrl) { + mods = mods & ~ KeyEvent.CTRL_MASK; + mods = mods & ~ KeyEvent.CTRL_DOWN_MASK; + mods |= KeyEvent.ALT_MASK; + mods |= KeyEvent.ALT_DOWN_MASK; + } else if (!isAlt && !isCtrl) { + return super.processKeyBinding (ks, e, condition, pressed); + } + + KeyEvent newEvent = new MarkedKeyEvent ((Component) e.getSource(), e.getID(), + e.getWhen(), mods, e.getKeyCode(), e.getKeyChar(), + e.getKeyLocation()); + + KeyStroke newStroke = e.getID() == KeyEvent.KEY_TYPED ? + KeyStroke.getKeyStroke (ks.getKeyChar(), mods) : + KeyStroke.getKeyStroke (ks.getKeyCode(), mods, + !ks.isOnKeyRelease()); + + boolean result = super.processKeyBinding (newStroke, newEvent, + condition, pressed); + + if (newEvent.isConsumed()) { + e.consume(); + } + return result; + } else { + return super.processKeyBinding (ks, e, condition, pressed); + } + } /** Blocks until the menubar is completely created. */ public void waitFinished () { @@ -295,6 +348,18 @@ } } + + /** + * A marker class to allow different processing of remapped key events + * on mac - allows them to be recognized by LazyMenu. + */ + private static final class MarkedKeyEvent extends KeyEvent { + public MarkedKeyEvent (Component c, int id, + long when, int mods, int code, char kchar, + int loc) { + super(c, id, when, mods, code, kchar, loc); + } + } /** Menu based on the folder content whith lazy items creation. */ private static class LazyMenu extends JMenuPlus implements NodeListener, Runnable { @@ -313,6 +378,47 @@ updateProps(); } + + protected boolean processKeyBinding(KeyStroke ks, + KeyEvent e, + int condition, + boolean pressed) { + if (Utilities.getOperatingSystem() == Utilities.OS_MAC) { + int mods = e.getModifiers(); + boolean isCtrl = (mods & KeyEvent.CTRL_MASK) != 0; + boolean isAlt = (mods & KeyEvent.ALT_MASK) != 0; + if (isAlt && (e instanceof MarkedKeyEvent)) { + mods = mods & ~ KeyEvent.CTRL_MASK; + mods = mods & ~ KeyEvent.CTRL_DOWN_MASK; + mods |= KeyEvent.ALT_MASK; + mods |= KeyEvent.ALT_DOWN_MASK; + + KeyEvent newEvent = new MarkedKeyEvent ( + (Component) e.getSource(), e.getID(), + e.getWhen(), mods, e.getKeyCode(), e.getKeyChar(), + e.getKeyLocation()); + + KeyStroke newStroke = e.getID() == KeyEvent.KEY_TYPED ? + KeyStroke.getKeyStroke (ks.getKeyChar(), mods) : + KeyStroke.getKeyStroke (ks.getKeyCode(), mods, + !ks.isOnKeyRelease()); + + boolean result = super.processKeyBinding (newStroke, + newEvent, condition, pressed); + + if (newEvent.isConsumed()) { + e.consume(); + } + return result; + } else if (!isAlt) { + return super.processKeyBinding (ks, e, condition, pressed); + } else { + return false; + } + } else { + return super.processKeyBinding (ks, e, condition, pressed); + } + } private void updateProps() { // set the text and be aware of mnemonics Index: openide/src/org/openide/util/Utilities.java =================================================================== RCS file: /cvs/openide/src/org/openide/util/Utilities.java,v retrieving revision 1.144 diff -u -u -r1.144 Utilities.java --- openide/src/org/openide/util/Utilities.java 8 Sep 2004 17:09:10 -0000 1.144 +++ openide/src/org/openide/util/Utilities.java 2 Oct 2004 15:56:24 -0000 @@ -1218,6 +1218,23 @@ *

  • S stands for the Shift key *
  • M stands for the Meta key * + * The format also supports two wildcard codes, to support differences in + * platforms. These are the preferred choices for registering keystrokes, + * since platform conflicts will automatically be handled: + *
      + *
    • D stands for the default menu accelerator - the Control + * key on most platforms, the Command (meta) key on Macintosh
    • + *
    • O stands for the alternate accelerator - the Alt key on + * most platforms, the Ctrl key on Macintosh (Macintosh uses Alt as a + * secondary shift key for composing international characters - if you bind + * Alt-8 to an action, a mac user with a French keyboard will not be able + * to type the [ character, which is a significant handicap
    • + *
    + * If you use the wildcard characters, and specify a key which will conflict + * with keys the operating system consumes, it will be mapped to whichever + * choice can work - for example, on Macintosh, Command-Q is always consumed + * by the operating system, so D-Q will always map to Control-Q. + *

    * Every modifier before the hyphen must be pressed. * identifier can be any text constant from {@link KeyEvent} but * without the leading VK_ characters. So {@link KeyEvent#VK_ENTER} is described as @@ -1252,10 +1269,13 @@ } else { // last text must be the key code Integer i = (Integer)names.get (el); - boolean wildcard = (needed & WILDCARD_MASK) != 0; + boolean wildcard = (needed & CTRL_WILDCARD_MASK) != 0; //Strip out the explicit mask - KeyStroke won't know //what to do with it - needed = needed & ~WILDCARD_MASK; + needed = needed & ~CTRL_WILDCARD_MASK; + + boolean macAlt = (needed & ALT_WILDCARD_MASK) != 0; + needed = needed & ~ALT_WILDCARD_MASK; if (i != null) { //#26854 - Default accelerator should be Command on mac @@ -1268,6 +1288,13 @@ } } } + if (macAlt) { + if (getOperatingSystem() == OS_MAC) { + needed |= KeyEvent.CTRL_MASK; + } else { + needed |= KeyEvent.ALT_MASK; + } + } return KeyStroke.getKeyStroke (i.intValue (), needed); } else { return null; @@ -1322,7 +1349,8 @@ return (KeyStroke[])arr.toArray (new KeyStroke[arr.size ()]); } - private static final int WILDCARD_MASK = 32768; + private static final int CTRL_WILDCARD_MASK = 32768; + private static final int ALT_WILDCARD_MASK = CTRL_WILDCARD_MASK * 2; /** Adds characters for modifiers to the buffer. * @param buf buffer to add to @@ -1348,10 +1376,14 @@ buf.append("M"); // NOI18N b = true; } - if ((modif & WILDCARD_MASK) != 0) { + if ((modif & CTRL_WILDCARD_MASK) != 0) { buf.append("D"); b = true; } + if ((modif & ALT_WILDCARD_MASK) != 0) { + buf.append("O"); + b = true; + } return b; } @@ -1378,10 +1410,13 @@ m |= KeyEvent.SHIFT_MASK; break; case 'D': - m |= WILDCARD_MASK; + m |= CTRL_WILDCARD_MASK; + break; + case 'O': + m |= ALT_WILDCARD_MASK; break; default: - throw new NoSuchElementException (); + throw new NoSuchElementException (s); } } return m; Index: refactoring/src/org/netbeans/modules/refactoring/resources/mf-layer.xml =================================================================== RCS file: /cvs/refactoring/src/org/netbeans/modules/refactoring/resources/mf-layer.xml,v retrieving revision 1.13 diff -u -u -r1.13 mf-layer.xml --- refactoring/src/org/netbeans/modules/refactoring/resources/mf-layer.xml 24 Sep 2004 09:34:30 -0000 1.13 +++ refactoring/src/org/netbeans/modules/refactoring/resources/mf-layer.xml 2 Oct 2004 15:56:47 -0000 @@ -59,13 +59,13 @@ - + - + - +