]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/Menubar_pimpl.C
It compiles, ship it. JMarc, can you see why I might be segfaulting
[lyx.git] / src / frontends / qt2 / Menubar_pimpl.C
1 /**
2  * \file Menubar_pimpl.C
3  * Copyright 1999-2001 The LyX Team.
4  * See the file COPYING.
5  *
6  * \author  Lars Gullik Bjønnes, larsbj@lyx.org
7  */
8
9 #include <config.h>
10
11 #include <algorithm>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "Menubar_pimpl.h"
18 #include "MenuBackend.h"
19 #include "LyXAction.h"
20 #include "kbmap.h"
21 #include "buffer.h"
22 #include "Dialogs.h"
23 #include "lyxfunc.h"
24 #include "FloatList.h"
25 #include "support/lstrings.h"
26 #include "support/LAssert.h"
27 #include "gettext.h"
28 #include "debug.h"
29
30 #include "QtView.h"
31  
32 #include <qmenubar.h>
33 #include <qpopupmenu.h>
34  
35 using std::endl;
36 using std::vector;
37 using std::max;
38 using std::min;
39 using std::for_each;
40
41 namespace {
42  
43 string const getLabel(MenuItem const & mi)
44 {
45         string const shortcut = mi.shortcut();
46         string label = mi.label();
47
48         label = subst(label, "&", "&&");
49  
50         if (shortcut.empty())
51                 return label;
52  
53         string::size_type pos = label.find(shortcut);
54         if (pos == string::npos)
55                 return label;
56         label.insert(pos, "&");
57  
58         return label;
59 }
60
61 };
62  
63 typedef vector<int>::size_type size_type;
64
65 extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
66 extern LyXAction lyxaction;
67
68
69 Menubar::Pimpl::Pimpl(LyXView * view, MenuBackend const & mbe) 
70         : owner_(static_cast<QtView*>(view)), menubackend_(mbe)
71 {
72         Menu::const_iterator m = mbe.getMenubar().begin();
73         Menu::const_iterator end = mbe.getMenubar().end();
74         for (; m != end; ++m) {
75                 Menu tomenu;
76                 Menu const frommenu = menubackend_.getMenu(m->submenuname());
77                 menubackend_.expand(frommenu, tomenu, owner_->buffer());
78                 makeMenu(owner_->menuBar(), m, tomenu);
79         }
80 }
81
82
83 void Menubar::Pimpl::makeMenu(QMenuData * parent, MenuItem const * item, Menu const & menu)
84 {
85         // FIXME: does this leak or not ?
86         QPopupMenu * pm = new QPopupMenu();
87         int const parentid = parent->insertItem(getLabel(*item).c_str(), pm);
88  
89         Menu::const_iterator m = menu.begin();
90         Menu::const_iterator end = menu.end();
91         for (; m != end; ++m) {
92                 // FIXME: handle the special stuff here
93                 if (m->kind() == MenuItem::Separator) {
94                         pm->insertSeparator();
95                 } else if (m->kind() == MenuItem::Submenu) {
96                         makeMenu(pm, m, m->submenu());
97                 } else {
98                         pm->insertItem(getLabel(*m).c_str(), m->action());
99                         MenuItemInfo const info(pm, m->action(), m);
100                         items_[m->label()] = info;
101                         updateItem(info);
102                 }
103         }
104
105         MenuItemInfo const info(parent, parentid, item);
106         items_[item->label()] = info;
107         updateSubmenu(info);
108 }
109
110  
111 // FIXME: this is probably buggy with respect to enabling
112 // two-level submenus
113 void Menubar::Pimpl::updateSubmenu(MenuItemInfo const & i)
114 {
115 #if 0 // SEGFAULTS
116 // 7  0x0809d372 in Menu::begin (this=0x0) at MenuBackend.h:138
117 // 8  0x081dcf60 in Menubar::Pimpl::updateSubmenu (this=0x839eaa0, i=@0xbffff010) at Menubar_pimpl.C:116 
118         bool enable = false;
119  
120         Menu::const_iterator m = i.item_->submenu().begin();
121         Menu::const_iterator end = i.item_->submenu().end();
122         for (; m != end; ++m) {
123                 if (m->action() > 0) {
124                         FuncStatus const status =
125                                 owner_->getLyXFunc()->getStatus(m->action());
126                         if (!status.disabled())
127                                 enable = true;
128                 }
129         }
130 #else
131         bool enable = true;
132 #endif
133         i.parent_->setItemEnabled(i.id_, enable);
134 }
135  
136  
137 void Menubar::Pimpl::updateItem(MenuItemInfo const & i)
138 {
139         if (i.item_->kind() == MenuItem::Submenu) {
140                 updateSubmenu(i);
141                 return;
142         }
143  
144         // FIXME
145         if (i.id_ < 0)
146                 return;
147  
148         FuncStatus const status = owner_->getLyXFunc()->getStatus(i.id_);
149         i.parent_->setItemEnabled(i.id_, !status.disabled());
150         i.parent_->setItemChecked(i.id_, status.onoff(true));
151 }
152
153  
154 void Menubar::Pimpl::update()
155 {
156         // FIXME: handle special stuff to be updated.
157  
158         ItemMap::const_iterator cit = items_.begin();
159         ItemMap::const_iterator end = items_.end();
160
161         for (; cit != end; ++cit)
162                 updateItem(cit->second);
163 }
164
165
166 void Menubar::Pimpl::openByName(string const & name)
167 {
168         lyxerr << "Menubar::Pimpl::openByName: menu " << name << endl;
169
170         ItemMap::iterator it = items_.find(name);
171
172         if (it == items_.end())
173                 lyxerr << "NOT FOUND " << name << endl;
174
175         // FIXME 
176 }