Am Mittwoch, dem 03.04.2024 um 16:40 +0200 schrieb Jürgen Spitzmüller:
> 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.
And here with a context menu change to try out.
E.g., right-click in the User's Guide on the index subentry in section
heading 1.1 ("Graphics Dialog [Figures > Graphics Dialog]").
This is the one conflicting and hardly resolvable case I am aware of.
It now just takes the other possible accelerator (f rather than c) and
all is well.
--
Jürgen
diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc
index dc49f44c77..32d76e603e 100644
--- a/lib/ui/stdcontext.inc
+++ b/lib/ui/stdcontext.inc
@@ -650,7 +650,7 @@ Menuset
Menu "context-edit-index"
OptItem "Insert Subentry|n" "indexmacro-insert subentry"
OptItem "Insert Sortkey|k" "indexmacro-insert sortkey"
- OptItem "Insert See Reference|c" "indexmacro-insert see"
+ OptItem "Insert See Reference|cf" "indexmacro-insert see"
OptItem "Insert See also Reference|a" "indexmacro-insert seealso"
End
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
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-devel