Removes all mnemonics, then sets a mnemonic for each menu and menu item recursively by these rules: It tries to assign one of KDE's defaults . Failing that, it loops through the first letter of eac
(JMenuItem... menu)
| 285 | * A menu, a list of menus or an array of menu items to set mnemonics for. |
| 286 | */ |
| 287 | static public void setMenuMnemonics(JMenuItem... menu) { |
| 288 | if (Platform.isMacOS()) return; |
| 289 | if (menu.length == 0) return; |
| 290 | |
| 291 | // The English is http://techbase.kde.org/Projects/Usability/HIG/Keyboard_Accelerators, |
| 292 | // made lowercase. |
| 293 | // Nothing but [a-z] except for '&' before mnemonics and regexes for changable text. |
| 294 | final String[] kdePreDefStrs = { "&file", "&new", "&open", "open&recent", |
| 295 | "&save", "save&as", "saveacop&y", "saveas&template", "savea&ll", "reloa&d", |
| 296 | "&print", "printpre&view", "&import", "e&xport", "&closefile", |
| 297 | "clos&eallfiles", "&quit", "&edit", "&undo", "re&do", "cu&t", "©", |
| 298 | "&paste", "&delete", "select&all", "dese&lect", "&find", "find&next", |
| 299 | "findpre&vious", "&replace", "&gotoline", "&view", "&newview", |
| 300 | "close&allviews", "&splitview", "&removeview", "splitter&orientation", |
| 301 | "&horizontal", "&vertical", "view&mode", "&fullscreenmode", "&zoom", |
| 302 | "zoom&in", "zoom&out", "zoomtopage&width", "zoomwhole&page", "zoom&factor", |
| 303 | "&insert", "&format", "&go", "&up", "&back", "&forward", "&home", "&go", |
| 304 | "&previouspage", "&nextpage", "&firstpage", "&lastpage", "read&updocument", |
| 305 | "read&downdocument", "&back", "&forward", "&gotopage", "&bookmarks", |
| 306 | "&addbookmark", "bookmark&tabsasfolder", "&editbookmarks", |
| 307 | "&newbookmarksfolder", "&tools", "&settings", "&toolbars", |
| 308 | "configure&shortcuts", "configuretool&bars", "&configure.*", "&help", |
| 309 | ".+&handbook", "&whatsthis", "report&bug", "&aboutprocessing", "about&kde", |
| 310 | "&beenden", "&suchen", // de |
| 311 | "&preferncias", "&sair", // Preferências; pt |
| 312 | "&rechercher" }; // fr |
| 313 | Pattern[] kdePreDefPats = new Pattern[kdePreDefStrs.length]; |
| 314 | for (int i = 0; i < kdePreDefStrs.length; i++) { |
| 315 | kdePreDefPats[i] = Pattern.compile(kdePreDefStrs[i].replace("&","")); |
| 316 | } |
| 317 | |
| 318 | final Pattern nonAAlpha = Pattern.compile("[^A-Za-z]"); |
| 319 | FontMetrics fmTmp = null; |
| 320 | for (JMenuItem m : menu) { |
| 321 | if (m != null) { |
| 322 | fmTmp = m.getFontMetrics(m.getFont()); |
| 323 | break; |
| 324 | } |
| 325 | } |
| 326 | if (fmTmp == null) return; // All null menuitems; would fail. |
| 327 | final FontMetrics fm = fmTmp; // Hack for accessing variable in comparator. |
| 328 | |
| 329 | final Comparator<Character> charComparator = new Comparator<Character>() { |
| 330 | char[] baddies = "qypgjaeiouQAEIOU".toCharArray(); |
| 331 | public int compare(Character ch1, Character ch2) { |
| 332 | // Discriminates against descenders for readability, per MS |
| 333 | // Human Interface Guide, and vowels per MS and Gnome. |
| 334 | float w1 = fm.charWidth(ch1), w2 = fm.charWidth(ch2); |
| 335 | for (char bad : baddies) { |
| 336 | if (bad == ch1) w1 *= 0.66f; |
| 337 | if (bad == ch2) w2 *= 0.66f; |
| 338 | } |
| 339 | return (int)Math.signum(w2 - w1); |
| 340 | } |
| 341 | }; |
| 342 | |
| 343 | // Holds only [0-9a-z], not uppercase. |
| 344 | // Prevents X != x, so "Save" and "Save As" aren't both given 'a'. |
no test coverage detected