]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QLPopupMenu.C
ea7c8cd3275ca97e792c34812f816bf64ba8ca07
[lyx.git] / src / frontends / qt2 / 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  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13
14 #include "support/lstrings.h"
15 #include "MenuBackend.h"
16
17 #include "QtView.h"
18
19 #include "QLMenubar.h"
20 #include "QLPopupMenu.h"
21 #include "qt_helpers.h"
22
23 using lyx::support::subst;
24
25 using std::distance;
26 using std::make_pair;
27 using std::string;
28 using std::pair;
29
30
31 namespace {
32
33 string const getLabel(MenuItem const & mi)
34 {
35         string const shortcut = mi.shortcut();
36         string label = subst(mi.label(), "&", "&&");
37
38         if (!shortcut.empty()) {
39                 string::size_type pos = label.find(shortcut);
40                 if (pos != string::npos)
41                         label.insert(pos, 1, '&');
42         }
43
44         if (mi.kind() == MenuItem::Command) {
45                 string const binding(mi.binding());
46                 if (!binding.empty()) {
47                         label += '\t' + binding;
48                 }
49         }
50
51         return label;
52 }
53
54 } // namespace anon
55
56
57 pair<int, QLPopupMenu *>
58 createMenu(QMenuData * parent, MenuItem const * item, QLMenubar * owner,
59            bool is_toplevel)
60 {
61         // FIXME: leaks ??
62         QLPopupMenu * pm = new QLPopupMenu(owner, item->submenuname(), is_toplevel);
63         int const id = parent->insertItem(toqstr(getLabel(*item)), pm);
64         return make_pair(id, pm);
65 }
66
67
68 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
69                          string const & name, bool toplevel)
70         : owner_(owner), name_(name)
71 {
72         if (toplevel)
73                 connect(this, SIGNAL(aboutToShow()), this, SLOT(showing()));
74         connect(this, SIGNAL(activated(int)),
75                 this, SLOT(fire(int)));
76 }
77
78
79 void QLPopupMenu::fire(int index)
80 {
81         owner_->view()->activated(funcs_[index]);
82 }
83
84
85 void QLPopupMenu::populate(Menu * menu)
86 {
87         funcs_.clear();
88
89         Menu::const_iterator m = menu->begin();
90         Menu::const_iterator end = menu->end();
91         for (; m != end; ++m) {
92                 if (m->kind() == MenuItem::Separator) {
93                         insertSeparator();
94                 } else if (m->kind() == MenuItem::Submenu) {
95                         pair<int, QLPopupMenu *> res = createMenu(this, &(*m), owner_);
96                         setItemEnabled(res.first,
97                                        !m->status().disabled());
98                         res.second->populate(m->submenu());
99                 } else {
100                         FuncStatus const status = m->status();
101
102                         Funcs::iterator fit =
103                                 funcs_.insert(funcs_.end(), m->func());
104                         int const index = distance(funcs_.begin(), fit);
105
106                         insertItem(toqstr(getLabel(*m)), index);
107                         setItemEnabled(index, !status.disabled());
108                         setItemChecked(index, status.onoff(true));
109                 }
110         }
111 }
112
113
114 void QLPopupMenu::showing()
115 {
116         clear();
117         Menu tomenu;
118         Menu const frommenu = owner_->backend().getMenu(name_);
119         owner_->backend().expand(frommenu, tomenu, owner_->view());
120         populate(&tomenu);
121 }