Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/Shortcut.java

    r4595 r4979  
    66import java.awt.event.KeyEvent;
    77import java.util.ArrayList;
     8import java.util.Arrays;
     9import java.util.Collection;
    810import java.util.HashMap;
    911import java.util.LinkedHashMap;
     12import java.util.LinkedList;
    1013import java.util.List;
    1114import java.util.Map;
    1215
     16import javax.swing.AbstractAction;
    1317import javax.swing.AbstractButton;
    1418import javax.swing.JMenu;
     
    3337 */
    3438public class Shortcut {
    35     //  public static final int SHIFT = KeyEvent.SHIFT_DOWN_MASK;
    36     //  public static final int CTRL = KeyEvent.CTRL_DOWN_MASK;
    37     //  public static final int SHIFT_CTRL = KeyEvent.SHIFT_DOWN_MASK|KeyEvent.CTRL_DOWN_MASK;
    38     public static final int SHIFT_DEFAULT = 1;
    3939    private String shortText;        // the unique ID of the shortcut
    4040    private String longText;         // a human readable description that will be shown in the preferences
     
    137137     */
    138138    public void setAssignedUser(boolean assignedUser) {
    139         this.reset = (!this.assignedUser && assignedUser);
     139        this.reset = (this.assignedUser || reset) && !assignedUser;
    140140        if (assignedUser) {
    141141            assignedDefault = false;
     142        } else if (reset) {
     143            assignedKey = requestedKey;
     144            assignedModifier = findModifier(requestedGroup, null);
    142145        }
    143146        this.assignedUser = assignedUser;
     
    153156    }
    154157
    155     private boolean isSame(int isKey, int isModifier) {
    156         // -1 --- an unassigned shortcut is different from any other shortcut
    157         return( isKey == assignedKey && isModifier == assignedModifier && assignedModifier != groups.get(GROUP_NONE));
    158     }
    159 
    160158    // create a shortcut object from an string as saved in the preferences
    161159    private Shortcut(String prefString) {
    162         String[] s = prefString.split(";");
    163         this.shortText = s[0];
    164         this.longText = s[1];
    165         this.requestedKey = Integer.parseInt(s[2]);
    166         this.requestedGroup = Integer.parseInt(s[3]);
    167         this.assignedKey = Integer.parseInt(s[4]);
    168         this.assignedModifier = Integer.parseInt(s[5]);
    169         this.assignedDefault = Boolean.parseBoolean(s[6]);
    170         this.assignedUser = Boolean.parseBoolean(s[7]);
     160        ArrayList<String> s = (new ArrayList<String>(Main.pref.getCollection(prefString)));
     161        this.shortText = prefString.substring(15);
     162        this.longText = s.get(0);
     163        this.requestedKey = Integer.parseInt(s.get(1));
     164        this.requestedGroup = Integer.parseInt(s.get(2));
     165        this.assignedKey = Integer.parseInt(s.get(3));
     166        this.assignedModifier = Integer.parseInt(s.get(4));
     167        this.assignedDefault = Boolean.parseBoolean(s.get(5));
     168        this.assignedUser = Boolean.parseBoolean(s.get(6));
     169    }
     170
     171    private void saveDefault() {
     172        Main.pref.getCollection("shortcut.entry."+shortText, Arrays.asList(new String[]{longText,
     173        String.valueOf(requestedKey), String.valueOf(requestedGroup), String.valueOf(requestedKey),
     174        String.valueOf(getGroupModifier(requestedGroup)), String.valueOf(true), String.valueOf(false)}));
    171175    }
    172176
    173177    // get a string that can be put into the preferences
    174     private String asPrefString() {
    175         return shortText + ";" + longText + ";" + requestedKey + ";" + requestedGroup + ";" + assignedKey + ";" + assignedModifier + ";" + assignedDefault + ";" + assignedUser;
    176     }
    177 
    178     private boolean isSame(Shortcut other) {
    179         return assignedKey == other.assignedKey && assignedModifier == other.assignedModifier;
     178    private boolean save() {
     179        if (getAutomatic() || getReset() || !getAssignedUser()) {
     180            return Main.pref.putCollection("shortcut.entry."+shortText, null);
     181        } else {
     182            return Main.pref.putCollection("shortcut.entry."+shortText, Arrays.asList(new String[]{longText,
     183            String.valueOf(requestedKey), String.valueOf(requestedGroup), String.valueOf(assignedKey),
     184            String.valueOf(assignedModifier), String.valueOf(assignedDefault), String.valueOf(assignedUser)}));
     185        }
     186    }
     187
     188    private boolean isSame(int isKey, int isModifier) {
     189        // an unassigned shortcut is different from any other shortcut
     190        return isKey == assignedKey && isModifier == assignedModifier && assignedModifier != getGroupModifier(NONE);
     191    }
     192
     193    public boolean isEvent(KeyEvent e) {
     194        return getKeyStroke() != null && getKeyStroke().equals(
     195        KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers()));
    180196    }
    181197
     
    184200     */
    185201    public void setMnemonic(JMenu menu) {
    186         if (requestedGroup == GROUP_MNEMONIC && assignedModifier == groups.get(requestedGroup + GROUPS_DEFAULT) && getKeyStroke() != null && KeyEvent.getKeyText(assignedKey).length() == 1) {
     202        if (assignedModifier == getGroupModifier(MNEMONIC) && getKeyStroke() != null && KeyEvent.getKeyText(assignedKey).length() == 1) {
    187203            menu.setMnemonic(KeyEvent.getKeyText(assignedKey).charAt(0)); //getKeyStroke().getKeyChar() seems not to work here
    188204        }
     
    192208     */
    193209    public void setMnemonic(AbstractButton button) {
    194         if (requestedGroup == GROUP_MNEMONIC && assignedModifier == groups.get(requestedGroup + GROUPS_DEFAULT) && getKeyStroke() != null && KeyEvent.getKeyText(assignedKey).length() == 1) {
     210        if (assignedModifier == getGroupModifier(MNEMONIC) && getKeyStroke() != null && KeyEvent.getKeyText(assignedKey).length() == 1) {
    195211            button.setMnemonic(KeyEvent.getKeyText(assignedKey).charAt(0)); //getKeyStroke().getKeyChar() seems not to work here
     212        }
     213    }
     214    /**
     215     * use this to set a actions's accelerator
     216     */
     217    public void setAccelerator(AbstractAction action) {
     218        if (getKeyStroke() != null) {
     219            action.putValue(AbstractAction.ACCELERATOR_KEY, getKeyStroke());
    196220        }
    197221    }
     
    221245
    222246    // and here our modifier groups
    223     private static Map<Integer, Integer> groups = new HashMap<Integer, Integer>();
     247    private static Map<Integer, Integer> groups= new HashMap<Integer, Integer>();
    224248
    225249    // check if something collides with an existing shortcut
    226250    private static Shortcut findShortcut(int requestedKey, int modifier) {
    227         if (modifier == groups.get(GROUP_NONE))
     251        if (modifier == getGroupModifier(NONE))
    228252            return null;
    229253        for (Shortcut sc : shortcuts.values()) {
     
    248272    }
    249273
    250     // try to find an unused shortcut
    251     private static Shortcut findRandomShortcut(String shortText, String longText, int requestedKey, int requestedGroup) {
    252         int[] mods = {groups.get(requestedGroup + GROUPS_DEFAULT), groups.get(requestedGroup + GROUPS_ALT1), groups.get(requestedGroup + GROUPS_ALT2)};
    253         for (int m : mods) {
    254             for (int k = KeyEvent.VK_A; k < KeyEvent.VK_Z; k++) { // we'll limit ourself to 100% safe keys
    255                 if ( findShortcut(k, m) == null )
    256                     return new Shortcut(shortText, longText, requestedKey, requestedGroup, k, m, false, false);
    257             }
    258         }
    259         return new Shortcut(shortText, longText, requestedKey, requestedGroup, requestedKey, groups.get(GROUP_NONE), false, false);
    260     }
    261 
    262     // use these constants to request shortcuts
    263     /**
    264      * no shortcut.
    265      */
    266     public static final int GROUP_NONE = 0;
    267     /**
    268      * a button action, will use another modifier than MENU on system with a meta key.
    269      */
    270     public static final int GROUP_HOTKEY = 1;
    271     /**
    272      * a menu action, e.g. "ctrl-e" (export).
    273      */
    274     public static final int GROUP_MENU = 2;
    275     /**
    276      * direct edit key, e.g. "a" (add).
    277      */
    278     public static final int GROUP_EDIT = 3;
    279     /**
    280      * toggle one of the right-hand-side windows, e.g. "alt-l" (layers).
    281      */
    282     public static final int GROUP_LAYER = 4;
    283     /**
    284      * for non-letter keys, preferable without modifier, e.g. F5.
    285      */
    286     public static final int GROUP_DIRECT = 5;
    287     /**
    288      * for use with {@see #setMnemonic} only!
    289      */
    290     public static final int GROUP_MNEMONIC = 6;
    291     public static final int GROUP__MAX = 7;
    292     public static final int GROUP_RESERVED = 1000;
    293     public static final int GROUPS_DEFAULT = 0;
    294     public static final int GROUPS_ALT1 = GROUP__MAX;
    295     public static final int GROUPS_ALT2 = GROUP__MAX * 2;
     274    public static final int NONE = 5000;
     275    public static final int MNEMONIC = 5001;
     276    public static final int RESERVED = 5002;
     277    public static final int DIRECT = 5003;
     278    public static final int ALT = 5004;
     279    public static final int SHIFT = 5005;
     280    public static final int CTRL = 5006;
     281    public static final int ALT_SHIFT = 5007;
     282    public static final int ALT_CTRL = 5008;
     283    public static final int CTRL_SHIFT = 5009;
     284    public static final int ALT_CTRL_SHIFT = 5010;
     285
     286    /* for reassignment */
     287    private static int[] mods = {ALT_CTRL, ALT_SHIFT, CTRL_SHIFT, ALT_CTRL_SHIFT};
     288    private static int[] keys = {KeyEvent.VK_F1, KeyEvent.VK_F2, KeyEvent.VK_F3, KeyEvent.VK_F4,
     289                                 KeyEvent.VK_F5, KeyEvent.VK_F6, KeyEvent.VK_F7, KeyEvent.VK_F8,
     290                                 KeyEvent.VK_F9, KeyEvent.VK_F10, KeyEvent.VK_F11, KeyEvent.VK_F12};
     291
     292    /* old */
     293    @Deprecated public static final int GROUP_NONE = 0;
     294    @Deprecated public static final int GROUP_HOTKEY = 1;
     295    @Deprecated public static final int GROUP_MENU = 2;
     296    @Deprecated public static final int GROUP_EDIT = 3;
     297    @Deprecated public static final int GROUP_LAYER = 4;
     298    @Deprecated public static final int GROUP_DIRECT = 5;
     299    @Deprecated public static final int GROUP_MNEMONIC = 6;
     300    @Deprecated public static final int GROUP_DIRECT2 = 7;
     301    @Deprecated public static final int GROUP_DIRECT3 = 8;
     302    @Deprecated public static final int GROUPS_DEFAULT = 0;
     303    @Deprecated public static final int GROUPS_ALT1 = 100;
     304    @Deprecated public static final int GROUPS_ALT2 = 200;
     305    @Deprecated public static final int SHIFT_DEFAULT = 1;
     306    @Deprecated public static Shortcut registerShortcut(String shortText, String longText, int requestedKey, int requestedGroup, int modifier) {
     307        return registerShortcut(shortText, longText, requestedKey, requestedGroup, new Integer(modifier));
     308    }
    296309
    297310    // bootstrap
     
    300313        if (initdone) return;
    301314        initdone = true;
    302         // if we have no modifier groups in the config, we have to create them
    303         if (Main.pref.get("shortcut.groups.configured", null) == null) {
    304             Main.platform.initShortcutGroups();
    305             Main.pref.put("shortcut.groups.configured", true);
    306         }
    307         // pull in the groups
    308         for (int i = GROUP_NONE; i < GROUP__MAX+GROUPS_ALT2*2; i++) { // fill more groups, so registering with e.g. ALT2+MNEMONIC won't NPE
    309             groups.put(i, Main.pref.getInteger("shortcut.groups."+i, -1));
    310         }
     315        groups.put(NONE, -1);
     316        groups.put(MNEMONIC, KeyEvent.ALT_DOWN_MASK);
     317        groups.put(DIRECT, 0);
     318        groups.put(ALT, KeyEvent.ALT_DOWN_MASK);
     319        groups.put(SHIFT, KeyEvent.SHIFT_DOWN_MASK);
     320        groups.put(CTRL, KeyEvent.CTRL_DOWN_MASK);
     321        groups.put(ALT_SHIFT, KeyEvent.ALT_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK);
     322        groups.put(ALT_CTRL, KeyEvent.ALT_DOWN_MASK|KeyEvent.CTRL_DOWN_MASK);
     323        groups.put(CTRL_SHIFT, KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK);
     324        groups.put(ALT_CTRL_SHIFT, KeyEvent.ALT_DOWN_MASK|KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK);
     325
     326        /* old */
     327        groups.put(GROUPS_DEFAULT+GROUP_NONE,    -1);
     328        groups.put(GROUPS_DEFAULT+GROUP_HOTKEY,  KeyEvent.CTRL_DOWN_MASK);
     329        groups.put(GROUPS_DEFAULT+GROUP_MENU,    KeyEvent.CTRL_DOWN_MASK);
     330        groups.put(GROUPS_DEFAULT+GROUP_EDIT,    0);
     331        groups.put(GROUPS_DEFAULT+GROUP_LAYER,   KeyEvent.ALT_DOWN_MASK);
     332        groups.put(GROUPS_DEFAULT+GROUP_DIRECT,  0);
     333        groups.put(GROUPS_DEFAULT+GROUP_MNEMONIC,KeyEvent.ALT_DOWN_MASK);
     334        groups.put(GROUPS_DEFAULT+GROUP_DIRECT2, KeyEvent.ALT_DOWN_MASK);
     335        groups.put(GROUPS_DEFAULT+GROUP_DIRECT3, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK);
     336
     337        groups.put(GROUPS_ALT1+GROUP_NONE,       -1);
     338        groups.put(GROUPS_ALT1+GROUP_HOTKEY,     KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK);
     339        groups.put(GROUPS_ALT1+GROUP_MENU,       KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK);
     340        groups.put(GROUPS_ALT1+GROUP_EDIT,       KeyEvent.SHIFT_DOWN_MASK);
     341        groups.put(GROUPS_ALT1+GROUP_LAYER,      KeyEvent.ALT_DOWN_MASK  | KeyEvent.SHIFT_DOWN_MASK);
     342        groups.put(GROUPS_ALT1+GROUP_DIRECT,     KeyEvent.SHIFT_DOWN_MASK);
     343        groups.put(GROUPS_ALT1+GROUP_MNEMONIC,   KeyEvent.ALT_DOWN_MASK);
     344        groups.put(GROUPS_ALT1+GROUP_DIRECT2,    KeyEvent.ALT_DOWN_MASK  | KeyEvent.SHIFT_DOWN_MASK);
     345        groups.put(GROUPS_ALT1+GROUP_DIRECT3,    KeyEvent.ALT_DOWN_MASK  | KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK);
     346
     347        groups.put(GROUPS_ALT2+GROUP_NONE,       -1);
     348        groups.put(GROUPS_ALT2+GROUP_HOTKEY,     KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK);
     349        groups.put(GROUPS_ALT2+GROUP_MENU,       KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK);
     350        groups.put(GROUPS_ALT2+GROUP_EDIT,       KeyEvent.ALT_DOWN_MASK  | KeyEvent.SHIFT_DOWN_MASK);
     351        groups.put(GROUPS_ALT2+GROUP_LAYER,      KeyEvent.SHIFT_DOWN_MASK);
     352        groups.put(GROUPS_ALT2+GROUP_DIRECT,     KeyEvent.CTRL_DOWN_MASK);
     353        groups.put(GROUPS_ALT2+GROUP_MNEMONIC,   KeyEvent.ALT_DOWN_MASK);
     354        groups.put(GROUPS_ALT2+GROUP_DIRECT2,    KeyEvent.ALT_DOWN_MASK  | KeyEvent.CTRL_DOWN_MASK);
     355        groups.put(GROUPS_ALT2+GROUP_DIRECT3,    KeyEvent.META_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK);
     356
    311357        // (1) System reserved shortcuts
    312358        Main.platform.initSystemShortcuts();
    313359        // (2) User defined shortcuts
    314         int i = 0;
    315         String p = Main.pref.get("shortcut.shortcut."+i, null);
    316         while (p != null) {
    317             Shortcut sc = new Shortcut(p);
    318             if (sc.getAssignedUser()) {
    319                 registerShortcut(sc);
    320             }
    321             i++;
    322             p = Main.pref.get("shortcut.shortcut."+i, null);
     360        LinkedList<Shortcut> newshortcuts = new LinkedList<Shortcut>();
     361        for(String s : Main.pref.getAllPrefixCollectionKeys("shortcut.entry.")) {
     362            newshortcuts.add(new Shortcut(s));
     363        }
     364
     365        for(Shortcut sc : newshortcuts) {
     366            if (sc.getAssignedUser()
     367            && findShortcut(sc.getAssignedKey(), sc.getAssignedModifier()) == null) {
     368                shortcuts.put(sc.getShortText(), sc);
     369            }
    323370        }
    324371        // Shortcuts at their default values
    325         i = 0;
    326         p = Main.pref.get("shortcut.shortcut."+i, null);
    327         while (p != null) {
    328             Shortcut sc = new Shortcut(p);
    329             if (!sc.getAssignedUser() && sc.getAssignedDefault()) {
    330                 registerShortcut(sc);
    331             }
    332             i++;
    333             p = Main.pref.get("shortcut.shortcut."+i, null);
     372        for(Shortcut sc : newshortcuts) {
     373            if (!sc.getAssignedUser() && sc.getAssignedDefault()
     374            && findShortcut(sc.getAssignedKey(), sc.getAssignedModifier()) == null) {
     375                shortcuts.put(sc.getShortText(), sc);
     376            }
    334377        }
    335378        // Shortcuts that were automatically moved
    336         i = 0;
    337         p = Main.pref.get("shortcut.shortcut."+i, null);
    338         while (p != null) {
    339             Shortcut sc = new Shortcut(p);
    340             if (!sc.getAssignedUser() && !sc.getAssignedDefault()) {
    341                 registerShortcut(sc);
    342             }
    343             i++;
    344             p = Main.pref.get("shortcut.shortcut."+i, null);
    345         }
    346     }
     379        for(Shortcut sc : newshortcuts) {
     380            if (!sc.getAssignedUser() && !sc.getAssignedDefault()
     381            && findShortcut(sc.getAssignedKey(), sc.getAssignedModifier()) == null) {
     382                shortcuts.put(sc.getShortText(), sc);
     383            }
     384        }
     385    }
     386
     387    private static int getGroupModifier(int group) {
     388        Integer m = groups.get(group);
     389        if(m == null)
     390            m = -1;
     391        return m;
     392    }
     393
     394    private static int findModifier(int group, Integer modifier) {
     395        Integer defaultModifier = getGroupModifier(group);
     396        if(modifier != null) {
     397            if(modifier == SHIFT_DEFAULT) {
     398                defaultModifier |= KeyEvent.SHIFT_DOWN_MASK;
     399            } else {
     400                defaultModifier = modifier;
     401            }
     402        }
     403        else if (defaultModifier == null) { // garbage in, no shortcut out
     404            defaultModifier = getGroupModifier(NONE);
     405        }
     406        return defaultModifier;
     407    }
     408
     409/*  NEW function:
     410    private static int findModifier(int group, Integer modifier) {
     411        if(modifier == null) {
     412            modifier = getGroupModifier(group);
     413            if (modifier == null) { // garbage in, no shortcut out
     414                modifier = getGroupModifier(NONE);
     415            }
     416        }
     417        return modifier;
     418    }*/
    347419
    348420    // shutdown handling
    349421    public static boolean savePrefs() {
    350         //      we save this directly from the preferences pane, so don't overwrite these values here
    351         //      for (int i = GROUP_NONE; i < GROUP__MAX+GROUPS_ALT2; i++) {
    352         //      Main.pref.put("shortcut.groups."+i, Groups.get(i).toString());
    353         //      }
    354422        boolean changed = false;
    355         int i = 0;
    356423        for (Shortcut sc : shortcuts.values()) {
    357             //          TODO: Remove sc.getAssignedUser() when we fixed all internal conflicts
    358             if (!sc.getAutomatic() && !sc.getReset() && sc.getAssignedUser()) {
    359                 changed = changed | Main.pref.put("shortcut.shortcut."+i, sc.asPrefString());
    360                 i++;
    361             }
    362         }
    363         changed = changed | Main.pref.put("shortcut.shortcut."+i, "");
     424            changed = changed | sc.save();
     425        }
    364426        return changed;
    365     }
    366 
    367     // this is used to register a shortcut that was read from the preferences
    368     private static void registerShortcut(Shortcut sc) {
    369         // put a user configured shortcut in as-is -- unless there's a conflict
    370         if(sc.getAssignedUser() && findShortcut(sc.getAssignedKey(),
    371                 sc.getAssignedModifier()) == null) {
    372             shortcuts.put(sc.getShortText(), sc);
    373         } else {
    374             registerShortcut(sc.getShortText(), sc.getLongText(), sc.getRequestedKey(),
    375                     sc.getRequestedGroup(), sc.getAssignedModifier(), sc);
    376         }
    377427    }
    378428
     
    391441            return null;
    392442        }
    393         potentialShortcut = new Shortcut(shortText, longText, key, GROUP_RESERVED, key, modifier, true, false);
     443        potentialShortcut = new Shortcut(shortText, longText, key, RESERVED, key, modifier, true, false);
    394444        shortcuts.put(shortText, potentialShortcut);
    395445        return potentialShortcut;
     
    409459     * @param requestedKey the key you'd prefer. Use a {@link KeyEvent KeyEvent.VK_*} constant here.
    410460     * @param requestedGroup the group this shortcut fits best. This will determine the
    411      * modifiers your shortcut will get assigned. Use the {@code GROUP_*}
    412      * constants defined above.
    413      * @param modifier to register a {@code ctrl+shift} command, use {@see #SHIFT_DEFAULT}.
    414      */
    415     public static Shortcut registerShortcut(String shortText, String longText, int requestedKey, int requestedGroup, int modifier) {
    416         return registerShortcut(shortText, longText, requestedKey, requestedGroup, modifier, null);
    417     }
    418 
    419     /**
    420      * Register a shortcut.
    421      *
    422      * Here you get your shortcuts from. The parameters are:
    423      *
    424      * @param shortText an ID. re-use a {@code "system:*"} ID if possible, else use something unique.
    425      * {@code "menu:*"} is reserved for menu mnemonics, {@code "core:*"} is reserved for
    426      * actions that are part of JOSM's core. Use something like
    427      * {@code <pluginname>+":"+<actionname>}.
    428      * @param longText this will be displayed in the shortcut preferences dialog. Better
    429      * use something the user will recognize...
    430      * @param requestedKey the key you'd prefer. Use a {@link KeyEvent KeyEvent.VK_*} constant here.
    431      * @param requestedGroup the group this shortcut fits best. This will determine the
    432      * modifiers your shortcut will get assigned. Use the {@code GROUP_*}
    433      * constants defined above.
     461     * modifiers your shortcut will get assigned. Use the constants defined above.
    434462     */
    435463    public static Shortcut registerShortcut(String shortText, String longText, int requestedKey, int requestedGroup) {
    436         return registerShortcut(shortText, longText, requestedKey, requestedGroup, null, null);
    437     }
    438 
    439     // and now the workhorse. same parameters as above, just one more: if originalShortcut is not null and
    440     // is different from the shortcut that will be assigned, a popup warning will be displayed to the user.
    441     // This is used when registering shortcuts that have been visible to the user before (read: have been
    442     // read from the preferences file). New shortcuts will never warn, even when they land on some funny
    443     // random fallback key like Ctrl+Alt+Shift+Z for "File Open..." <g>
    444     private static Shortcut registerShortcut(String shortText, String longText, int requestedKey, int requestedGroup, Integer modifier,
    445             Shortcut originalShortcut) {
     464        return registerShortcut(shortText, longText, requestedKey, requestedGroup, null);
     465    }
     466
     467    // and now the workhorse. same parameters as above, just one more
     468    private static Shortcut registerShortcut(String shortText, String longText, int requestedKey, int requestedGroup, Integer modifier) {
    446469        doInit();
     470        Integer defaultModifier = findModifier(requestedGroup, modifier);
    447471        if (shortcuts.containsKey(shortText)) { // a re-register? maybe a sc already read from the preferences?
    448472            Shortcut sc = shortcuts.get(shortText);
    449473            sc.setLongText(longText); // or set by the platformHook, in this case the original longText doesn't match the real action
     474            sc.saveDefault();
    450475            return sc;
    451476        }
    452         Integer defaultModifier = groups.get(requestedGroup + GROUPS_DEFAULT);
    453         if(modifier != null) {
    454             if(modifier == SHIFT_DEFAULT) {
    455                 defaultModifier |= KeyEvent.SHIFT_DOWN_MASK;
    456             } else {
    457                 defaultModifier = modifier;
    458             }
    459         }
    460         else if (defaultModifier == null) { // garbage in, no shortcut out
    461             defaultModifier = groups.get(GROUP_NONE + GROUPS_DEFAULT);
    462         }
    463         Shortcut conflictsWith = null;
    464         Shortcut potentialShortcut = findShortcut(requestedKey, defaultModifier);
    465         if (potentialShortcut != null) { // 3 stage conflict handling
    466             conflictsWith = potentialShortcut;
    467             defaultModifier = groups.get(requestedGroup + GROUPS_ALT1);
    468             if (defaultModifier == null) { // garbage in, no shortcurt out
    469                 defaultModifier = groups.get(GROUP_NONE + GROUPS_DEFAULT);
    470             }
    471             potentialShortcut = findShortcut(requestedKey, defaultModifier);
    472             if (potentialShortcut != null) {
    473                 defaultModifier = groups.get(requestedGroup + GROUPS_ALT2);
    474                 if (defaultModifier == null) { // garbage in, no shortcurt out
    475                     defaultModifier = groups.get(GROUP_NONE + GROUPS_DEFAULT);
     477        Shortcut conflict = findShortcut(requestedKey, defaultModifier);
     478        if (conflict != null) {
     479            for (int m : mods) {
     480                for (int k : keys) {
     481                    int newmodifier = getGroupModifier(m);
     482                    if ( findShortcut(k, m) == null ) {
     483                        Shortcut newsc = new Shortcut(shortText, longText, requestedKey, m, k, newmodifier, false, false);
     484                        System.out.println(tr("Silent shortcut conflict: ''{0}'' moved by ''{1}'' to ''{2}''.",
     485                            shortText, conflict.getShortText(), newsc.getKeyText()));
     486                        newsc.saveDefault();
     487                        shortcuts.put(shortText, newsc);
     488                        return newsc;
     489                    }
    476490                }
    477                 potentialShortcut = findShortcut(requestedKey, defaultModifier);
    478                 if (potentialShortcut != null) { // if all 3 modifiers for a group are used, we give up
    479                     potentialShortcut = findRandomShortcut(shortText, longText, requestedKey, requestedGroup);
    480                 } else {
    481                     potentialShortcut = new Shortcut(shortText, longText, requestedKey, requestedGroup, requestedKey, defaultModifier, false, false);
    482                 }
    483             } else {
    484                 potentialShortcut = new Shortcut(shortText, longText, requestedKey, requestedGroup, requestedKey, defaultModifier, false, false);
    485             }
    486             if (originalShortcut != null && !originalShortcut.isSame(potentialShortcut)) {
    487                 displayWarning(conflictsWith, potentialShortcut, shortText, longText);
    488             } else if (originalShortcut == null) {
    489                 System.out.println("Silent shortcut conflict: '"+shortText+"' moved by '"+conflictsWith.getShortText()+"' to '"+potentialShortcut.getKeyText()+"'.");
    490491            }
    491492        } else {
    492             potentialShortcut = new Shortcut(shortText, longText, requestedKey, requestedGroup, requestedKey, defaultModifier, true, false);
    493         }
    494 
    495         shortcuts.put(shortText, potentialShortcut);
    496         return potentialShortcut;
    497     }
    498 
    499     // a lengthy warning message
    500     private static void displayWarning(Shortcut conflictsWith, Shortcut potentialShortcut, String shortText, String longText) {
    501         JOptionPane.showMessageDialog(Main.parent,
    502                 tr("Setting the keyboard shortcut ''{0}'' for the action ''{1}'' ({2}) failed\n"+
    503                         "because the shortcut is already taken by the action ''{3}'' ({4}).\n\n",
    504                         conflictsWith.getKeyText(), longText, shortText,
    505                         conflictsWith.getLongText(), conflictsWith.getShortText())+
    506                         (potentialShortcut.getKeyText().equals("") ?
    507                                 tr("This action will have no shortcut.\n\n")
    508                                 :
    509                                     tr("Using the shortcut ''{0}'' instead.\n\n", potentialShortcut.getKeyText())
    510                                 )+
    511                                 tr("(Hint: You can edit the shortcuts in the preferences.)"),
    512                                 tr("Error"),
    513                                 JOptionPane.ERROR_MESSAGE
    514                 );
     493            Shortcut newsc = new Shortcut(shortText, longText, requestedKey, requestedGroup, requestedKey, defaultModifier, true, false);
     494            newsc.saveDefault();
     495            shortcuts.put(shortText, newsc);
     496            return newsc;
     497        }
     498
     499        return null;
    515500    }
    516501
Note: See TracChangeset for help on using the changeset viewer.