3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
26 class LyxMenu : public Gtk::Menu {
28 LyxMenu() { menu_.reset(new ::Menu); }
30 ::Menu& getBackMenu() { return *menu_.get(); }
32 void clearBackMenu() { menu_.reset(new ::Menu); }
34 std::auto_ptr< ::Menu > menu_;
38 Glib::ustring labelTrans(string const & label, string const & shortcut)
40 string labelN = label;
41 string::size_type i = label.find(shortcut);
42 if (i == string::npos)
43 return Glib::locale_to_utf8(label);
44 labelN.insert(i, "_");
45 return Glib::locale_to_utf8(labelN);
49 void ClearMenu(Gtk::MenuShell * menu)
51 Gtk::Menu_Helpers::MenuList::iterator m = menu->items().begin();
52 Gtk::Menu_Helpers::MenuList::iterator end = menu->items().end();
54 for (; m != end; ++m) {
55 if ((subMenu = m->get_submenu()) != 0) {
60 menu->items().clear();
67 GMenubar::GMenubar(LyXView * lyxView, MenuBackend const & /*menuBackend*/) :
70 GView * gview = static_cast<GView*>(lyxView);
71 Menu const & menu = menubackend.getMenubar();
72 Menu::const_iterator i = menu.begin();
73 Menu::const_iterator end = menu.end();
74 for (; i != end; ++i) {
75 if (i->kind() != MenuItem::Submenu) {
76 lyxerr << "ERROR: GMenubar::createMenubar:"
77 " only submenus can appear in a menubar"
81 Gtk::Menu * gmenu = new LyxMenu;
82 menubar_.items().push_back(
83 Gtk::Menu_Helpers::MenuElem(
84 labelTrans(i->label(), i->shortcut()),
86 menubar_.items().back().signal_activate().connect(
87 sigc::bind(sigc::mem_fun(*this, &GMenubar::onSubMenuActivate), &(*i),
88 &menubar_.items().back()));
89 mainMenuNames_.push_back(i->submenuname());
92 gview->getBox(GView::Top).children().push_back(
93 Gtk::Box_Helpers::Element(menubar_, Gtk::PACK_SHRINK));
103 void GMenubar::update()
108 void GMenubar::openByName(string const & name)
110 Glib::ustring uname = Glib::locale_to_utf8(name);
111 std::vector<Glib::ustring>::iterator it =
112 std::find(mainMenuNames_.begin(), mainMenuNames_.end(),
114 if (it != mainMenuNames_.end()) {
115 Gtk::MenuItem& mitem = menubar_.items()[it - mainMenuNames_.begin()];
120 lyxerr << "GMenubar::openByName: menu "
121 << name << " not found" << std::endl;
125 bool GMenubar::submenuDisabled(MenuItem const * item)
127 Menu * from = item->submenu();
129 menubackend.expand(*from, to, view_);
130 Menu::const_iterator i = to.begin();
131 Menu::const_iterator end = to.end();
132 for (; i != end; ++i) {
134 case MenuItem::Submenu:
135 if (!submenuDisabled(&(*i)))
138 case MenuItem::Command:
140 FuncStatus const flag =
141 view_->getLyXFunc().getStatus(i->func());
154 void GMenubar::onSubMenuActivate(MenuItem const * item,
155 Gtk::MenuItem * gitem)
157 Gtk::Menu * gmenu = gitem->get_submenu();
159 LyxMenu * lyxmenu = static_cast<LyxMenu*>(gmenu);
160 lyxmenu->clearBackMenu();
161 Menu * fmenu = item->submenuname().empty() ?
163 &menubackend.getMenu(item->submenuname());
165 menubackend.expand(*fmenu, lyxmenu->getBackMenu(), view_);
166 Menu::const_iterator i = lyxmenu->getBackMenu().begin();
167 Menu::const_iterator end = lyxmenu->getBackMenu().end();
168 Gtk::Menu * gmenu_new;
169 for (; i != end; ++i) {
171 case MenuItem::Submenu:
172 gmenu_new = new LyxMenu;
173 gmenu->items().push_back(
174 Gtk::Menu_Helpers::MenuElem(
175 labelTrans(i->label(), i->shortcut()),
177 gmenu->items().back().signal_activate().connect(
178 sigc::bind(sigc::mem_fun(*this, &GMenubar::onSubMenuActivate),
180 &gmenu->items().back()));
181 if (submenuDisabled(&(*i)))
182 gmenu->items().back().set_sensitive(false);
184 case MenuItem::Command:
186 FuncStatus const flag =
187 view_->getLyXFunc().getStatus(i->func());
188 bool on = flag.onoff(true);
189 bool off = flag.onoff(false);
192 gmenu->items().push_back(
193 Gtk::Menu_Helpers::CheckMenuElem(
194 labelTrans(i->label(),
196 Gtk::CheckMenuItem& citem =
197 static_cast<Gtk::CheckMenuItem&>(
198 gmenu->items().back());
199 citem.set_active(on);
201 // This is necessary because add_accel_label is protected,
202 // and even if you subclass Gtk::MenuItem then add_accel_label
203 // doesn't do what you'd expect.
204 Gtk::MenuItem * item = Gtk::manage(new Gtk::MenuItem);
205 Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox);
206 Gtk::Label * label1 = Gtk::manage(new Gtk::Label(
207 labelTrans(i->label(), i->shortcut()), true));
208 Gtk::Label * label2 = Gtk::manage(new Gtk::Label(
209 " " + i->binding(), false));
210 hbox->pack_start(*label1, false, false, 0);
211 hbox->pack_end(*label2, false, false, 0);
214 gmenu->append(*item);
217 Gtk::MenuItem & item = gmenu->items().back();
218 item.signal_activate().connect(
219 sigc::bind(sigc::mem_fun(*this, &GMenubar::onCommandActivate),
222 item.set_sensitive(false);
225 case MenuItem::Separator:
226 gmenu->items().push_back(
227 Gtk::Menu_Helpers::SeparatorElem());
230 lyxerr << "GMenubar::create_submenu: "
231 "this should not happen" << std::endl;
238 void GMenubar::onCommandActivate(MenuItem const * item,
239 Gtk::MenuItem * /*gitem*/)
241 view_->getLyXFunc().dispatch(item->func(), true);
244 } // namespace frontend