3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
13 // Qt defines a macro 'signals' that clashes with a boost namespace.
14 // All is well if the namespace is visible first.
17 #include "QLPopupMenu.h"
18 #include "QLMenubar.h"
19 #include "qt_helpers.h"
21 #include "MenuBackend.h"
23 #include "frontends/Application.h"
25 #include "support/lstrings.h"
29 #include "QLyXKeySym.h"
32 #include <qapplication.h>
47 docstring const getLabel(MenuItem const & mi)
49 docstring const shortcut = mi.shortcut();
50 docstring label = subst(mi.label(),
52 lyx::from_ascii("&&"));
54 if (!shortcut.empty()) {
55 docstring::size_type pos = label.find(shortcut);
56 if (pos != docstring::npos)
57 label.insert(pos, 1, char_type('&'));
64 // The offset added to the special Mac menu entries
65 const int indexOffset = 5000;
71 pair<int, QLPopupMenu *>
72 createMenu(QMenuData * parent, MenuItem const * item, QLMenubar * owner,
75 QLPopupMenu * pm = new QLPopupMenu(owner, item->submenuname(), is_toplevel);
76 int const id = parent->insertItem(toqstr(getLabel(*item)), pm);
77 return make_pair(id, pm);
81 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
82 docstring const & name, bool toplevel)
83 : owner_(owner), name_(name)
86 connect(this, SIGNAL(aboutToShow()), this, SLOT(showing()));
87 connect(this, SIGNAL(activated(int)),
88 this, SLOT(fire(int)));
92 void QLPopupMenu::fire(int index)
94 // make sure the interface is repainted correctly (in case the
95 // action needs a long time, like File>Open).
98 if (index >= indexOffset) {
99 MenuItem mi = owner_->backend().getMenu("LyX")[index - indexOffset];
100 owner_->view()->activated(mi.func());
103 owner_->view()->activated(funcs_[index]);
107 void QLPopupMenu::populate(Menu * menu)
111 Menu::const_iterator m = menu->begin();
112 Menu::const_iterator end = menu->end();
113 for (; m != end; ++m) {
114 if (m->kind() == MenuItem::Separator) {
116 } else if (m->kind() == MenuItem::Submenu) {
117 pair<int, QLPopupMenu *> res = createMenu(this, &(*m), owner_);
118 setItemEnabled(res.first, m->status().enabled());
119 res.second->populate(m->submenu());
120 } else { // we have a MenuItem::Command
121 FuncStatus status = m->status();
123 Funcs::iterator fit =
124 funcs_.insert(funcs_.end(), m->func());
125 int const index = distance(funcs_.begin(), fit);
127 QString label = toqstr(getLabel(*m));
129 /* There are two constraints on Qt/Mac: (1)
130 the bindings require a unicode string to be
131 represented meaningfully and std::string
132 does not work (2) only 1-key bindings can
133 be represented in menus.
135 This is why the unpleasant hack bellow is
138 pair<LyXKeySym const *, key_modifier::state>
139 binding = theTopLevelKeymap().find1keybinding(m->func());
141 QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
142 label += '\t' + key->qprint(binding.second);
145 docstring const binding(m->binding());
146 if (!binding.empty()) {
147 label += '\t' + toqstr(binding);
151 // Actually insert the menu item
152 insertItem(label, index);
153 setItemEnabled(index, status.enabled());
154 setItemChecked(index, status.onoff(true));
160 void QLPopupMenu::showing()
164 Menu const frommenu = owner_->backend().getMenu(name_);
165 owner_->backend().expand(frommenu, tomenu, owner_->view()->buffer());
168 /* The qt/mac menu code has a very silly hack that
169 moves some menu entries that it recognizes by name
170 (e.g. "Preferences...") to the "LyX" menu. This
171 feature can only work if the menu entries are
172 always available. Since we build menus on demand,
173 we add some dummy contents to one of the menus (JMarc)
175 static QLPopupMenu * themenu = this;
176 if (themenu == this && owner_->backend().hasMenu("LyX")) {
177 Menu special = owner_->backend().getMenu("LyX");
178 Menu::const_iterator end = special.end();
179 Menu::size_type i = 0;
180 for (Menu::const_iterator cit = special.begin();
181 cit != end ; ++cit, ++i)
182 insertItem(toqstr(cit->label()), indexOffset + i);
187 } // namespace frontend
190 #include "QLPopupMenu_moc.cpp"