]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QLPopupMenu.C
hopefully fix tex2lyx linking.
[lyx.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 #ifdef Q_WS_MACX
31 #include "kbmap.h"
32 #include "QLyXKeySym.h"
33 #endif
34
35 using std::make_pair;
36 using std::string;
37 using std::pair;
38 using std::endl;
39
40 namespace {
41
42 } // namespace anon
43
44 namespace lyx {
45
46 namespace frontend {
47
48
49 // MacOSX specific stuff is at the end.
50
51 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
52                                                  MenuItem const & mi, bool topLevelMenu)
53         : owner_(owner)
54 {
55         name_ = mi.submenuname();
56
57         setTitle(toqstr(getLabel(mi)));
58
59         if (topLevelMenu)
60                 connect(this, SIGNAL(aboutToShow()), this, SLOT(update()));
61 }
62
63
64
65 void QLPopupMenu::update()
66 {
67         lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << endl;
68         lyxerr[Debug::GUI] << "\tTriggered menu: " << lyx::to_utf8(name_) << endl;
69
70         clear();
71
72         if (name_.empty())
73                 return;
74
75         Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
76         owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view()->buffer());
77
78         if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
79                 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << lyx::to_utf8(topLevelMenu_.name()) << endl;
80         }
81         populate(this, &topLevelMenu_);
82
83         specialMacXmenuHack();
84 }
85
86 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
87 {
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;
91                 return;
92         }
93         else {
94                 lyxerr[Debug::GUI] << " *****  menu entries " << menu->size() << endl;
95         }
96
97         Menu::const_iterator m = menu->begin();
98         Menu::const_iterator end = menu->end();
99
100         for (; m != end; ++m) {
101
102                 if (m->kind() == MenuItem::Separator) {
103
104                         qMenu->addSeparator();
105                         lyxerr[Debug::GUI] << "adding Menubar Separator" << endl;
106
107                 } else if (m->kind() == MenuItem::Submenu) {
108
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());
112
113                 } else { // we have a MenuItem::Command
114
115                         lyxerr[Debug::GUI] << "creating Menu Item " << lyx::to_utf8(m->label()) << endl;
116
117                         docstring label = getLabel(*m);
118                         addBinding(label, *m);
119
120                         Action * action = new Action(*(owner_->view()),
121                                                      label, m->func());
122                         qMenu->addAction(action);
123                 }
124         }
125 }
126
127 docstring const QLPopupMenu::getLabel(MenuItem const & mi)
128 {
129         docstring const shortcut = mi.shortcut();
130         docstring label = support::subst(mi.label(),
131                                       lyx::from_ascii("&"),
132                                       lyx::from_ascii("&&"));
133
134         if (!shortcut.empty()) {
135                 docstring::size_type pos = label.find(shortcut);
136                 if (pos != docstring::npos)
137                         label.insert(pos, 1, char_type('&'));
138         }
139
140         return label;
141 }
142
143 /// \todo Mac specific binding handling.
144 void QLPopupMenu::addBinding(docstring & label, MenuItem const & mi)
145 {
146 #ifndef Q_WS_MACX
147
148                 docstring const binding(mi.binding());
149                 if (!binding.empty()) {
150                         label += char_type('\t') + binding;
151                 }
152
153 #else
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.
159
160                            This is why the unpleasant hack bellow is
161                            needed (JMarc)
162                         */
163 /*                      pair<LyXKeySym const *, key_modifier::state>
164                                 binding = toplevel_keymap->find1keybinding(mi.func());
165                         if (binding.first) {
166                                 QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
167                                 label += '\t' + key->qprint(binding.second);
168                         }
169 */
170 #endif
171 }
172
173 /// \todo Fix Mac specific menu hack
174 void QLPopupMenu::specialMacXmenuHack()
175 {
176 #ifdef Q_WS_MACX
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)
183         */
184 /*
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);
193         }
194 */
195 #endif
196 }
197
198 } // namespace frontend
199 } // namespace lyx
200
201 #include "QLPopupMenu_moc.cpp"