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