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/lyx_gui.h"
25 #include "support/lstrings.h"
29 #include "QLyXKeySym.h"
30 extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
33 #include <qapplication.h>
48 docstring const getLabel(MenuItem const & mi)
50 docstring const shortcut = mi.shortcut();
51 docstring label = subst(mi.label(),
53 lyx::from_ascii("&&"));
55 if (!shortcut.empty()) {
56 docstring::size_type pos = label.find(shortcut);
57 if (pos != docstring::npos)
58 label.insert(pos, 1, char_type('&'));
65 // The offset added to the special Mac menu entries
66 const int indexOffset = 5000;
72 pair<int, QLPopupMenu *>
73 createMenu(QMenuData * parent, MenuItem const * item, QLMenubar * owner,
76 QLPopupMenu * pm = new QLPopupMenu(owner, item->submenuname(), is_toplevel);
77 int const id = parent->insertItem(toqstr(getLabel(*item)), pm);
78 return make_pair(id, pm);
82 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
83 docstring const & name, bool toplevel)
84 : owner_(owner), name_(name)
87 connect(this, SIGNAL(aboutToShow()), this, SLOT(showing()));
88 connect(this, SIGNAL(activated(int)),
89 this, SLOT(fire(int)));
93 void QLPopupMenu::fire(int index)
95 // make sure the interface is repainted correctly (in case the
96 // action needs a long time, like File>Open).
97 lyx_gui::sync_events();
99 if (index >= indexOffset) {
100 MenuItem mi = owner_->backend().getMenu("LyX")[index - indexOffset];
101 owner_->view()->activated(mi.func());
104 owner_->view()->activated(funcs_[index]);
108 void QLPopupMenu::populate(Menu * menu)
112 Menu::const_iterator m = menu->begin();
113 Menu::const_iterator end = menu->end();
114 for (; m != end; ++m) {
115 if (m->kind() == MenuItem::Separator) {
117 } else if (m->kind() == MenuItem::Submenu) {
118 pair<int, QLPopupMenu *> res = createMenu(this, &(*m), owner_);
119 setItemEnabled(res.first, m->status().enabled());
120 res.second->populate(m->submenu());
121 } else { // we have a MenuItem::Command
122 FuncStatus status = m->status();
124 Funcs::iterator fit =
125 funcs_.insert(funcs_.end(), m->func());
126 int const index = distance(funcs_.begin(), fit);
128 QString label = toqstr(getLabel(*m));
130 /* There are two constraints on Qt/Mac: (1)
131 the bindings require a unicode string to be
132 represented meaningfully and std::string
133 does not work (2) only 1-key bindings can
134 be represented in menus.
136 This is why the unpleasant hack bellow is
139 pair<LyXKeySym const *, key_modifier::state>
140 binding = toplevel_keymap->find1keybinding(m->func());
142 QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
143 label += '\t' + key->qprint(binding.second);
146 docstring const binding(m->binding());
147 if (!binding.empty()) {
148 label += char_type('\t') + toqstr(binding);
152 // Actually insert the menu item
153 insertItem(label, index);
154 setItemEnabled(index, status.enabled());
155 setItemChecked(index, status.onoff(true));
161 void QLPopupMenu::showing()
165 Menu const frommenu = owner_->backend().getMenu(name_);
166 owner_->backend().expand(frommenu, tomenu, owner_->view());
169 /* The qt/mac menu code has a very silly hack that
170 moves some menu entries that it recognizes by name
171 (e.g. "Preferences...") to the "LyX" menu. This
172 feature can only work if the menu entries are
173 always available. Since we build menus on demand,
174 we add some dummy contents to one of the menus (JMarc)
176 static QLPopupMenu * themenu = this;
177 if (themenu == this && owner_->backend().hasMenu("LyX")) {
178 Menu special = owner_->backend().getMenu("LyX");
179 Menu::const_iterator end = special.end();
180 Menu::size_type i = 0;
181 for (Menu::const_iterator cit = special.begin();
182 cit != end ; ++cit, ++i)
183 insertItem(toqstr(cit->label()), indexOffset + i);
188 } // namespace frontend
191 #include "QLPopupMenu_moc.cpp"