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"
49 // MacOSX specific stuff is at the end.
51 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
52 MenuItem const & mi, bool topLevelMenu)
55 name_ = mi.submenuname();
57 setTitle(toqstr(getLabel(mi)));
60 connect(this, SIGNAL(aboutToShow()), this, SLOT(update()));
65 void QLPopupMenu::update()
67 lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << endl;
68 lyxerr[Debug::GUI] << "\tTriggered menu: " << lyx::to_utf8(name_) << endl;
75 Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
76 owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view()->buffer());
78 if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
79 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << lyx::to_utf8(topLevelMenu_.name()) << endl;
81 populate(this, &topLevelMenu_);
83 specialMacXmenuHack();
86 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
88 lyxerr[Debug::GUI] << "populating menu " << lyx::to_utf8(menu->name()) ;
89 if (menu->size() == 0) {
90 lyxerr[Debug::GUI] << "\tERROR: empty menu " << lyx::to_utf8(menu->name()) << endl;
94 lyxerr[Debug::GUI] << " ***** menu entries " << menu->size() << endl;
97 Menu::const_iterator m = menu->begin();
98 Menu::const_iterator end = menu->end();
100 for (; m != end; ++m) {
102 if (m->kind() == MenuItem::Separator) {
104 qMenu->addSeparator();
105 lyxerr[Debug::GUI] << "adding Menubar Separator" << endl;
107 } else if (m->kind() == MenuItem::Submenu) {
109 lyxerr[Debug::GUI] << "** creating New Sub-Menu " << lyx::to_utf8(getLabel(*m)) << endl;
110 QMenu * subMenu = qMenu->addMenu(toqstr(getLabel(*m)));
111 populate(subMenu, m->submenu());
113 } else { // we have a MenuItem::Command
115 lyxerr[Debug::GUI] << "creating Menu Item " << lyx::to_utf8(m->label()) << endl;
117 docstring label = getLabel(*m);
118 addBinding(label, *m);
120 Action * action = new Action(*(owner_->view()),
122 qMenu->addAction(action);
127 docstring const QLPopupMenu::getLabel(MenuItem const & mi)
129 docstring const shortcut = mi.shortcut();
130 docstring label = support::subst(mi.label(),
131 lyx::from_ascii("&"),
132 lyx::from_ascii("&&"));
134 if (!shortcut.empty()) {
135 docstring::size_type pos = label.find(shortcut);
136 if (pos != docstring::npos)
137 label.insert(pos, 1, char_type('&'));
143 /// \todo Mac specific binding handling.
144 void QLPopupMenu::addBinding(docstring & label, MenuItem const & mi)
148 docstring const binding(mi.binding());
149 if (!binding.empty()) {
150 label += char_type('\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"