always-update is /obscenely/ slow. Furthermore, it seems it is impossible to safely delete items from the menus: Qt bug I believe.
I'm REALLY pissed off with Qt right now. Here's the patch if you want to try it. We need to figure out a better scheme, I'm afraid. And even then things might be fun given the response Qt gives me when I select LAyout->character a few times. regards john Index: Menubar_pimpl.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/Menubar_pimpl.C,v retrieving revision 1.9 diff -u -r1.9 Menubar_pimpl.C --- Menubar_pimpl.C 25 Jul 2002 02:24:36 -0000 1.9 +++ Menubar_pimpl.C 25 Jul 2002 03:40:51 -0000 @@ -29,6 +29,10 @@ #include "QtView.h" +// this is really taking the piss. "Internal" +// type returned by public members. Nice ! +#define INCLUDE_MENUITEM_DEF +#include <qapplication.h> #include <qmenubar.h> #include <qpopupmenu.h> @@ -69,8 +73,8 @@ Menubar::Pimpl::Pimpl(LyXView * view, MenuBackend const & mbe) : owner_(static_cast<QtView*>(view)), menubackend_(mbe) { - Menu::const_iterator m = mbe.getMenubar().begin(); - Menu::const_iterator end = mbe.getMenubar().end(); + Menu::const_iterator m = menubackend_.getMenubar().begin(); + Menu::const_iterator end = menubackend_.getMenubar().end(); for (; m != end; ++m) { Menu tomenu; Menu const frommenu = menubackend_.getMenu(m->submenuname()); @@ -84,10 +88,7 @@ { // FIXME: does this leak or not ? QPopupMenu * pm = new QPopupMenu(); - int const parentid = parent->insertItem(getLabel(*item).c_str(), pm); - - MenuItemInfo const info(parent, parentid, item); - items_[item->label()] = info; + parent->insertItem(getLabel(*item).c_str(), pm); return pm; } @@ -103,77 +104,55 @@ fillMenu(createMenu(qmenu, m), *m->submenu()); } else { qmenu->insertItem(getLabel(*m).c_str(), m->action()); - MenuItemInfo const info(qmenu, m->action(), m); - items_[m->label()] = info; - updateItem(info); + updateItem(qmenu, m); } } } -// FIXME: this is probably buggy with respect to enabling -// two-level submenus -void Menubar::Pimpl::updateSubmenu(MenuItemInfo const & i) -{ -#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) +void Menubar::Pimpl::updateItem(QMenuData * menu, MenuItem const * m) { - if (i.item_->kind() == MenuItem::Submenu) { - updateSubmenu(i); + if (m->kind() == MenuItem::Submenu) { + // FIXME return; } // FIXME - if (i.id_ < 0) + if (m->action() < 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)); + FuncStatus const status = owner_->getLyXFunc()->getStatus(m->action()); + menu->setItemEnabled(m->action(), !status.disabled()); + menu->setItemChecked(m->action(), 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(); + size_t i; + QMenuData const * bar(owner_->menuBar()); - for (; cit != end; ++cit) - updateItem(cit->second); + for (i = 0; i < bar->count(); ++i) { + bar->findItem(bar->idAt(i))->popup()->clear(); + } + + qApp->processEvents(); + + i = 0; + + Menu::const_iterator m = menubackend_.getMenubar().begin(); + Menu::const_iterator end = menubackend_.getMenubar().end(); + for (; m != end; ++m) { + Menu tomenu; + Menu const frommenu = menubackend_.getMenu(m->submenuname()); + menubackend_.expand(frommenu, tomenu, owner_->buffer()); + fillMenu(bar->findItem(bar->idAt(i))->popup(), tomenu); + ++i; + } } 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 } Index: Menubar_pimpl.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/qt2/Menubar_pimpl.h,v retrieving revision 1.6 diff -u -r1.6 Menubar_pimpl.h --- Menubar_pimpl.h 25 Jul 2002 02:24:36 -0000 1.6 +++ Menubar_pimpl.h 25 Jul 2002 03:40:51 -0000 @@ -33,26 +33,6 @@ class MenuItem; class MenuBackend; -/// stored state for menu items -struct MenuItemInfo { - // I REALLY hate this stupid requirement of std::map - MenuItemInfo::MenuItemInfo() - : parent_(0), id_(0), item_(0) {}; - - MenuItemInfo::MenuItemInfo(QMenuData * p, int id, MenuItem const * item) - : parent_(p), id_(id), item_(item) {}; - - /// menu containing item - QMenuData * parent_; - - /// id in containing menu - int id_; - - /// LyX info for item - MenuItem const * item_; -}; - - struct Menubar::Pimpl { public: Pimpl(LyXView *, MenuBackend const &); @@ -70,22 +50,14 @@ /// populate a menu (recursively) void fillMenu(QMenuData * qmenu, Menu const & menu); - /// special handling updating a submenu label - void updateSubmenu(MenuItemInfo const & i); - - /// update an individual item, returns true if enabled - void updateItem(MenuItemInfo const & i); + /// update an individual item + void updateItem(QMenuData * menu, MenuItem const * m); /// owning view QtView * owner_; /// menu controller MenuBackend const & menubackend_; - - typedef std::map<string, MenuItemInfo> ItemMap; - - /// menu items - ItemMap items_; }; #endif // MENUBAR_PIMPL_H