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: " << lyx::to_utf8(name_) << endl;
77 Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
78 owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view()->buffer());
80 if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
81 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << lyx::to_utf8(topLevelMenu_.name()) << endl;
83 populate(this, &topLevelMenu_);
85 specialMacXmenuHack();
88 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
90 lyxerr[Debug::GUI] << "populating menu " << lyx::to_utf8(menu->name()) ;
91 if (menu->size() == 0) {
92 lyxerr[Debug::GUI] << "\tERROR: empty menu " << lyx::to_utf8(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 " << lyx::to_utf8(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 " << lyx::to_utf8(m->label()) << endl;
119 docstring label = getLabel(*m);
120 addBinding(label, *m);
122 Action * action = new Action(*(owner_->view()),
123 lyx::to_utf8(label), m->func());
124 qMenu->addAction(action);
129 docstring const QLPopupMenu::getLabel(MenuItem const & mi)
131 docstring const shortcut = mi.shortcut();
132 docstring label = support::subst(mi.label(),
133 lyx::from_ascii("&"),
134 lyx::from_ascii("&&"));
136 if (!shortcut.empty()) {
137 docstring::size_type pos = label.find(shortcut);
138 if (pos != docstring::npos)
139 label.insert(pos, 1, char_type('&'));
145 /// \todo Mac specific binding handling.
146 void QLPopupMenu::addBinding(docstring & label, MenuItem const & mi)
150 docstring const binding(mi.binding());
151 if (!binding.empty()) {
152 label += char_type('\t') + binding;
156 /* There are two constraints on Qt/Mac: (1)
157 the bindings require a unicode string to be
158 represented meaningfully and std::string
159 does not work (2) only 1-key bindings can
160 be represented in menus.
162 This is why the unpleasant hack bellow is
165 /* pair<LyXKeySym const *, key_modifier::state>
166 binding = toplevel_keymap->find1keybinding(mi.func());
168 QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
169 label += '\t' + key->qprint(binding.second);
175 /// \todo Fix Mac specific menu hack
176 void QLPopupMenu::specialMacXmenuHack()
179 /* The qt/mac menu code has a very silly hack that
180 moves some menu entries that it recognizes by name
181 (e.g. "Preferences...") to the "LyX" menu. This
182 feature can only work if the menu entries are
183 always available. Since we build menus on demand,
184 we add some dummy contents to one of the menus (JMarc)
187 static QLPopupMenu * themenu = this;
188 if (themenu == this && owner_->backend().hasMenu("LyX")) {
189 Menu special = owner_->backend().getMenu("LyX");
190 Menu::const_iterator end = special.end();
191 Menu::size_type i = 0;
192 for (Menu::const_iterator cit = special.begin();
193 cit != end ; ++cit, ++i)
194 insertItem(toqstr(cit->label()), indexOffset + i);
200 } // namespace frontend
203 #include "QLPopupMenu_moc.cpp"