]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QLPopupMenu.C
remove qPixmapFromMimeSource. This caused the inclusion of Qt3 support headers which...
[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 "frontends/lyx_gui.h"
27 #include "support/lstrings.h"
28 #include "debug.h"
29
30
31 #ifdef Q_WS_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)
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
74         if (name_.empty())
75                 return;
76
77         Menu const & fromLyxMenu = owner_->backend().getMenu(name_);
78         owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view());
79
80         if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
81                 lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << topLevelMenu_.name() << endl;
82         }
83         populate(this, &topLevelMenu_);
84
85         specialMacXmenuHack();
86 }
87
88 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
89 {
90         lyxerr[Debug::GUI] << "populating menu " << menu->name() ;
91         if (menu->size() == 0) {
92                 lyxerr[Debug::GUI] << "\tERROR: empty menu " << menu->name() << endl;
93                 return;
94         }
95         else {
96                 lyxerr[Debug::GUI] << " *****  menu entries " << menu->size() << endl;
97         }
98
99         Menu::const_iterator m = menu->begin();
100         Menu::const_iterator end = menu->end();
101
102         for (; m != end; ++m) {
103
104                 if (m->kind() == MenuItem::Separator) {
105
106                         qMenu->addSeparator();
107                         lyxerr[Debug::GUI] << "adding Menubar Separator" << endl;
108
109                 } else if (m->kind() == MenuItem::Submenu) {
110
111                         lyxerr[Debug::GUI] << "** creating New Sub-Menu " << getLabel(*m) << endl;
112                         QMenu * subMenu = qMenu->addMenu(toqstr(getLabel(*m)));
113                         populate(subMenu, m->submenu());
114
115                 } else { // we have a MenuItem::Command
116
117                         lyxerr[Debug::GUI] << "creating Menu Item " << m->label() << endl;
118
119                         string label = getLabel(*m);
120                         addBinding(label, *m);
121
122                         Action * action = new Action(*(owner_->view()), 
123                                                      label, m->func());
124                         qMenu->addAction(action);
125                 }
126         }
127 }
128
129 string const QLPopupMenu::getLabel(MenuItem const & mi)
130 {
131         string const shortcut = mi.shortcut();
132         string label = support::subst(mi.label(), "&", "&&");
133
134         if (!shortcut.empty()) {
135                 string::size_type pos = label.find(shortcut);
136                 if (pos != string::npos)
137                         label.insert(pos, 1, '&');
138         }
139
140         return label;
141 }
142
143 /// \todo Mac specific binding handling.
144 void QLPopupMenu::addBinding(string & label, MenuItem const & mi)
145 {
146 #ifndef Q_WS_MACX
147
148                 string const binding(mi.binding());
149                 if (!binding.empty()) {
150                         label += '\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"