From: <cr...@us...> - 2008-10-11 03:45:07
|
Revision: 4619 http://jnode.svn.sourceforge.net/jnode/?rev=4619&view=rev Author: crawley Date: 2008-10-11 03:44:57 +0000 (Sat, 11 Oct 2008) Log Message: ----------- Implemented some more 'bindkeys' functionality Modified Paths: -------------- trunk/core/src/driver/org/jnode/driver/console/KeyEventBindings.java trunk/core/src/driver/org/jnode/driver/console/textscreen/ConsoleKeyEventBindings.java trunk/shell/descriptors/org.jnode.shell.command.xml trunk/shell/src/shell/org/jnode/shell/command/BindKeysCommand.java Modified: trunk/core/src/driver/org/jnode/driver/console/KeyEventBindings.java =================================================================== --- trunk/core/src/driver/org/jnode/driver/console/KeyEventBindings.java 2008-10-10 13:01:27 UTC (rev 4618) +++ trunk/core/src/driver/org/jnode/driver/console/KeyEventBindings.java 2008-10-11 03:44:57 UTC (rev 4619) @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Set; +import org.jnode.driver.console.textscreen.KeyboardReaderAction; import org.jnode.driver.input.KeyboardEvent; /** @@ -131,14 +132,13 @@ } /** - * Set the action for a given virtual key code and no modifiers + * Unset the action for a given character. + * This is equivalent to setting the action to the default action. * - * @param vk the virtual key code - * @param action the action + * @param ch the character */ - public void setVKAction(int vk, T action) { - checkVK(vk, 0); - vkMap.put(vk, action); + public void unsetCharAction(char ch) { + charMap.put(ch, defaultCharAction); } /** @@ -154,6 +154,37 @@ } /** + * Unset the action for a given virtual key code and modifier set. + * This is equivalent to setting the action to the default action. + * + * @param vk the virtual key code + * @param modifiers the modifier set + */ + public void unsetVKAction(int vk, int modifiers) { + setVKAction(vk, modifiers, defaultVKAction); + } + + /** + * Set the action for a given VirtualKey + * + * @param vk the VirtualKey + * @param action the action + */ + public void setVKAction(VirtualKey vk, T action) { + setVKAction(vk.getVKCode(), vk.getModifiers(), action); + } + + /** + * Unset the action for a given VirtualKey. + * This is equivalent to setting the action to the default action. + * + * @param vk the VirtualKey + */ + public void unsetVKAction(VirtualKey vk) { + setVKAction(vk, defaultVKAction); + } + + /** * Set the action for a given range of characters * * @param chLo the first character in the range @@ -187,6 +218,10 @@ } } + /** + * Get all characters that are currently bound to an action. + * @return the bound characters. + */ public char[] getBoundChars() { Set<Integer> charSet = charMap.getKeys(); char[] res = new char[charSet.size()]; @@ -197,6 +232,10 @@ return res; } + /** + * Get all virtual keys that are currently bound to an action. + * @return the bound virtual keys. + */ public VirtualKey[] getBoundVKs() { Set<Integer> vkSet = vkMap.getKeys(); VirtualKey[] res = new VirtualKey[vkSet.size()]; Modified: trunk/core/src/driver/org/jnode/driver/console/textscreen/ConsoleKeyEventBindings.java =================================================================== --- trunk/core/src/driver/org/jnode/driver/console/textscreen/ConsoleKeyEventBindings.java 2008-10-10 13:01:27 UTC (rev 4618) +++ trunk/core/src/driver/org/jnode/driver/console/textscreen/ConsoleKeyEventBindings.java 2008-10-11 03:44:57 UTC (rev 4619) @@ -54,22 +54,22 @@ */ public static ConsoleKeyEventBindings createDefault() { ConsoleKeyEventBindings res = new ConsoleKeyEventBindings(); - res.setVKAction(KeyEvent.VK_BACK_SPACE, KeyboardReaderAction.KR_DELETE_BEFORE); + res.setVKAction(KeyEvent.VK_BACK_SPACE, 0, KeyboardReaderAction.KR_DELETE_BEFORE); res.setCharAction('\b', KeyboardReaderAction.KR_DELETE_BEFORE); - res.setVKAction(KeyEvent.VK_ENTER, KeyboardReaderAction.KR_ENTER); + res.setVKAction(KeyEvent.VK_ENTER, 0, KeyboardReaderAction.KR_ENTER); res.setCharAction('\n', KeyboardReaderAction.KR_ENTER); - res.setVKAction(KeyEvent.VK_TAB, KeyboardReaderAction.KR_COMPLETE); + res.setVKAction(KeyEvent.VK_TAB, 0, KeyboardReaderAction.KR_COMPLETE); res.setCharAction('\t', KeyboardReaderAction.KR_COMPLETE); res.setCharAction('\004', KeyboardReaderAction.KR_SOFT_EOF); res.setCharAction('\014', KeyboardReaderAction.KR_KILL_LINE); - res.setVKAction(KeyEvent.VK_UP, KeyboardReaderAction.KR_HISTORY_UP); - res.setVKAction(KeyEvent.VK_DOWN, KeyboardReaderAction.KR_HISTORY_DOWN); - res.setVKAction(KeyEvent.VK_LEFT, KeyboardReaderAction.KR_CURSOR_LEFT); - res.setVKAction(KeyEvent.VK_RIGHT, KeyboardReaderAction.KR_CURSOR_RIGHT); - res.setVKAction(KeyEvent.VK_HOME, KeyboardReaderAction.KR_CURSOR_TO_START); - res.setVKAction(KeyEvent.VK_END, KeyboardReaderAction.KR_CURSOR_TO_END); + res.setVKAction(KeyEvent.VK_UP, 0, KeyboardReaderAction.KR_HISTORY_UP); + res.setVKAction(KeyEvent.VK_DOWN, 0, KeyboardReaderAction.KR_HISTORY_DOWN); + res.setVKAction(KeyEvent.VK_LEFT, 0, KeyboardReaderAction.KR_CURSOR_LEFT); + res.setVKAction(KeyEvent.VK_RIGHT, 0, KeyboardReaderAction.KR_CURSOR_RIGHT); + res.setVKAction(KeyEvent.VK_HOME, 0, KeyboardReaderAction.KR_CURSOR_TO_START); + res.setVKAction(KeyEvent.VK_END, 0, KeyboardReaderAction.KR_CURSOR_TO_END); res.setCharAction('\177', KeyboardReaderAction.KR_DELETE_AFTER); - res.setVKAction(KeyEvent.VK_DELETE, KeyboardReaderAction.KR_DELETE_AFTER); + res.setVKAction(KeyEvent.VK_DELETE, 0, KeyboardReaderAction.KR_DELETE_AFTER); return res; } } Modified: trunk/shell/descriptors/org.jnode.shell.command.xml =================================================================== --- trunk/shell/descriptors/org.jnode.shell.command.xml 2008-10-10 13:01:27 UTC (rev 4618) +++ trunk/shell/descriptors/org.jnode.shell.command.xml 2008-10-11 03:44:57 UTC (rev 4619) @@ -55,7 +55,13 @@ <argument argLabel="className"/> </sequence> </syntax> - <syntax alias="bindkeys" description="Show the key bindings"> + <syntax alias="bindkeys"> + <empty description="Show the key bindings"/> + <option argLabel="reset" longName="reset" description="Reset the key bindings to the default settings"/> + <sequence description="Remove key bindings"> + <option argLabel="remove" shortName="r" longName="remove"/> + <argument argLabel="action"/> + </sequence> </syntax> <syntax alias="class" description="Show details of a Java class"> <argument argLabel="className"/> Modified: trunk/shell/src/shell/org/jnode/shell/command/BindKeysCommand.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/command/BindKeysCommand.java 2008-10-10 13:01:27 UTC (rev 4618) +++ trunk/shell/src/shell/org/jnode/shell/command/BindKeysCommand.java 2008-10-11 03:44:57 UTC (rev 4619) @@ -20,8 +20,6 @@ */ package org.jnode.shell.command; -import static java.awt.event.KeyEvent.*; - import java.awt.event.KeyEvent; import java.io.PrintWriter; import java.util.ArrayList; @@ -30,12 +28,17 @@ import java.util.Map; import org.jnode.driver.console.Console; +import org.jnode.driver.console.KeyEventBindings; import org.jnode.driver.console.TextConsole; import org.jnode.driver.console.VirtualKey; import org.jnode.driver.console.textscreen.ConsoleKeyEventBindings; import org.jnode.driver.console.textscreen.KeyboardReaderAction; import org.jnode.shell.AbstractCommand; import org.jnode.shell.ShellUtils; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.EnumArgument; +import org.jnode.shell.syntax.FlagArgument; +import org.jnode.shell.syntax.StringArgument; /** * This command allows the user to examine and change JNode's key bindings. @@ -43,11 +46,51 @@ * @author cr...@jn... */ public class BindKeysCommand extends AbstractCommand { + + private static final String[] ASCII_NAMES = new String[] { + "NUL", "SOH", "STC", "ETX", "EOT", "ENQ", "ACK", "BEL", + "BS", "HT", "NL", "VT", "FF", "CR", "SO", "SI", + "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", + "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" + }; + + private static class ActionArgument extends EnumArgument<KeyboardReaderAction> { + public ActionArgument(String label, int flags, String description) { + super(label, flags, KeyboardReaderAction.class, description); + } + + @Override + protected String argumentKind() { + return "keyboard reader action"; + } + } + + private final FlagArgument FLAG_RESET = + new FlagArgument("reset", Argument.OPTIONAL, "reset the bindings to the default values"); + + private final FlagArgument FLAG_ADD = + new FlagArgument("add", Argument.OPTIONAL, "add bindings"); + + private final FlagArgument FLAG_REMOVE = + new FlagArgument("remove", Argument.OPTIONAL, "remove bindings"); + + private final ActionArgument ARG_ACTION = + new ActionArgument("action", Argument.OPTIONAL, "an keyboard reader action"); + + private final StringArgument ARG_VK_NAME = + new StringArgument("vkName", Argument.OPTIONAL + Argument.MULTIPLE, "a virtual key specification"); + + private final StringArgument ARG_CHAR_NAME = + new StringArgument("charName", Argument.OPTIONAL + Argument.MULTIPLE, "a character"); + private PrintWriter out; private PrintWriter err; + public BindKeysCommand() { super("display or change the keyboard bindings"); + registerArguments(FLAG_RESET, FLAG_ADD, FLAG_REMOVE, + ARG_ACTION, ARG_VK_NAME, ARG_CHAR_NAME); } @Override @@ -56,43 +99,106 @@ err = getError().getPrintWriter(); Console console = ShellUtils.getCurrentShell().getConsole(); if (!(console instanceof TextConsole)) { - err.println("The current console is not a TextConsole"); + err.println("The current console is not a TextConsole."); } TextConsole textConsole = (TextConsole) console; - displayBindings(textConsole); + if (FLAG_RESET.isSet()) { + resetBindings(textConsole); + } else if (FLAG_ADD.isSet()) { + addBindings(textConsole); + } else if (FLAG_REMOVE.isSet()) { + removeBindings(textConsole); + } else { + displayBindings(textConsole); + } } - private void displayBindings(TextConsole console) { + /** + * Remove bindings for an action. + * + * @param console the console whose bindings are to be changed + */ + private void removeBindings(TextConsole console) { ConsoleKeyEventBindings bindings = console.getKeyEventBindings(); + // This throws an unchecked exception if the action is not supplied. It signals + // a bug in the command syntax and should be allowed to propagate to the shell. + KeyboardReaderAction action = ARG_ACTION.getValue(); - // Build a map from actions to the characters that map to them. - char[] boundChars = bindings.getBoundChars(); - Map<KeyboardReaderAction, List<Character>> charMap = - new HashMap<KeyboardReaderAction, List<Character>>(); - for (char ch : boundChars) { - KeyboardReaderAction action = bindings.getCharAction(ch); - List<Character> list = charMap.get(action); - if (list == null) { - list = new ArrayList<Character>(); - charMap.put(action, list); + if (ARG_CHAR_NAME.isSet() || ARG_VK_NAME.isSet()) { + // If character or virtual key names were supplied, remove only those bindings. + if (ARG_CHAR_NAME.isSet()) { + for (String charName : ARG_CHAR_NAME.getValues()) { + char ch = getCharacter(charName); + if (ch != KeyEvent.CHAR_UNDEFINED) { + bindings.unsetCharAction(ch); + } else { + err.println("Cannot translate character name '" + charName + "'"); + exit(1); + } + } + } + if (ARG_VK_NAME.isSet()) { + for (String vkName : ARG_VK_NAME.getValues()) { + VirtualKey vk = getVirtualKey(vkName); + if (vk != null) { + bindings.unsetVKAction(vk); + } else { + err.println("Cannot translate virtual key name '" + vkName + "'"); + exit(1); + } + } + } + } else { + // Otherwise remove all bindings for the action. + int count = 0; + List<Character> chars = buildCharMap(bindings).get(action); + if (chars != null) { + for (char ch : chars) { + bindings.unsetCharAction(ch); + count++; + } } - list.add(ch); - } - - // Build a map from actions to the virtual keys that map to them. - VirtualKey[] boundKeys = bindings.getBoundVKs(); - Map<KeyboardReaderAction, List<VirtualKey>> vkMap = - new HashMap<KeyboardReaderAction, List<VirtualKey>>(); - for (VirtualKey vk : boundKeys) { - KeyboardReaderAction action = bindings.getVKAction(vk); - List<VirtualKey> list = vkMap.get(action); - if (list == null) { - list = new ArrayList<VirtualKey>(); - vkMap.put(action, list); + List<VirtualKey> vks = buildVKMap(bindings).get(action); + if (vks != null) { + for (VirtualKey vk : vks) { + bindings.unsetVKAction(vk); + count++; + } } - list.add(vk); + if (count == 0) { + err.println("There are no bindings for action '" + action + "'"); + exit(1); + } } + console.setKeyEventBindings(bindings); + out.println("Updated the current console's key bindings for action '" + action + "'."); + } + + private char getCharacter(String charName) { + // TODO Auto-generated method stub + return KeyEvent.CHAR_UNDEFINED; + } + + private VirtualKey getVirtualKey(String vkName) { + // TODO Auto-generated method stub + return null; + } + + private void addBindings(TextConsole console) { + ConsoleKeyEventBindings bindings = console.getKeyEventBindings(); + } + + private void resetBindings(TextConsole console) { + console.setKeyEventBindings(ConsoleKeyEventBindings.createDefault()); + out.println("Reset the current console's key bindings."); + } + + private void displayBindings(TextConsole console) { + ConsoleKeyEventBindings bindings = console.getKeyEventBindings(); + Map<KeyboardReaderAction, List<Character>> charMap = buildCharMap(bindings); + Map<KeyboardReaderAction, List<VirtualKey>> vkMap = buildVKMap(bindings); + for (KeyboardReaderAction action : KeyboardReaderAction.values()) { List<Character> chars = charMap.get(action); List<VirtualKey> vks = vkMap.get(action); @@ -133,6 +239,50 @@ } } + /** + * Build a map from actions to the virtual keys that map to them. + * @param bindings + * @return the map + */ + private Map<KeyboardReaderAction, List<VirtualKey>> buildVKMap( + KeyEventBindings<KeyboardReaderAction> bindings) { + VirtualKey[] boundKeys = bindings.getBoundVKs(); + Map<KeyboardReaderAction, List<VirtualKey>> vkMap = + new HashMap<KeyboardReaderAction, List<VirtualKey>>(); + for (VirtualKey vk : boundKeys) { + KeyboardReaderAction action = bindings.getVKAction(vk); + List<VirtualKey> list = vkMap.get(action); + if (list == null) { + list = new ArrayList<VirtualKey>(); + vkMap.put(action, list); + } + list.add(vk); + } + return vkMap; + } + + /** + * Build a map from actions to the characters that map to them. + * @param bindings + * @return the map. + */ + private Map<KeyboardReaderAction, List<Character>> buildCharMap( + KeyEventBindings<KeyboardReaderAction> bindings) { + char[] boundChars = bindings.getBoundChars(); + Map<KeyboardReaderAction, List<Character>> charMap = + new HashMap<KeyboardReaderAction, List<Character>>(); + for (char ch : boundChars) { + KeyboardReaderAction action = bindings.getCharAction(ch); + List<Character> list = charMap.get(action); + if (list == null) { + list = new ArrayList<Character>(); + charMap.put(action, list); + } + list.add(ch); + } + return charMap; + } + private String describe(KeyboardReaderAction action) { return action.toString(); } @@ -140,13 +290,6 @@ private KeyboardReaderAction getAction(String name) { return KeyboardReaderAction.valueOf(name); } - - private static final String[] ASCII_NAMES = new String[] { - "NUL", "SOH", "STC", "ETX", "EOT", "ENQ", "ACK", "BEL", - "BS", "HT", "NL", "VT", "FF", "CR", "SO", "SI", - "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", - "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" - }; private String describe(char ch) { StringBuilder sb = new StringBuilder(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |