3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Abdelrazak Younes
9 * Full author contact details are available in file CREDITS.
14 #include <boost/current_function.hpp>
16 // Qt defines a macro 'signals' that clashes with a boost namespace.
17 // All is well if the namespace is visible first.
21 #include "QLPopupMenu.h"
22 #include "QLMenubar.h"
23 #include "qt_helpers.h"
24 #include "MenuBackend.h"
26 #include "frontends/lyx_gui.h"
27 #include "support/lstrings.h"
33 #include "QLyXKeySym.h"
34 extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
51 // MacOSX specific stuff is at the end.
53 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
54 MenuItem const & mi, bool topLevelMenu)
57 name_ = mi.submenuname();
59 setTitle(toqstr(getLabel(mi)));
62 connect(this, SIGNAL(aboutToShow()), this, SLOT(update()));
67 void QLPopupMenu::update()
69 lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << endl;
70 lyxerr[Debug::GUI] << "\tTriggered menu: " << name_ << endl;
77 Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
78 owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view());
80 if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
81 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << topLevelMenu_.name() << endl;
83 populate(this, &topLevelMenu_);
85 specialMacXmenuHack();
88 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
90 lyxerr[Debug::GUI] << "populating menu " << menu->name() ;
91 if (menu->size() == 0) {
92 lyxerr[Debug::GUI] << "\tERROR: empty menu " << menu->name() << endl;
96 lyxerr[Debug::GUI] << " ***** menu entries " << menu->size() << endl;
99 Menu::const_iterator m = menu->begin();
100 Menu::const_iterator end = menu->end();
102 for (; m != end; ++m) {
104 if (m->kind() == MenuItem::Separator) {
106 qMenu->addSeparator();
107 lyxerr[Debug::GUI] << "adding Menubar Separator" << endl;
109 } else if (m->kind() == MenuItem::Submenu) {
111 lyxerr[Debug::GUI] << "** creating New Sub-Menu " << getLabel(*m) << endl;
112 QMenu * subMenu = qMenu->addMenu(toqstr(getLabel(*m)));
113 populate(subMenu, m->submenu());
115 } else { // we have a MenuItem::Command
117 lyxerr[Debug::GUI] << "creating Menu Item " << m->label() << endl;
119 string label = getLabel(*m);
120 addBinding(label, *m);
122 Action * action = new Action(*(owner_->view()),
124 qMenu->addAction(action);
129 string const QLPopupMenu::getLabel(MenuItem const & mi)
131 string const shortcut = mi.shortcut();
132 string label = support::subst(mi.label(), "&", "&&");
134 if (!shortcut.empty()) {
135 string::size_type pos = label.find(shortcut);
136 if (pos != string::npos)
137 label.insert(pos, 1, '&');
143 /// \todo Mac specific binding handling.
144 void QLPopupMenu::addBinding(string & label, MenuItem const & mi)
148 string const binding(mi.binding());
149 if (!binding.empty()) {
150 label += '\t' + binding;
154 /* There are two constraints on Qt/Mac: (1)
155 the bindings require a unicode string to be
156 represented meaningfully and std::string
157 does not work (2) only 1-key bindings can
158 be represented in menus.
160 This is why the unpleasant hack bellow is
163 /* pair<LyXKeySym const *, key_modifier::state>
164 binding = toplevel_keymap->find1keybinding(mi.func());
166 QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
167 label += '\t' + key->qprint(binding.second);
173 /// \todo Fix Mac specific menu hack
174 void QLPopupMenu::specialMacXmenuHack()
177 /* The qt/mac menu code has a very silly hack that
178 moves some menu entries that it recognizes by name
179 (e.g. "Preferences...") to the "LyX" menu. This
180 feature can only work if the menu entries are
181 always available. Since we build menus on demand,
182 we add some dummy contents to one of the menus (JMarc)
185 static QLPopupMenu * themenu = this;
186 if (themenu == this && owner_->backend().hasMenu("LyX")) {
187 Menu special = owner_->backend().getMenu("LyX");
188 Menu::const_iterator end = special.end();
189 Menu::size_type i = 0;
190 for (Menu::const_iterator cit = special.begin();
191 cit != end ; ++cit, ++i)
192 insertItem(toqstr(cit->label()), indexOffset + i);
198 } // namespace frontend
201 #include "QLPopupMenu_moc.cpp"