Am Mittwoch, dem 03.04.2024 um 11:41 +0200 schrieb Jürgen Spitzmüller: > What could be a more clever (?) option, I think, is the possibility > to assign shortcut alternatives, as in "Text actions|Txct", and LyX > checks the characters in turn until one is free.
As in the attached. -- Jürgen
diff --git a/src/frontends/qt/Menus.cpp b/src/frontends/qt/Menus.cpp index 4a09a1b4a7..3704051288 100644 --- a/src/frontends/qt/Menus.cpp +++ b/src/frontends/qt/Menus.cpp @@ -233,10 +233,17 @@ public: } /// The keyboard shortcut (usually underlined in the entry) - QString shortcut() const + QString shortcut(bool first = false) const { int const index = label_.lastIndexOf('|'); - return index == -1 ? QString() : label_.mid(index + 1); + if (index == -1) + return QString(); + QString accelerators = label_.mid(index + 1); + if (accelerators.size() == 1) + return accelerators; + if (first) + return accelerators.left(1); + return accelerators; } /// The complete label, with label and shortcut separated by a '|' QString fulllabel() const { return label_; } @@ -349,8 +356,12 @@ public: /// Checks the associated FuncRequest status before adding the /// menu item. void addWithStatusCheck(MenuItem const &); - // Check whether the menu shortcuts are unique - void checkShortcuts() const; + /// Check whether the menu shortcuts are unique + void checkShortcutUnique(QString const sc) const; + /// Check a given menu shortcuts is unique + bool checkShortcut(QString const sc) const; + /// Try to find a unique shortcut from a string of alternatives + QString getBestShortcut(MenuItem const & mi) const; /// void expandLastfiles(); void expandDocuments(); @@ -760,13 +771,33 @@ void MenuDefinition::cat(MenuDefinition const & other) } -void MenuDefinition::checkShortcuts() const +QString MenuDefinition::getBestShortcut(MenuItem const & mi) const +{ + QString accelerators = mi.shortcut(); + if (accelerators.size() <= 1) { + checkShortcutUnique(accelerators); + return accelerators; + } + for (int i = 0; i < accelerators.length(); i++) + { + QString const sc = accelerators.at(i); + if (checkShortcut(sc)) + return sc; + } + LYXERR0("Menu warning: All accelerators of menu entry " + << '"' << mi.fulllabel() + << "\" are already taken. Omitting shortcut."); + return QString(); +} + + +void MenuDefinition::checkShortcutUnique(QString const sc) const { // This is a quadratic algorithm, but we do not care because // menus are short enough for (const_iterator it1 = begin(); it1 != end(); ++it1) { - QString shortcut = it1->shortcut(); - if (shortcut.isEmpty()) + QString shortcut = it1->shortcut(true); + if (shortcut != sc) continue; if (!it1->label().contains(shortcut)) LYXERR0("Menu warning: menu entry \"" @@ -785,6 +816,19 @@ void MenuDefinition::checkShortcuts() const } +bool MenuDefinition::checkShortcut(QString const shortcut) const +{ + if (shortcut.isEmpty()) + return true; + for (const_iterator it = begin(); it != end(); ++it) { + if (it->shortcut(true).compare(shortcut, Qt::CaseInsensitive) == 0) { + return false; + } + } + return true; +} + + bool MenuDefinition::searchMenu(FuncRequest const & func, docstring_list & names) const { const_iterator m = begin(); @@ -2116,12 +2160,12 @@ struct Menu::Impl /// Get a MenuDefinition item label from the menu backend -static QString label(MenuItem const & mi) +static QString label(MenuItem const & mi, MenuDefinition const & menu) { QString label = mi.label(); label.replace("&", "&&"); - QString shortcut = mi.shortcut(); + QString shortcut = menu.getBestShortcut(mi); if (!shortcut.isEmpty()) { int pos = label.indexOf(shortcut); if (pos != -1) @@ -2158,7 +2202,7 @@ void Menu::Impl::populate(QMenu * qMenu, MenuDefinition const & menu) qMenu->addSeparator(); break; case MenuItem::Submenu: { - QMenu * subMenu = qMenu->addMenu(label(m)); + QMenu * subMenu = qMenu->addMenu(label(m, menu)); populate(subMenu, m.submenu()); subMenu->setEnabled(!subMenu->isEmpty()); break; @@ -2168,7 +2212,7 @@ void Menu::Impl::populate(QMenu * qMenu, MenuDefinition const & menu) // FIXME: A previous comment assured that MenuItem::Command was the // only possible case in practice, but this is wrong. It would be // good to document which cases are actually treated here. - qMenu->addAction(new Action(m.func(), QIcon(), label(m), + qMenu->addAction(new Action(m.func(), QIcon(), label(m, menu), m.tooltip(), qMenu)); break; } @@ -2529,9 +2573,6 @@ void Menus::Impl::expand(MenuDefinition const & frommenu, // we do not want the menu to end with a separator if (!tomenu.empty() && tomenu.items_.back().kind() == MenuItem::Separator) tomenu.items_.pop_back(); - - // Check whether the shortcuts are unique - tomenu.checkShortcuts(); } @@ -2700,7 +2741,7 @@ void Menus::fillMenuBar(QMenuBar * qmb, GuiView * view, bool initial) } Menu * menuptr = new Menu(view, m.submenuname(), true); - menuptr->setTitle(label(m)); + menuptr->setTitle(label(m, menu)); #if defined(Q_OS_MAC) // On Mac OS with Qt/Cocoa, the menu is not displayed if there is no action
-- lyx-devel mailing list lyx-devel@lists.lyx.org http://lists.lyx.org/mailman/listinfo/lyx-devel