using std::min;
using std::for_each;
+namespace {
+
+string const getLabel(MenuItem const & mi)
+{
+ string const shortcut = mi.shortcut();
+ string label = mi.label();
+
+ label = subst(label, "&", "&&");
+
+ if (shortcut.empty())
+ return label;
+
+ string::size_type pos = label.find(shortcut);
+ if (pos == string::npos)
+ return label;
+ label.insert(pos, "&");
+
+ return label;
+}
+
+};
+
typedef vector<int>::size_type size_type;
extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
Menu::const_iterator m = mbe.getMenubar().begin();
Menu::const_iterator end = mbe.getMenubar().end();
for (; m != end; ++m) {
- makeMenu(owner_->menuBar(), *m);
+ Menu tomenu;
+ Menu const frommenu = menubackend_.getMenu(m->submenuname());
+ menubackend_.expand(frommenu, tomenu, owner_->buffer());
+ makeMenu(owner_->menuBar(), m, tomenu);
}
}
-void Menubar::Pimpl::makeMenu(QMenuData * parent, MenuItem const & menu)
+void Menubar::Pimpl::makeMenu(QMenuData * parent, MenuItem const * item, Menu const & menu)
{
- // FIXME: leak
+ // FIXME: does this leak or not ?
QPopupMenu * pm = new QPopupMenu();
- parent->insertItem(menu.label().c_str(), pm);
+ int const parentid = parent->insertItem(getLabel(*item).c_str(), pm);
- Menu md;
- menubackend_.getMenu(menu.submenu()).expand(md, 0);
- Menu::const_iterator m = md.begin();
- Menu::const_iterator end = md.end();
+ Menu::const_iterator m = menu.begin();
+ Menu::const_iterator end = menu.end();
for (; m != end; ++m) {
+ // FIXME: handle the special stuff here
if (m->kind() == MenuItem::Separator) {
pm->insertSeparator();
+ } else if (m->kind() == MenuItem::Submenu) {
+ makeMenu(pm, m, *m->submenu());
} else {
- pm->insertItem(m->label().c_str(), m->action());
- }
+ pm->insertItem(getLabel(*m).c_str(), m->action());
+ MenuItemInfo const info(pm, m->action(), m);
+ items_[m->label()] = info;
+ updateItem(info);
+ }
}
+
+ MenuItemInfo const info(parent, parentid, item);
+ items_[item->label()] = info;
+ updateSubmenu(info);
}
-void Menubar::Pimpl::openByName(string const & name)
+// FIXME: this is probably buggy with respect to enabling
+// two-level submenus
+void Menubar::Pimpl::updateSubmenu(MenuItemInfo const & i)
{
- lyxerr << "Menubar::Pimpl::openByName: menu " << name << endl;
-
-#if 0
- if (menubackend_->getMenu(current_menu_name_).hasSubmenu(name)) {
- for (ButtonList::const_iterator cit = buttonlist_.begin();
- cit != buttonlist_.end(); ++cit) {
- if ((*cit)->item_->submenu() == name) {
- MenuCallback((*cit)->obj_, 1);
- return;
- }
+#if 0 // SEGFAULTS
+// 7 0x0809d372 in Menu::begin (this=0x0) at MenuBackend.h:138
+// 8 0x081dcf60 in Menubar::Pimpl::updateSubmenu (this=0x839eaa0, i=@0xbffff010) at Menubar_pimpl.C:116
+ bool enable = false;
+
+ Menu::const_iterator m = i.item_->submenu().begin();
+ Menu::const_iterator end = i.item_->submenu().end();
+ for (; m != end; ++m) {
+ if (m->action() > 0) {
+ FuncStatus const status =
+ owner_->getLyXFunc()->getStatus(m->action());
+ if (!status.disabled())
+ enable = true;
}
}
+#else
+ bool enable = true;
#endif
+ i.parent_->setItemEnabled(i.id_, enable);
+}
+
+
+void Menubar::Pimpl::updateItem(MenuItemInfo const & i)
+{
+ if (i.item_->kind() == MenuItem::Submenu) {
+ updateSubmenu(i);
+ return;
+ }
+
+ // FIXME
+ if (i.id_ < 0)
+ return;
+
+ FuncStatus const status = owner_->getLyXFunc()->getStatus(i.id_);
+ i.parent_->setItemEnabled(i.id_, !status.disabled());
+ i.parent_->setItemChecked(i.id_, status.onoff(true));
+}
+
+
+void Menubar::Pimpl::update()
+{
+ // FIXME: handle special stuff to be updated.
+
+ ItemMap::const_iterator cit = items_.begin();
+ ItemMap::const_iterator end = items_.end();
+
+ for (; cit != end; ++cit)
+ updateItem(cit->second);
+}
+
+
+void Menubar::Pimpl::openByName(string const & name)
+{
+ lyxerr << "Menubar::Pimpl::openByName: menu " << name << endl;
+
+ ItemMap::iterator it = items_.find(name);
+
+ if (it == items_.end())
+ lyxerr << "NOT FOUND " << name << endl;
+
+ // FIXME
}