]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QLMenubar.C
bbe027d076540f0076a5fa4a5375fc78e93d474f
[lyx.git] / src / frontends / qt4 / QLMenubar.C
1 /**
2  * \file qt4/QLMenubar.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  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 // Qt defines a macro 'signals' that clashes with a boost namespace.
14 // All is well if the namespace is visible first.
15 #include "GuiView.h"
16
17 #include "Action.h"
18 #include "QLMenubar.h"
19 #include "QLPopupMenu.h"
20
21 #include "qt_helpers.h"
22 #include "support/lstrings.h"
23
24 #include "MenuBackend.h"
25
26 #include "debug.h"
27
28 #include <QMenuBar>
29 #include <QCursor>
30
31 using std::pair;
32 using std::string;
33 using std::endl;
34
35 namespace {
36
37 } // namespace anon
38
39 namespace lyx {
40
41
42 namespace frontend {
43
44 // MacOSX specific stuff is at the end.
45
46 QLMenubar::QLMenubar(LyXView * view, MenuBackend & mbe)
47         : owner_(static_cast<GuiView*>(view)), menubackend_(mbe)
48 {
49         macxMenuBarInit();
50
51         lyxerr[Debug::GUI] << "populating menu bar" << lyx::to_utf8(menubackend_.getMenubar().name()) << endl;
52
53         if (menubackend_.getMenubar().size() == 0) {
54                 lyxerr[Debug::GUI] << "\tERROR: empty menu bar" << lyx::to_utf8(menubackend_.getMenubar().name()) << endl;
55                 return;
56                 //                      continue;
57         }
58         else {
59                 lyxerr[Debug::GUI] << "menu bar entries " << menubackend_.getMenubar().size();
60         }
61         //      for (; m != end; ++m) {
62
63         Menu menu;
64         menubackend_.expand(menubackend_.getMenubar(), menu, owner_->buffer());
65
66         Menu::const_iterator m = menu.begin();
67         Menu::const_iterator end = menu.end();
68
69         for (; m != end; ++m) {
70
71                 if (m->kind() != MenuItem::Submenu) {
72                         lyxerr[Debug::GUI] << "\tERROR: not a submenu " << lyx::to_utf8(m->label()) << endl;
73                         continue;
74                 }
75
76                 lyxerr[Debug::GUI] << "menu bar item " << lyx::to_utf8(m->label()) << " is a submenu named " << lyx::to_utf8(m->submenuname()) << endl;
77
78                 docstring name = m->submenuname();
79                 if (!menubackend_.hasMenu(name)) {
80                         lyxerr[Debug::GUI] << "\tERROR: " << lyx::to_utf8(name) << " submenu has no menu!" << endl;
81                         continue;
82                 }
83
84                 Menu menu;
85                 menubackend_.expand(menubackend_.getMenubar(), menu, owner_->buffer());
86
87                 QLPopupMenu * qMenu = new QLPopupMenu(this, *m, true);
88                 owner_->menuBar()->addMenu(qMenu);
89
90                 pair<NameMap::iterator, bool> I = name_map_.insert(make_pair(name, qMenu));
91                 if (!I.second) {
92                         lyxerr[Debug::GUI] << "\tERROR: " << lyx::to_utf8(name) << " submenu is already there!" << endl;
93                 }
94 /*
95                 QObject::connect(qMenu, SIGNAL(aboutToShow()), this, SLOT(update()));
96                 QObject::connect(qMenu, SIGNAL(triggered(QAction *)), this, SLOT(update()));
97                 QObject::connect(qMenu->menuAction(), SIGNAL(triggered()), this, SLOT(update()));
98 */
99         }
100         //QObject::connect(owner_->menuBar(), SIGNAL(triggered()), this, SLOT(update()));
101 }
102
103 void QLMenubar::openByName(docstring const & name)
104 {
105         NameMap::const_iterator const cit = name_map_.find(name);
106         if (cit == name_map_.end())
107                 return;
108
109         // I (Abdel) don't understand this comment:
110         // this will have to do I'm afraid.
111         cit->second->exec(QCursor::pos());
112 }
113
114
115 void QLMenubar::update()
116 { }
117
118 GuiView * QLMenubar::view()
119 {
120         return owner_;
121 }
122
123
124 MenuBackend const & QLMenubar::backend()
125 {
126         return menubackend_;
127 }
128
129
130 /// Some special Qt/Mac support hacks
131
132 /*
133   Here is what the Qt documentation says about how a menubar is chosen:
134
135      1) If the window has a QMenuBar then it is used. 2) If the window
136      is a modal then its menubar is used. If no menubar is specified
137      then a default menubar is used (as documented below) 3) If the
138      window has no parent then the default menubar is used (as
139      documented below).
140
141      The above 3 steps are applied all the way up the parent window
142      chain until one of the above are satisifed. If all else fails a
143      default menubar will be created, the default menubar on Qt/Mac is
144      an empty menubar, however you can create a different default
145      menubar by creating a parentless QMenuBar, the first one created
146      will thus be designated the default menubar, and will be used
147      whenever a default menubar is needed.
148
149   Thus, for Qt/Mac, we add the menus to a free standing menubar, so
150   that this menubar will be used also when one of LyX' dialogs has
151   focus. (JMarc)
152 */
153 QMenuBar * QLMenubar::menuBar() const
154 {
155 #ifdef Q_WS_MACX
156         return mac_menubar_.get();
157 #else
158         return owner_->menuBar();
159 #endif
160 }
161
162 #ifdef Q_WS_MACX
163 # define MERGE_MAC_MENUS
164 # ifndef MERGE_MAC_MENUS
165 extern void qt_mac_set_menubar_merge(bool b);
166 # endif
167 #endif
168
169 void QLMenubar::macxMenuBarInit()
170 {
171 #ifdef Q_WS_MACX
172         mac_menubar_.reset(new QMenuBar);
173
174 # ifdef MERGE_MAC_MENUS
175         /* The qt/mac menu code has a very silly hack that moves some
176            menu entries that it recognizes by name (e.g.
177            "Preferences...") to the "LyX" menu. This feature can only
178            work if the menu entries are always available. Since we
179            build menus on demand, we add the entries to a dummy menu
180            (JMarc)
181         */
182
183         // this is the name of the menu that contains our special entries
184         docstring const & specialname = from_ascii("LyX");
185         if (menubackend_.hasMenu(specialname)) {
186                 QMenu * qMenu = owner_->menuBar()->addMenu("special");
187                 //qMenu->setVisible(false);
188
189                 menubackend_.specialMenu(specialname);
190                 Menu const & special = menubackend_.getMenu(specialname);
191                 Menu::const_iterator end = special.end();
192                 for (Menu::const_iterator cit = special.begin();
193                      cit != end ; ++cit) 
194                         qMenu->addAction(new Action(*owner_, cit->label(), cit->func()));
195         }
196 # else
197         qt_mac_set_menubar_merge(false);
198 # endif // MERGE_MAC_MENUS
199 #endif // Q_WS_MACX
200 }
201
202 } // namespace frontend
203 } // namespace lyx
204
205 #include "QLMenubar_moc.cpp"