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 "support/lstrings.h"
32 #include "QLyXKeySym.h"
33 extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
50 // MacOSX specific stuff is at the end.
52 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
53 MenuItem const & mi, bool topLevelMenu)
56 name_ = mi.submenuname();
58 setTitle(toqstr(getLabel(mi)));
61 connect(this, SIGNAL(aboutToShow()), this, SLOT(update()));
66 void QLPopupMenu::update()
68 lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << endl;
69 lyxerr[Debug::GUI] << "\tTriggered menu: " << lyx::to_utf8(name_) << endl;
76 Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
77 owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view()->buffer());
79 if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
80 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << lyx::to_utf8(topLevelMenu_.name()) << endl;
82 populate(this, &topLevelMenu_);
84 specialMacXmenuHack();
87 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
89 lyxerr[Debug::GUI] << "populating menu " << lyx::to_utf8(menu->name()) ;
90 if (menu->size() == 0) {
91 lyxerr[Debug::GUI] << "\tERROR: empty menu " << lyx::to_utf8(menu->name()) << endl;
95 lyxerr[Debug::GUI] << " ***** menu entries " << menu->size() << endl;
98 Menu::const_iterator m = menu->begin();
99 Menu::const_iterator end = menu->end();
101 for (; m != end; ++m) {
103 if (m->kind() == MenuItem::Separator) {
105 qMenu->addSeparator();
106 lyxerr[Debug::GUI] << "adding Menubar Separator" << endl;
108 } else if (m->kind() == MenuItem::Submenu) {
110 lyxerr[Debug::GUI] << "** creating New Sub-Menu " << lyx::to_utf8(getLabel(*m)) << endl;
111 QMenu * subMenu = qMenu->addMenu(toqstr(getLabel(*m)));
112 populate(subMenu, m->submenu());
114 } else { // we have a MenuItem::Command
116 lyxerr[Debug::GUI] << "creating Menu Item " << lyx::to_utf8(m->label()) << endl;
118 docstring label = getLabel(*m);
119 addBinding(label, *m);
121 Action * action = new Action(*(owner_->view()),
123 qMenu->addAction(action);
128 docstring const QLPopupMenu::getLabel(MenuItem const & mi)
130 docstring const shortcut = mi.shortcut();
131 docstring label = support::subst(mi.label(),
132 lyx::from_ascii("&"),
133 lyx::from_ascii("&&"));
135 if (!shortcut.empty()) {
136 docstring::size_type pos = label.find(shortcut);
137 if (pos != docstring::npos)
138 label.insert(pos, 1, char_type('&'));
144 /// \todo Mac specific binding handling.
145 void QLPopupMenu::addBinding(docstring & label, MenuItem const & mi)
149 docstring const binding(mi.binding());
150 if (!binding.empty()) {
151 label += char_type('\t') + binding;
155 /* There are two constraints on Qt/Mac: (1)
156 the bindings require a unicode string to be
157 represented meaningfully and std::string
158 does not work (2) only 1-key bindings can
159 be represented in menus.
161 This is why the unpleasant hack bellow is
164 /* pair<LyXKeySym const *, key_modifier::state>
165 binding = toplevel_keymap->find1keybinding(mi.func());
167 QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
168 label += '\t' + key->qprint(binding.second);
174 /// \todo Fix Mac specific menu hack
175 void QLPopupMenu::specialMacXmenuHack()
178 /* The qt/mac menu code has a very silly hack that
179 moves some menu entries that it recognizes by name
180 (e.g. "Preferences...") to the "LyX" menu. This
181 feature can only work if the menu entries are
182 always available. Since we build menus on demand,
183 we add some dummy contents to one of the menus (JMarc)
186 static QLPopupMenu * themenu = this;
187 if (themenu == this && owner_->backend().hasMenu("LyX")) {
188 Menu special = owner_->backend().getMenu("LyX");
189 Menu::const_iterator end = special.end();
190 Menu::size_type i = 0;
191 for (Menu::const_iterator cit = special.begin();
192 cit != end ; ++cit, ++i)
193 insertItem(toqstr(cit->label()), indexOffset + i);
199 } // namespace frontend
202 #include "QLPopupMenu_moc.cpp"