diff --git a/src/org/openstreetmap/josm/tools/Shortcut.java b/src/org/openstreetmap/josm/tools/Shortcut.java
index 2448aec..8c212bc 100644
|
a
|
b
|
|
| 6 | 6 | import java.awt.event.KeyEvent; |
| 7 | 7 | import java.util.ArrayList; |
| 8 | 8 | import java.util.Arrays; |
| | 9 | import java.util.Collections; |
| 9 | 10 | import java.util.HashMap; |
| 10 | | import java.util.LinkedHashMap; |
| 11 | 11 | import java.util.LinkedList; |
| 12 | 12 | import java.util.List; |
| 13 | 13 | import java.util.Map; |
| | 14 | import java.util.Optional; |
| | 15 | import java.util.concurrent.CopyOnWriteArrayList; |
| 14 | 16 | |
| 15 | 17 | import javax.swing.AbstractAction; |
| 16 | 18 | import javax.swing.AbstractButton; |
| … |
… |
public String toString() {
|
| 267 | 269 | /////////////////////////////// |
| 268 | 270 | |
| 269 | 271 | // here we store our shortcuts |
| 270 | | private static Map<String, Shortcut> shortcuts = new LinkedHashMap<>(); |
| | 272 | private static List<Shortcut> shortcuts = new CopyOnWriteArrayList<>(); |
| 271 | 273 | |
| 272 | 274 | // and here our modifier groups |
| 273 | 275 | private static Map<Integer, Integer> groups = new HashMap<>(); |
| 274 | 276 | |
| 275 | 277 | // check if something collides with an existing shortcut |
| | 278 | |
| | 279 | /** |
| | 280 | * Returns the registered shortcut fot the key and modifier |
| | 281 | * @param requestedKey the requested key |
| | 282 | * @param modifier the modifier |
| | 283 | * @return the registered shortcut or {@code null} |
| | 284 | */ |
| 276 | 285 | public static Shortcut findShortcut(int requestedKey, int modifier) { |
| | 286 | return findShortcutByKeyOrShortText(requestedKey, modifier, null) |
| | 287 | .orElse(null); |
| | 288 | } |
| | 289 | |
| | 290 | private static Optional<Shortcut> findShortcutByKeyOrShortText(int requestedKey, int modifier, String shortText) { |
| 277 | 291 | if (modifier == getGroupModifier(NONE)) |
| 278 | | return null; |
| 279 | | for (Shortcut sc : shortcuts.values()) { |
| 280 | | if (sc.isSame(requestedKey, modifier)) |
| 281 | | return sc; |
| 282 | | } |
| 283 | | return null; |
| | 292 | return Optional.empty(); |
| | 293 | return shortcuts.stream() |
| | 294 | .filter(sc -> sc.isSame(requestedKey, modifier) || (shortText != null && shortText.equals(sc.getShortText()))) |
| | 295 | .findAny(); |
| | 296 | |
| 284 | 297 | } |
| 285 | 298 | |
| 286 | 299 | /** |
| … |
… |
public static Shortcut findShortcut(int requestedKey, int modifier) {
|
| 288 | 301 | * @return a list of all shortcuts |
| 289 | 302 | */ |
| 290 | 303 | public static List<Shortcut> listAll() { |
| 291 | | List<Shortcut> l = new ArrayList<>(); |
| 292 | | for (Shortcut c : shortcuts.values()) { |
| 293 | | if (!"core:none".equals(c.shortText)) { |
| 294 | | l.add(c); |
| 295 | | } |
| 296 | | } |
| 297 | | return l; |
| | 304 | return Collections.unmodifiableList(shortcuts); |
| 298 | 305 | } |
| 299 | 306 | |
| 300 | 307 | /** None group: used with KeyEvent.CHAR_UNDEFINED if no shortcut is defined */ |
| … |
… |
private static void doInit() {
|
| 353 | 360 | for (Shortcut sc : newshortcuts) { |
| 354 | 361 | if (sc.isAssignedUser() |
| 355 | 362 | && findShortcut(sc.getAssignedKey(), sc.getAssignedModifier()) == null) { |
| 356 | | shortcuts.put(sc.getShortText(), sc); |
| | 363 | shortcuts.add(sc); |
| 357 | 364 | } |
| 358 | 365 | } |
| 359 | 366 | // Shortcuts at their default values |
| 360 | 367 | for (Shortcut sc : newshortcuts) { |
| 361 | 368 | if (!sc.isAssignedUser() && sc.isAssignedDefault() |
| 362 | 369 | && findShortcut(sc.getAssignedKey(), sc.getAssignedModifier()) == null) { |
| 363 | | shortcuts.put(sc.getShortText(), sc); |
| | 370 | shortcuts.add(sc); |
| 364 | 371 | } |
| 365 | 372 | } |
| 366 | 373 | // Shortcuts that were automatically moved |
| 367 | 374 | for (Shortcut sc : newshortcuts) { |
| 368 | 375 | if (!sc.isAssignedUser() && !sc.isAssignedDefault() |
| 369 | 376 | && findShortcut(sc.getAssignedKey(), sc.getAssignedModifier()) == null) { |
| 370 | | shortcuts.put(sc.getShortText(), sc); |
| | 377 | shortcuts.add(sc); |
| 371 | 378 | } |
| 372 | 379 | } |
| 373 | 380 | } |
| … |
… |
private static int findModifier(int group, Integer modifier) {
|
| 392 | 399 | // shutdown handling |
| 393 | 400 | public static boolean savePrefs() { |
| 394 | 401 | boolean changed = false; |
| 395 | | for (Shortcut sc : shortcuts.values()) { |
| | 402 | for (Shortcut sc : shortcuts) { |
| 396 | 403 | changed = changed | sc.save(); |
| 397 | 404 | } |
| 398 | 405 | return changed; |
| … |
… |
public static boolean savePrefs() {
|
| 410 | 417 | * @return the system shortcut |
| 411 | 418 | */ |
| 412 | 419 | public static Shortcut registerSystemShortcut(String shortText, String longText, int key, int modifier) { |
| 413 | | if (shortcuts.containsKey(shortText)) |
| 414 | | return shortcuts.get(shortText); |
| 415 | | Shortcut potentialShortcut = findShortcut(key, modifier); |
| 416 | | if (potentialShortcut != null) { |
| | 420 | final Optional<Shortcut> existing = findShortcutByKeyOrShortText(key, modifier, shortText); |
| | 421 | if (existing.isPresent() && shortText.equals(existing.get().getShortText())) { |
| | 422 | return existing.get(); |
| | 423 | } else if (existing.isPresent()) { |
| 417 | 424 | // this always is a logic error in the hook |
| 418 | | Main.error("CONFLICT WITH SYSTEM KEY "+shortText+": "+potentialShortcut); |
| | 425 | Main.error("CONFLICT WITH SYSTEM KEY " + shortText + ": " + existing.get()); |
| 419 | 426 | return null; |
| 420 | 427 | } |
| 421 | | potentialShortcut = new Shortcut(shortText, longText, key, RESERVED, key, modifier, true, false); |
| 422 | | shortcuts.put(shortText, potentialShortcut); |
| 423 | | return potentialShortcut; |
| | 428 | final Shortcut shortcut = new Shortcut(shortText, longText, key, RESERVED, key, modifier, true, false); |
| | 429 | shortcuts.add(shortcut); |
| | 430 | return shortcut; |
| 424 | 431 | } |
| 425 | 432 | |
| 426 | 433 | /** |
| … |
… |
public static Shortcut registerShortcut(String shortText, String longText, int r
|
| 446 | 453 | // and now the workhorse. same parameters as above, just one more |
| 447 | 454 | private static Shortcut registerShortcut(String shortText, String longText, int requestedKey, int requestedGroup, Integer modifier) { |
| 448 | 455 | doInit(); |
| 449 | | if (shortcuts.containsKey(shortText)) { // a re-register? maybe a sc already read from the preferences? |
| 450 | | Shortcut sc = shortcuts.get(shortText); |
| | 456 | Integer defaultModifier = findModifier(requestedGroup, modifier); |
| | 457 | final Optional<Shortcut> existing = findShortcutByKeyOrShortText(requestedKey, defaultModifier, shortText); |
| | 458 | if (existing.isPresent() && shortText.equals(existing.get().getShortText())) { |
| | 459 | // a re-register? maybe a sc already read from the preferences? |
| | 460 | final Shortcut sc = existing.get(); |
| 451 | 461 | sc.setLongText(longText); // or set by the platformHook, in this case the original longText doesn't match the real action |
| 452 | 462 | sc.saveDefault(); |
| 453 | 463 | return sc; |
| 454 | | } |
| 455 | | Integer defaultModifier = findModifier(requestedGroup, modifier); |
| 456 | | Shortcut conflict = findShortcut(requestedKey, defaultModifier); |
| 457 | | if (conflict != null) { |
| | 464 | } else if (existing.isPresent()) { |
| | 465 | final Shortcut conflict = existing.get(); |
| 458 | 466 | if (Main.isPlatformOsx()) { |
| 459 | 467 | // Try to reassign Meta to Ctrl |
| 460 | 468 | int newmodifier = findNewOsxModifier(requestedGroup); |
| … |
… |
private static Shortcut registerShortcut(String shortText, String longText, int
|
| 476 | 484 | } else { |
| 477 | 485 | Shortcut newsc = new Shortcut(shortText, longText, requestedKey, requestedGroup, requestedKey, defaultModifier, true, false); |
| 478 | 486 | newsc.saveDefault(); |
| 479 | | shortcuts.put(shortText, newsc); |
| | 487 | shortcuts.add(newsc); |
| 480 | 488 | return newsc; |
| 481 | 489 | } |
| 482 | 490 | |
| … |
… |
private static Shortcut reassignShortcut(String shortText, String longText, int
|
| 499 | 507 | Main.info(tr("Silent shortcut conflict: ''{0}'' moved by ''{1}'' to ''{2}''.", |
| 500 | 508 | shortText, conflict.getShortText(), newsc.getKeyText())); |
| 501 | 509 | newsc.saveDefault(); |
| 502 | | shortcuts.put(shortText, newsc); |
| | 510 | shortcuts.replaceAll(sc -> shortText.equals(sc.getShortText()) ? newsc : sc); |
| 503 | 511 | return newsc; |
| 504 | 512 | } |
| 505 | 513 | |
| … |
… |
private static Shortcut reassignShortcut(String shortText, String longText, int
|
| 511 | 519 | * @return the platform specific key stroke for the 'Copy' command |
| 512 | 520 | */ |
| 513 | 521 | public static KeyStroke getCopyKeyStroke() { |
| 514 | | Shortcut sc = shortcuts.get("system:copy"); |
| 515 | | if (sc == null) return null; |
| 516 | | return sc.getKeyStroke(); |
| | 522 | return getKeyStrokeForShortKey("system:copy"); |
| 517 | 523 | } |
| 518 | 524 | |
| 519 | 525 | /** |
| … |
… |
public static KeyStroke getCopyKeyStroke() {
|
| 524 | 530 | * @return the platform specific key stroke for the 'Paste' command |
| 525 | 531 | */ |
| 526 | 532 | public static KeyStroke getPasteKeyStroke() { |
| 527 | | Shortcut sc = shortcuts.get("system:paste"); |
| 528 | | if (sc == null) return null; |
| 529 | | return sc.getKeyStroke(); |
| | 533 | return getKeyStrokeForShortKey("system:paste"); |
| 530 | 534 | } |
| 531 | 535 | |
| 532 | 536 | /** |
| … |
… |
public static KeyStroke getPasteKeyStroke() {
|
| 537 | 541 | * @return the platform specific key stroke for the 'Cut' command |
| 538 | 542 | */ |
| 539 | 543 | public static KeyStroke getCutKeyStroke() { |
| 540 | | Shortcut sc = shortcuts.get("system:cut"); |
| 541 | | if (sc == null) return null; |
| 542 | | return sc.getKeyStroke(); |
| | 544 | return getKeyStrokeForShortKey("system:cut"); |
| | 545 | } |
| | 546 | |
| | 547 | private static KeyStroke getKeyStrokeForShortKey(String shortKey) { |
| | 548 | return shortcuts.stream() |
| | 549 | .filter(sc -> shortKey.equals(sc.getShortText())) |
| | 550 | .findAny() |
| | 551 | .map(Shortcut::getKeyStroke) |
| | 552 | .orElse(null); |
| 543 | 553 | } |
| 544 | 554 | } |