]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QLPopupMenu.C
Abdelrazak Younes: Compile fixes for the Mac (ChangeLog follows)
[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 "QtView.h"
19
20 #include "QLAction.h"
21 #include "QLPopupMenu.h"
22 #include "QLMenubar.h"
23 #include "qt_helpers.h"
24 #include "MenuBackend.h"
25
26 #include "frontends/lyx_gui.h"
27 #include "support/lstrings.h"
28 #include "debug.h"
29
30
31 #ifdef Q_OS_MACX
32 #include "kbmap.h"
33 #include "QLyXKeySym.h"
34 extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
35 #endif
36
37 using std::make_pair;
38 using std::string;
39 using std::pair;
40 using std::endl;
41
42 namespace {
43
44 } // namespace anon
45
46 namespace lyx {
47
48 namespace frontend {
49
50
51 // MacOSX specific stuff is at the end.
52
53 QLPopupMenu::QLPopupMenu(QLMenubar * owner, 
54                                                  MenuItem const & mi, bool topLevelMenu)
55         : owner_(owner), topLevelMenu_(topLevelMenu)
56 {
57         name_ = mi.submenuname();
58
59         setTitle(toqstr(getLabel(mi)));
60
61         if (topLevelMenu)
62                 connect(this, SIGNAL(aboutToShow()), this, SLOT(update()));
63 }
64
65
66
67 void QLPopupMenu::update()
68 {
69         lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << endl;
70         lyxerr[Debug::GUI] << "\tTriggered menu: " << name_ << endl;
71
72         clear();
73         topLevelMenu.clear();
74
75         if (name_.empty())
76                 return;
77
78         Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
79         owner_->backend().expand(fromLyxMenu, topLevelMenu, owner_->view());
80         
81         if (!owner_->backend().hasMenu(topLevelMenu.name())) {
82                 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << topLevelMenu.name() << endl;
83         }
84         populate(this, &topLevelMenu);
85
86         specialMacXmenuHack();
87 }
88
89 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
90 {
91         lyxerr[Debug::GUI] << "populating menu " << menu->name() ;
92         if (menu->size() == 0) {
93                 lyxerr[Debug::GUI] << "\tERROR: empty menu " << menu->name() << endl;
94                 return;
95         }
96         else {
97                 lyxerr[Debug::GUI] << " *****  menu entries " << menu->size() << endl;
98         }
99
100         Menu::const_iterator m = menu->begin();
101         Menu::const_iterator end = menu->end();
102         
103         for (; m != end; ++m) {
104
105                 if (m->kind() == MenuItem::Separator) {
106                 
107                         qMenu->addSeparator();
108                         lyxerr[Debug::GUI] << "adding Menubar Separator" << endl;
109
110                 } else if (m->kind() == MenuItem::Submenu) {
111                         
112                         lyxerr[Debug::GUI] << "** creating New Sub-Menu " << getLabel(*m) << endl;
113                         QMenu * subMenu = qMenu->addMenu(toqstr(getLabel(*m)));
114                         populate(subMenu, m->submenu());
115                         
116                 } else { // we have a MenuItem::Command
117
118                         FuncStatus status = m->status();
119                         lyxerr[Debug::GUI] << "creating Menu Item " << m->label() << endl;
120                         
121                         string label = getLabel(*m);
122                         addBinding(label, *m);
123                         
124                         QLAction * action = new QLAction(*(owner_->view()), label, m->func());
125                         action->setEnabled(m->status().enabled());
126                         action->setChecked(m->status().onoff(true));
127                         // Actually insert the menu item
128                         qMenu->addAction(action);
129                 }
130         }
131 }
132
133 string const QLPopupMenu::getLabel(MenuItem const & mi)
134 {
135         string const shortcut = mi.shortcut();
136         string label = support::subst(mi.label(), "&", "&&");
137
138         if (!shortcut.empty()) {
139                 string::size_type pos = label.find(shortcut);
140                 if (pos != string::npos)
141                         label.insert(pos, 1, '&');
142         }
143
144         return label;
145 }
146
147 /// \todo Mac specific binding handling.
148 void QLPopupMenu::addBinding(string & label, MenuItem const & mi)
149 {
150 #ifndef Q_OS_MACX
151
152                 string const binding(mi.binding());
153                 if (!binding.empty()) {
154                         label += '\t' + binding;
155                 }
156
157 #else
158                         /* There are two constraints on Qt/Mac: (1)
159                            the bindings require a unicode string to be
160                            represented meaningfully and std::string
161                            does not work (2) only 1-key bindings can
162                            be represented in menus.
163
164                            This is why the unpleasant hack bellow is
165                            needed (JMarc)
166                         */
167 /*                      pair<LyXKeySym const *, key_modifier::state>
168                                 binding = toplevel_keymap->find1keybinding(mi.func());
169                         if (binding.first) {
170                                 QLyXKeySym const *key = static_cast<QLyXKeySym const *>(binding.first);
171                                 label += '\t' + key->qprint(binding.second);
172                         }
173 */
174 #endif
175 }
176
177 /// \todo Fix Mac specific menu hack
178 void QLPopupMenu::specialMacXmenuHack()
179 {
180 #ifdef Q_OS_MACX
181         /* The qt/mac menu code has a very silly hack that
182            moves some menu entries that it recognizes by name
183            (e.g. "Preferences...") to the "LyX" menu. This
184            feature can only work if the menu entries are
185            always available. Since we build menus on demand,
186            we add some dummy contents to one of the menus (JMarc)
187         */
188 /*
189         static QLPopupMenu * themenu = this;
190         if (themenu == this && owner_->backend().hasMenu("LyX")) {
191                 Menu special = owner_->backend().getMenu("LyX");
192                 Menu::const_iterator end = special.end();
193                 Menu::size_type i = 0;
194                 for (Menu::const_iterator cit = special.begin();
195                      cit != end ; ++cit, ++i)
196                         insertItem(toqstr(cit->label()), indexOffset + i);
197         }
198 */
199 #endif
200 }
201
202 } // namespace frontend
203 } // namespace lyx