]> git.lyx.org Git - features.git/blob - src/frontends/qt4/QLPopupMenu.C
Convert shortcut strings to unicode (required by Qt/Mac); restore
[features.git] / src / frontends / qt4 / QLPopupMenu.C
1 /**
2  * \file QLPopupMenu.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Abdelrazak Younes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include <boost/current_function.hpp>
15
16 // Qt defines a macro 'signals' that clashes with a boost namespace.
17 // All is well if the namespace is visible first.
18 #include "GuiView.h"
19
20 #include "Action.h"
21 #include "QLPopupMenu.h"
22 #include "QLMenubar.h"
23 #include "qt_helpers.h"
24 #include "MenuBackend.h"
25
26 #include "support/lstrings.h"
27 #include "debug.h"
28
29
30 using std::make_pair;
31 using std::string;
32 using std::pair;
33 using std::endl;
34
35 namespace {
36
37 } // namespace anon
38
39 namespace lyx {
40
41 namespace frontend {
42
43
44 // MacOSX specific stuff is at the end.
45
46 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
47                                                  MenuItem const & mi, bool topLevelMenu)
48         : owner_(owner)
49 {
50         name_ = mi.submenuname();
51
52         setTitle(toqstr(getLabel(mi)));
53
54         if (topLevelMenu)
55                 connect(this, SIGNAL(aboutToShow()), this, SLOT(update()));
56 }
57
58
59
60 void QLPopupMenu::update()
61 {
62         lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << endl;
63         lyxerr[Debug::GUI] << "\tTriggered menu: " << lyx::to_utf8(name_) << endl;
64
65         clear();
66
67         if (name_.empty())
68                 return;
69
70         // Here, We make sure that theLyXFunc points to the correct LyXView.
71         theLyXFunc().setLyXView(owner_->view());
72
73         Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
74         owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view()->buffer());
75
76         if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
77                 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << lyx::to_utf8(topLevelMenu_.name()) << endl;
78         }
79         populate(this, &topLevelMenu_);
80
81         specialMacXmenuHack();
82 }
83
84 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
85 {
86         lyxerr[Debug::GUI] << "populating menu " << lyx::to_utf8(menu->name()) ;
87         if (menu->size() == 0) {
88                 lyxerr[Debug::GUI] << "\tERROR: empty menu " << lyx::to_utf8(menu->name()) << endl;
89                 return;
90         }
91         else {
92                 lyxerr[Debug::GUI] << " *****  menu entries " << menu->size() << endl;
93         }
94
95         Menu::const_iterator m = menu->begin();
96         Menu::const_iterator end = menu->end();
97
98         for (; m != end; ++m) {
99
100                 if (m->kind() == MenuItem::Separator) {
101
102                         qMenu->addSeparator();
103                         lyxerr[Debug::GUI] << "adding Menubar Separator" << endl;
104
105                 } else if (m->kind() == MenuItem::Submenu) {
106
107                         lyxerr[Debug::GUI] << "** creating New Sub-Menu " << lyx::to_utf8(getLabel(*m)) << endl;
108                         QMenu * subMenu = qMenu->addMenu(toqstr(getLabel(*m)));
109                         populate(subMenu, m->submenu());
110
111                 } else { // we have a MenuItem::Command
112
113                         lyxerr[Debug::GUI] << "creating Menu Item " << lyx::to_utf8(m->label()) << endl;
114
115                         docstring label = getLabel(*m);
116                         addBinding(label, *m);
117
118                         Action * action = new Action(*(owner_->view()),
119                                                      label, m->func());
120                         qMenu->addAction(action);
121                 }
122         }
123 }
124
125 docstring const QLPopupMenu::getLabel(MenuItem const & mi)
126 {
127         docstring const shortcut = mi.shortcut();
128         docstring label = support::subst(mi.label(),
129                                       lyx::from_ascii("&"),
130                                       lyx::from_ascii("&&"));
131
132         if (!shortcut.empty()) {
133                 docstring::size_type pos = label.find(shortcut);
134                 if (pos != docstring::npos)
135                         label.insert(pos, 1, char_type('&'));
136         }
137
138         return label;
139 }
140
141 /// \todo Mac specific binding handling.
142 void QLPopupMenu::addBinding(docstring & label, MenuItem const & mi)
143 {
144         docstring const binding(mi.binding());
145         if (!binding.empty()) {
146                 label += '\t' + binding;
147         }
148 }
149
150 /// \todo Fix Mac specific menu hack
151 void QLPopupMenu::specialMacXmenuHack()
152 {
153 #ifdef Q_WS_MACX
154         /* The qt/mac menu code has a very silly hack that
155            moves some menu entries that it recognizes by name
156            (e.g. "Preferences...") to the "LyX" menu. This
157            feature can only work if the menu entries are
158            always available. Since we build menus on demand,
159            we add some dummy contents to one of the menus (JMarc)
160         */
161 /*
162         static QLPopupMenu * themenu = this;
163         if (themenu == this && owner_->backend().hasMenu("LyX")) {
164                 Menu special = owner_->backend().getMenu("LyX");
165                 Menu::const_iterator end = special.end();
166                 Menu::size_type i = 0;
167                 for (Menu::const_iterator cit = special.begin();
168                      cit != end ; ++cit, ++i)
169                         insertItem(toqstr(cit->label()), indexOffset + i);
170         }
171 */
172 #endif
173 }
174
175 } // namespace frontend
176 } // namespace lyx
177
178 #include "QLPopupMenu_moc.cpp"