From a9114d0e446fac699ddaa717660a31288f185160 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Sat, 14 Aug 2004 18:06:10 +0000 Subject: [PATCH] the Qt/Mac merge menu patch; this is actually different from macmove8, so I hope it still works... git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8926 a592a061-630c-0410-9148-cb99ea01b6c8 --- lib/ChangeLog | 5 ++++ lib/ui/classic.ui | 10 +++++++ lib/ui/stdmenus.ui | 10 +++++++ src/ChangeLog | 20 +++++++++---- src/MenuBackend.C | 50 ++++++++++++++++++--------------- src/MenuBackend.h | 13 ++++++++- src/frontends/qt2/ChangeLog | 17 +++++++++++ src/frontends/qt2/QLMenubar.C | 21 ++++++-------- src/frontends/qt2/QLMenubar.h | 4 +-- src/frontends/qt2/QLPopupMenu.C | 35 +++++++++++++++++++++-- src/frontends/qt2/lyx_gui.C | 18 +++++++++++- 11 files changed, 157 insertions(+), 46 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index 788491b1c7..a2bcc12720 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,8 @@ +2004-08-14 Jean-Marc Lasgouttes + + * ui/stdmenus.ui: + * ui/classic.ui: add LyX menu + 2004-08-14 Bennett Helm * bind/mac.bind: new file. This is the Mac flavour bind file, based on diff --git a/lib/ui/classic.ui b/lib/ui/classic.ui index 04eddb56eb..39cfd87f98 100644 --- a/lib/ui/classic.ui +++ b/lib/ui/classic.ui @@ -407,6 +407,16 @@ Menuset Item "About LyX|X" "dialog-show aboutlyx" End +# +# LYX MENU - this menu is only used by LyX/Mac +# + + Menu "LyX" + Item "About LyX" "dialog-show aboutlyx" + Item "Preferences..." "dialog-show prefs" + Item "Quit LyX" "lyx-quit" + End + End # Which toolbars to use. diff --git a/lib/ui/stdmenus.ui b/lib/ui/stdmenus.ui index 39fc3f2808..a73a920d17 100644 --- a/lib/ui/stdmenus.ui +++ b/lib/ui/stdmenus.ui @@ -437,4 +437,14 @@ Menuset Item "About LyX...|X" "dialog-show aboutlyx" End +# +# LYX MENU - this menu is only used by LyX/Mac +# + + Menu "LyX" + Item "About LyX" "dialog-show aboutlyx" + Item "Preferences..." "dialog-show prefs" + Item "Quit LyX" "lyx-quit" + End + End diff --git a/src/ChangeLog b/src/ChangeLog index 9449533a90..2e1e3bd18c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2004-08-14 Jean-Marc Lasgouttes + + * MenuBackend.C (Menu::operator[]): new method to access + individual menu items + (Menu::hasFunc): new method. search for an item that corresponds + to a given func + (MenuBackend::specialMenu): new method + (MenuBackend::expand): if a special menu has been set, skip + entries whose func() appears in this menu + 2004-08-14 Lars Gullik Bjonnes * text3.C: use Debug::DEBUG a bit more @@ -22,11 +32,11 @@ * coordcache.[Ch]: * Makefile.am: new files to accomodate an 'external' (x,y)-position - cache for all insets in (at least partially) visible (top-level) - paragraphs. - - * BufferView_pimpl.C: reset external coord cache before every update. - This means the coord cache only contains valid entries. + cache for all insets in (at least partially) visible (top-level) + paragraphs. + + * BufferView_pimpl.C: reset external coord cache before every update. + This means the coord cache only contains valid entries. 2004-08-14 Lars Gullik Bjonnes diff --git a/src/MenuBackend.C b/src/MenuBackend.C index 543ba73c78..a4e02903c5 100644 --- a/src/MenuBackend.C +++ b/src/MenuBackend.C @@ -357,6 +357,20 @@ Menu & Menu::read(LyXLex & lex) } +MenuItem const & Menu::operator[](size_type i) const +{ + return items_[i]; +} + + +bool Menu::hasFunc(FuncRequest const & func) const +{ + return find_if(begin(), end(), + bind(std::equal_to(), + bind(&MenuItem::func, _1), + func)) != end(); +} + void Menu::checkShortcuts() const { // This is a quadratic algorithm, but we do not care because @@ -383,6 +397,13 @@ void Menu::checkShortcuts() const } +void MenuBackend::specialMenu(string const &name) +{ + if (hasMenu(name)) + specialmenu_ = &getMenu(name); +} + + namespace { class compare_format { @@ -775,8 +796,14 @@ void MenuBackend::expand(Menu const & frommenu, Menu & tomenu, } break; - default: + case MenuItem::Separator: tomenu.add(*cit, view); + break; + + case MenuItem::Command: + if (!specialmenu_ + || !specialmenu_->hasFunc(cit->func())) + tomenu.add(*cit, view); } } @@ -790,27 +817,6 @@ void MenuBackend::expand(Menu const & frommenu, Menu & tomenu, } -bool Menu::hasSubmenu(string const & name) const -{ -#if 1 - return find_if(begin(), end(), - bind(std::equal_to(), - bind(&MenuItem::submenuname, _1), - name)) != end(); -#else - // I would have prefered this, but I am not sure if it - // makes a difference. (Lgb) - return find_if( - make_transform_iterator(begin(), - bind(&MenuItem::submenuname, _1)), - make_transform_iterator(end(), - bind(&MenuItem::submenuname, _1)), - name - ).base() != end(); -#endif -} - - void MenuBackend::read(LyXLex & lex) { enum Menutags { diff --git a/src/MenuBackend.h b/src/MenuBackend.h index c704539eb0..2fe43c9ceb 100644 --- a/src/MenuBackend.h +++ b/src/MenuBackend.h @@ -156,7 +156,9 @@ public: /// ItemList::size_type size() const { return items_.size(); } /// - bool hasSubmenu(std::string const &) const; + MenuItem const & operator[](size_type) const; + /// + bool hasFunc(FuncRequest const &) const; /// const_iterator begin() const { return items_.begin(); @@ -188,6 +190,8 @@ public: /// typedef MenuList::iterator iterator; /// + MenuBackend::MenuBackend() : specialmenu_(0) {} + /// void read(LyXLex &); /// void add(Menu const &); @@ -201,6 +205,11 @@ public: Menu const & getMenubar() const; /// bool empty() const { return menulist_.empty(); } + /** This defines a menu whose entries list the FuncRequests + will be removed by expand() in other menus. This is used by + the Qt/Mac code + */ + void specialMenu(std::string const &); /// Expands some special entries of the menu /** The entries with the following kind are expanded to a sequence of Command MenuItems: Lastfiles, Documents, @@ -229,6 +238,8 @@ private: MenuList menulist_; /// Menu menubar_; + /// + Menu * specialmenu_; }; /// diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index ec8ba665a8..4982858d16 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,20 @@ +2004-08-11 Jean-Marc Lasgouttes + + Fix problem with the menu merging functionality of Qt/Mac. All the + code below is #ifdef Q_WS_MACX. + + * QLPopupMenu.C (showing): append dummy entries to one menu (so that + Qt/Mac moves them to the LyX menu) and give them special index value. + (fire): if index is more than indexOffset, dispatch to the + corresponding entry from the "LyX" menu. + + * lyx_gui.C (parse_init): add a new translator whose sole purpose + is to hide some menu entries from Qt/Mac scrutiny and avoid some + menu merging. + + * QLMenubar.C (QLMenubar): Use "LyX" as special menu; initialize + the contents of the first menu in the menubar + 2004-08-14 Jean-Marc Lasgouttes * QPrefsDialog.C (change_color): diff --git a/src/frontends/qt2/QLMenubar.C b/src/frontends/qt2/QLMenubar.C index ac979e6604..60780a6702 100644 --- a/src/frontends/qt2/QLMenubar.C +++ b/src/frontends/qt2/QLMenubar.C @@ -22,14 +22,13 @@ #include #include - using std::pair; using std::string; namespace lyx { namespace frontend { -QLMenubar::QLMenubar(LyXView * view, MenuBackend const & mbe) +QLMenubar::QLMenubar(LyXView * view, MenuBackend & mbe) : owner_(static_cast(view)), menubackend_(mbe) #ifdef Q_WS_MACX , menubar_(new QMenuBar) @@ -41,18 +40,14 @@ QLMenubar::QLMenubar(LyXView * view, MenuBackend const & mbe) pair menu = createMenu(menuBar(), &(*m), this, true); name_map_[m->submenuname()] = menu.second; -#ifdef Q_WS_MACX - /* The qt/mac menu code has a very silly hack that - moves some menu entries that it recognizes by name - (ex: "Preferences...") to the "LyX" menu. This - feature can only work if the menu entries are - always available. Since we build menus on demand, - we have to have a reasonable default value before - the menus have been explicitely opened. (JMarc) - */ - menu.second->showing(); -#endif } +#ifdef Q_WS_MACX + // this is the name of the menu that contains our special entries + menubackend_.specialMenu("LyX"); + // make sure that the special entries are added to the first + // menu even before this menu has been opened. + name_map_[mbe.getMenubar().begin()->submenuname()]->showing(); +#endif } void QLMenubar::openByName(string const & name) diff --git a/src/frontends/qt2/QLMenubar.h b/src/frontends/qt2/QLMenubar.h index 678ab34823..2cd740fc08 100644 --- a/src/frontends/qt2/QLMenubar.h +++ b/src/frontends/qt2/QLMenubar.h @@ -29,7 +29,7 @@ class QtView; class QLMenubar : public Menubar { public: - QLMenubar(LyXView *, MenuBackend const &); + QLMenubar(LyXView *, MenuBackend &); /// opens a top-level submenu given its name void openByName(std::string const &); @@ -47,7 +47,7 @@ private: QtView * owner_; /// menu controller - MenuBackend const & menubackend_; + MenuBackend & menubackend_; typedef std::map NameMap; diff --git a/src/frontends/qt2/QLPopupMenu.C b/src/frontends/qt2/QLPopupMenu.C index 4612ff62b9..c0089cd957 100644 --- a/src/frontends/qt2/QLPopupMenu.C +++ b/src/frontends/qt2/QLPopupMenu.C @@ -57,6 +57,11 @@ string const getLabel(MenuItem const & mi) return label; } +#ifdef Q_WS_MACX +// The offset added to the special Mac menu entries +const int indexOffset = 5000; +#endif + } // namespace anon @@ -84,7 +89,13 @@ QLPopupMenu::QLPopupMenu(QLMenubar * owner, void QLPopupMenu::fire(int index) { qApp->processEvents(); - owner_->view()->activated(funcs_[index]); +#ifdef Q_WS_MACX + if (index >= indexOffset) { + MenuItem mi = owner_->backend().getMenu("LyX")[index - indexOffset]; + owner_->view()->activated(mi.func()); + } else +#endif + owner_->view()->activated(funcs_[index]); } @@ -101,7 +112,7 @@ void QLPopupMenu::populate(Menu * menu) pair res = createMenu(this, &(*m), owner_); setItemEnabled(res.first, m->status().enabled()); res.second->populate(m->submenu()); - } else { + } else { // we have a MenuItem::Command FuncStatus const status = m->status(); Funcs::iterator fit = @@ -131,6 +142,8 @@ void QLPopupMenu::populate(Menu * menu) label += '\t' + toqstr(binding); } #endif + + // Actually insert the menu item insertItem(label, index); setItemEnabled(index, status.enabled()); setItemChecked(index, status.onoff(true)); @@ -146,6 +159,24 @@ void QLPopupMenu::showing() Menu const frommenu = owner_->backend().getMenu(name_); owner_->backend().expand(frommenu, tomenu, owner_->view()); populate(&tomenu); +#ifdef Q_WS_MACX + /* The qt/mac menu code has a very silly hack that + moves some menu entries that it recognizes by name + (e.g. "Preferences...") to the "LyX" menu. This + feature can only work if the menu entries are + always available. Since we build menus on demand, + we add some dummy contents to one of the menus (JMarc) + */ + static QLPopupMenu * themenu = this; + if (themenu == this && owner_->backend().hasMenu("LyX")) { + Menu special = owner_->backend().getMenu("LyX"); + Menu::const_iterator end = special.end(); + Menu::size_type i = 0; + for (Menu::const_iterator cit = special.begin(); + cit != end ; ++cit, ++i) + insertItem(toqstr(cit->label()), indexOffset + i); + } +#endif } } // namespace frontend diff --git a/src/frontends/qt2/lyx_gui.C b/src/frontends/qt2/lyx_gui.C index 92770b328b..fadcac418e 100644 --- a/src/frontends/qt2/lyx_gui.C +++ b/src/frontends/qt2/lyx_gui.C @@ -152,7 +152,6 @@ namespace lyx_gui { bool use_gui = true; - void parse_init(int & argc, char * argv[]) { static LQApplication app(argc, argv); @@ -175,6 +174,23 @@ void parse_init(int & argc, char * argv[]) << QTextCodec::locale() << std::endl; #endif +#ifdef Q_WS_MACX + // These translations are meant to break Qt/Mac menu merging + // algorithm on some entries. It lists the menu names that + // should not be moved to the LyX menu + static QTranslator aqua_trans(0); + aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setting", 0, + "do_not_merge_me")); + aqua_trans.insert(QTranslatorMessage("QMenuBar", "Config", 0, + "do_not_merge_me")); + aqua_trans.insert(QTranslatorMessage("QMenuBar", "Options", 0, + "do_not_merge_me")); + aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setup", 0, + "do_not_merge_me")); + + app.installTranslator(&aqua_trans); +#endif + using namespace lyx::graphics; Image::newImage = boost::bind(&QLImage::newImage);