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 // Here, We make sure that theLyXFunc points to the correct LyXView.
76 theLyXFunc().setLyXView(owner_->view());
78 Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
79 owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view()->buffer());
81 if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
82 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << lyx::to_utf8(topLevelMenu_.name()) << endl;
84 populate(this, &topLevelMenu_);
86 specialMacXmenuHack();
89 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
91 lyxerr[Debug::GUI] << "populating menu " << lyx::to_utf8(menu->name()) ;
92 if (menu->size() == 0) {
93 lyxerr[Debug::GUI] << "\tERROR: empty menu " << lyx::to_utf8(menu->name()) << endl;
97 lyxerr[Debug::GUI] << " ***** menu entries " << menu->size() << endl;
100 Menu::const_iterator m = menu->begin();
101 Menu::const_iterator end = menu->end();
103 for (; m != end; ++m) {
105 if (m->kind() == MenuItem::Separator) {
107 qMenu->addSeparator();
108 lyxerr[Debug::GUI] << "adding Menubar Separator" << endl;
110 } else if (m->kind() == MenuItem::Submenu) {
112 lyxerr[Debug::GUI] << "** creating New Sub-Menu " << lyx::to_utf8(getLabel(*m)) << endl;
113 QMenu * subMenu = qMenu->addMenu(toqstr(getLabel(*m)));
114 populate(subMenu, m->submenu());
116 } else { // we have a MenuItem::Command
118 lyxerr[Debug::GUI] << "creating Menu Item " << lyx::to_utf8(m->label()) << endl;
120 docstring label = getLabel(*m);
121 addBinding(label, *m);
123 Action * action = new Action(*(owner_->view()),
125 qMenu->addAction(action);
130 docstring const QLPopupMenu::getLabel(MenuItem const & mi)
132 docstring const shortcut = mi.shortcut();
133 docstring label = support::subst(mi.label(),
134 lyx::from_ascii("&"),
135 lyx::from_ascii("&&"));
137 if (!shortcut.empty()) {
138 docstring::size_type pos = label.find(shortcut);
139 if (pos != docstring::npos)
140 label.insert(pos, 1, char_type('&'));
146 /// \todo Mac specific binding handling.
147 void QLPopupMenu::addBinding(docstring & label, MenuItem const & mi)
151 docstring const binding(mi.binding());
152 if (!binding.empty()) {
153 label += char_type('\t') + binding;
157 /* There are two constraints on Qt/Mac: (1)
158 the bindings require a unicode string to be
159 represented meaningfully and std::string
160 does not work (2) only 1-key bindings can
161 be represented in menus.
163 This is why the unpleasant hack bellow is
166 /* pair<LyXKeySym const *, key_modifier::state>
167 binding = toplevel_keymap->find1keybinding(mi.func());
169 QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
170 label += '\t' + key->qprint(binding.second);
176 /// \todo Fix Mac specific menu hack
177 void QLPopupMenu::specialMacXmenuHack()
180 /* The qt/mac menu code has a very silly hack that
181 moves some menu entries that it recognizes by name
182 (e.g. "Preferences...") to the "LyX" menu. This
183 feature can only work if the menu entries are
184 always available. Since we build menus on demand,
185 we add some dummy contents to one of the menus (JMarc)
188 static QLPopupMenu * themenu = this;
189 if (themenu == this && owner_->backend().hasMenu("LyX")) {
190 Menu special = owner_->backend().getMenu("LyX");
191 Menu::const_iterator end = special.end();
192 Menu::size_type i = 0;
193 for (Menu::const_iterator cit = special.begin();
194 cit != end ; ++cit, ++i)
195 insertItem(toqstr(cit->label()), indexOffset + i);
201 } // namespace frontend
204 #include "QLPopupMenu_moc.cpp"