]> git.lyx.org Git - features.git/commitdiff
Encapsulate all menu related stuff inside Menu.cpp and simplify a few things.
authorAbdelrazak Younes <younes@lyx.org>
Sat, 8 Mar 2008 15:33:52 +0000 (15:33 +0000)
committerAbdelrazak Younes <younes@lyx.org>
Sat, 8 Mar 2008 15:33:52 +0000 (15:33 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23560 a592a061-630c-0410-9148-cb99ea01b6c8

src/frontends/qt4/GuiApplication.cpp
src/frontends/qt4/GuiPopupMenu.cpp [deleted file]
src/frontends/qt4/GuiPopupMenu.h [deleted file]
src/frontends/qt4/GuiSymbols.cpp
src/frontends/qt4/GuiView.cpp
src/frontends/qt4/Makefile.am
src/frontends/qt4/Menus.cpp
src/frontends/qt4/Menus.h

index 5c9d04894ca33aeb6d4259c07c445f8de076060b..e76f726904ef7f06cc8cde122bac6a2043947227 100644 (file)
@@ -658,7 +658,7 @@ void GuiApplication::readMenus(Lexer & lex)
 bool GuiApplication::searchMenu(FuncRequest const & func,
        vector<docstring> & names) const
 {
-       return menus().getMenubar().searchMenu(func, names);
+       return menus().searchMenu(func, names);
 }
 
 
diff --git a/src/frontends/qt4/GuiPopupMenu.cpp b/src/frontends/qt4/GuiPopupMenu.cpp
deleted file mode 100644 (file)
index 163be87..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * \file GuiPopupMenu.cpp
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author John Levon
- * \author Abdelrazak Younes
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#include <config.h>
-
-#include "GuiPopupMenu.h"
-
-#include "Action.h"
-#include "GuiApplication.h"
-#include "GuiView.h"
-#include "qt_helpers.h"
-
-#include "LyXFunc.h"
-
-#include "support/debug.h"
-
-namespace lyx {
-namespace frontend {
-
-GuiPopupMenu::GuiPopupMenu(GuiView * owner, MenuItem const & mi,
-               bool topLevelMenu)
-       : QMenu(owner), owner_(owner)
-{
-       name_ = mi.submenuname();
-
-       setTitle(label(mi));
-
-       if (topLevelMenu)
-               connect(this, SIGNAL(aboutToShow()), this, SLOT(updateView()));
-}
-
-
-void GuiPopupMenu::updateView()
-{
-       LYXERR(Debug::GUI, "GuiPopupMenu::updateView()"
-               << "\tTriggered menu: " << fromqstr(name_));
-
-       clear();
-
-       if (name_.isEmpty())
-               return;
-
-       // Here, We make sure that theLyXFunc points to the correct LyXView.
-       theLyXFunc().setLyXView(owner_);
-
-       Menus const & menus = guiApp->menus();
-       Menu const & fromLyxMenu = menus.getMenu(name_);
-       menus.expand(fromLyxMenu, topLevelMenu_, owner_->buffer());
-
-       if (!menus.hasMenu(topLevelMenu_.name())) {
-               LYXERR(Debug::GUI, "\tWARNING: menu seems empty"
-                       << fromqstr(topLevelMenu_.name()));
-       }
-       populate(this, &topLevelMenu_);
-}
-
-
-void GuiPopupMenu::populate(QMenu * qMenu, Menu * menu)
-{
-       LYXERR(Debug::GUI, "populating menu " << fromqstr(menu->name()));
-       if (menu->size() == 0) {
-               LYXERR(Debug::GUI, "\tERROR: empty menu " << fromqstr(menu->name()));
-               return;
-       }
-       LYXERR(Debug::GUI, " *****  menu entries " << menu->size());
-
-       Menu::const_iterator m = menu->begin();
-       Menu::const_iterator end = menu->end();
-
-       for (; m != end; ++m) {
-
-               if (m->kind() == MenuItem::Separator) {
-
-                       qMenu->addSeparator();
-                       LYXERR(Debug::GUI, "adding Menubar Separator");
-
-               } else if (m->kind() == MenuItem::Submenu) {
-
-                       LYXERR(Debug::GUI, "** creating New Sub-Menu "
-                               << fromqstr(label(*m)));
-                       QMenu * subMenu = qMenu->addMenu(label(*m));
-                       populate(subMenu, m->submenu());
-
-               } else { // we have a MenuItem::Command
-
-                       LYXERR(Debug::GUI, "creating Menu Item "
-                               << fromqstr(m->label()));
-
-                       Action * action = new Action(*owner_,
-                               QIcon(), label(*m), m->func(), QString());
-                       qMenu->addAction(action);
-               }
-       }
-}
-
-
-QString GuiPopupMenu::label(MenuItem const & mi) const
-{
-       QString label = mi.label();
-       label.replace("&", "&&");
-
-       QString shortcut = mi.shortcut();
-       if (!shortcut.isEmpty()) {
-               int pos = label.indexOf(shortcut);
-               if (pos != -1)
-                       //label.insert(pos, 1, char_type('&'));
-                       label.replace(pos, 0, "&");
-       }
-
-       QString const binding = mi.binding();
-       if (!binding.isEmpty())
-               label += '\t' + binding;
-
-       return label;
-}
-
-
-} // namespace frontend
-} // namespace lyx
-
-#include "GuiPopupMenu_moc.cpp"
diff --git a/src/frontends/qt4/GuiPopupMenu.h b/src/frontends/qt4/GuiPopupMenu.h
deleted file mode 100644 (file)
index e17fd63..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-// -*- C++ -*-
-/**
- * \file GuiPopupMenu.h
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author John Levon
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#ifndef GUIPOPUPMENU_H
-#define GUIPOPUPMENU_H
-
-#include "Menus.h"
-
-#include <QMenu>
-
-namespace lyx {
-namespace frontend {
-
-class GuiView;
-
-/// a submenu
-class GuiPopupMenu : public QMenu
-{
-       Q_OBJECT
-public:
-       ///
-       GuiPopupMenu(GuiView * owner, MenuItem const & mi,
-               bool topLevelMenu = false);
-
-       /// populates the menu or one of its submenu
-       /// This is used as a recursive function
-       void populate(QMenu * qMenu, Menu * menu);
-
-public Q_SLOTS:
-       /// populate the toplevel menu and all children
-       void updateView();
-
-private:
-       /// Get a Menu item label from the menu backend
-       QString label(MenuItem const & mi) const;
-
-       /// our owning view
-       GuiView * owner_;
-       /// the name of this menu
-       QString name_;
-       /// Top Level Menu
-       Menu topLevelMenu_;
-};
-
-} // namespace frontend
-} // namespace lyx
-
-#endif // GUIPOPUPMENU_H
index 3a47a5de1a60670a5d5781855ca2a97177e5b7c6..5486f5c1bf8f4b5e780248e0c30cd877a5edf5ea 100644 (file)
@@ -20,6 +20,7 @@
 #include "BufferParams.h"
 #include "BufferView.h"
 #include "Encoding.h"
+#include "FuncRequest.h"
 
 #include "support/gettext.h"
 
index 10cda4668a4aa20f3fd78b78dd0e898de9321115..eefe3ee1530cfbf3045b42e30938695785bd3c55 100644 (file)
@@ -37,6 +37,7 @@
 #include "Cursor.h"
 #include "ErrorList.h"
 #include "Format.h"
+#include "FuncStatus.h"
 #include "FuncRequest.h"
 #include "support/gettext.h"
 #include "Intl.h"
index dfea39dedd6a082d4862e265e84be6b1aad8f4d5..ab6778e980af53c5956874e854717a4abbfe5f19 100644 (file)
@@ -98,7 +98,6 @@ SOURCEFILES = \
        GuiNote.cpp \
        GuiPainter.cpp \
        GuiParagraph.cpp \
-       GuiPopupMenu.cpp \
        GuiPrefs.cpp \
        GuiPrint.cpp \
        GuiRef.cpp \
@@ -150,6 +149,7 @@ NOMOCHEADER = \
        GuiPainter.h \
        GuiToolbars.h \
        LaTeXHighlighter.h \
+       Menus.h \
        qt_helpers.h
 
 MOCHEADER = \
@@ -189,7 +189,6 @@ MOCHEADER = \
        GuiNomencl.h \
        GuiNote.h \
        GuiParagraph.h \
-       GuiPopupMenu.h \
        GuiPrefs.h \
        GuiPrint.h \
        GuiRef.h \
@@ -216,7 +215,6 @@ MOCHEADER = \
        InsertTableWidget.h \
        LengthCombo.h \
        LyXFileDialog.h \
-       Menus.h \
        PanelStack.h \
        TocModel.h \
        TocWidget.h \
index 4d83752d2d12bd168c878fe9d52a649ab90273f8..ddb88862163804d0f3deaa9a624b0f02d25de725 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "Action.h"
 #include "GuiApplication.h"
-#include "GuiPopupMenu.h"
 #include "GuiView.h"
 
 #include "BranchList.h"
 #include "Floating.h"
 #include "FloatList.h"
 #include "Format.h"
+#include "FuncRequest.h"
+#include "FuncStatus.h"
 #include "KeyMap.h"
-#include "Session.h"
+#include "Lexer.h"
 #include "LyXAction.h"
 #include "LyX.h" // for lastfiles
 #include "LyXFunc.h"
-#include "Lexer.h"
 #include "Paragraph.h"
+#include "qt_helpers.h"
+#include "Session.h"
 #include "TextClass.h"
 #include "TocBackend.h"
 #include "ToolbarBackend.h"
 
-#include "frontends/Application.h"
-
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/filetools.h"
 #include "support/gettext.h"
 #include "support/lstrings.h"
 
-#include "qt_helpers.h"
-
 #include <QCursor>
+#include <QHash>
 #include <QMenuBar>
+#include <QString>
+
+#include <boost/shared_ptr.hpp>
 
 #include <algorithm>
 #include <ostream>
+#include <vector>
 
 using namespace std;
 using namespace lyx::support;
@@ -68,6 +71,228 @@ namespace frontend {
 
 namespace {
 
+// MacOSX specific stuff is at the end.
+
+class Menu;
+
+///
+class MenuItem {
+public:
+       /// The type of elements that can be in a menu
+       enum Kind {
+               ///
+               Command,
+               ///
+               Submenu,
+               ///
+               Separator,
+               /** This is the list of last opened file,
+                   typically for the File menu. */
+               Lastfiles,
+               /** This is the list of opened Documents,
+                   typically for the Documents menu. */
+               Documents,
+               /** This is the bookmarks */
+               Bookmarks,
+               ///
+               Toc,
+               /** This is a list of viewable formats
+                   typically for the File->View menu. */
+               ViewFormats,
+               /** This is a list of updatable formats
+                   typically for the File->Update menu. */
+               UpdateFormats,
+               /** This is a list of exportable formats
+                   typically for the File->Export menu. */
+               ExportFormats,
+               /** This is a list of importable formats
+                   typically for the File->Export menu. */
+               ImportFormats,
+               /** This is the list of elements available
+                * for insertion into document. */
+               CharStyles,
+               /** This is the list of user-configurable
+               insets to insert into document */
+               Custom,
+               /** This is the list of XML elements to
+               insert into the document */
+               Elements,
+               /** This is the list of floats that we can
+                   insert a list for. */
+               FloatListInsert,
+               /** This is the list of floats that we can
+                   insert. */
+               FloatInsert,
+               /** This is the list of selections that can
+                   be pasted. */
+               PasteRecent,
+               /** toolbars */
+               Toolbars,
+               /** Available branches in document */
+               Branches
+       };
+
+       explicit MenuItem(Kind kind);
+
+       MenuItem(Kind kind,
+                QString const & label,
+                QString const & submenu = QString(),
+                bool optional = false);
+
+       MenuItem(Kind kind,
+                QString const & label,
+                FuncRequest const & func,
+                bool optional = false);
+
+       /// This one is just to please boost::shared_ptr<>
+       ~MenuItem();
+       /// The label of a given menuitem
+       QString label() const;
+       /// The keyboard shortcut (usually underlined in the entry)
+       QString shortcut() const;
+       /// The complete label, with label and shortcut separated by a '|'
+       QString fulllabel() const { return label_;}
+       /// The kind of entry
+       Kind kind() const { return kind_; }
+       /// the action (if relevant)
+       FuncRequest const & func() const { return func_; }
+       /// returns true if the entry should be ommited when disabled
+       bool optional() const { return optional_; }
+       /// returns the status of the lfun associated with this entry
+       FuncStatus const & status() const { return status_; }
+       /// returns the status of the lfun associated with this entry
+       FuncStatus & status() { return status_; }
+       /// returns the status of the lfun associated with this entry
+       void status(FuncStatus const & status) { status_ = status; }
+       ///returns the binding associated to this action.
+       QString binding() const;
+       /// the description of the  submenu (if relevant)
+       QString const & submenuname() const { return submenuname_; }
+       /// set the description of the  submenu
+       void submenuname(QString const & name) { submenuname_ = name; }
+       ///
+       Menu * submenu() const { return submenu_.get(); }
+       ///
+       void setSubmenu(Menu * menu);
+
+private:
+       ///
+       Kind kind_;
+       ///
+       QString label_;
+       ///
+       FuncRequest func_;
+       ///
+       QString submenuname_;
+       ///
+       bool optional_;
+       ///
+       FuncStatus status_;
+       ///
+       boost::shared_ptr<Menu> submenu_;
+};
+
+///
+class Menu {
+public:
+       ///
+       typedef std::vector<MenuItem> ItemList;
+       ///
+       typedef ItemList::const_iterator const_iterator;
+
+       ///
+       explicit Menu(QString const & name = QString()) : name_(name) {}
+
+       ///
+       void read(Lexer &);
+       ///
+       QString const & name() const { return name_; }
+       ///
+       bool empty() const { return items_.empty(); }
+       /// Clear the menu content.
+       void clear() { items_.clear(); }
+       ///
+       size_t size() const { return items_.size(); }
+       ///
+       MenuItem const & operator[](size_t) const;
+       ///
+       const_iterator begin() const { return items_.begin(); }
+       ///
+       const_iterator end() const { return items_.end(); }
+       
+       // search for func in this menu iteratively, and put menu
+       // names in a stack.
+       bool searchMenu(FuncRequest const & func, std::vector<docstring> & names)
+               const;
+
+private:
+       friend class Menus;
+       ///
+       bool hasFunc(FuncRequest const &) const;
+       /// Add the menu item unconditionally
+       void add(MenuItem const & item) { items_.push_back(item); }
+       /// Checks the associated FuncRequest status before adding the
+       /// menu item.
+       void addWithStatusCheck(MenuItem const &);
+       // Check whether the menu shortcuts are unique
+       void checkShortcuts() const;
+       ///
+       void expandLastfiles();
+       void expandDocuments();
+       void expandBookmarks();
+       void expandFormats(MenuItem::Kind kind, Buffer const * buf);
+       void expandFloatListInsert(Buffer const * buf);
+       void expandFloatInsert(Buffer const * buf);
+       void expandFlexInsert(Buffer const * buf, std::string s);
+       void expandToc2(Toc const & toc_list, size_t from, size_t to, int depth);
+       void expandToc(Buffer const * buf);
+       void expandPasteRecent();
+       void expandToolbars();
+       void expandBranches(Buffer const * buf);
+
+       ItemList items_;
+       ///
+       QString name_;
+};
+
+/// a submenu
+class GuiPopupMenu : public QMenu
+{
+public:
+       ///
+       GuiPopupMenu(GuiView * owner, MenuItem const & mi, bool top_level)
+               : QMenu(owner), owner_(owner), top_level_(top_level)
+       {
+               name_ = mi.submenuname();
+               setTitle(label(mi));
+       }
+
+       /// populates the menu or one of its submenu
+       /// This is used as a recursive function
+       void populate(QMenu * qMenu, Menu * menu);
+
+       /// Get a Menu item label from the menu backend
+       QString label(MenuItem const & mi) const;
+
+       void showEvent(QShowEvent * ev)
+       {
+               if (top_level_)
+                       guiApp->menus().updateMenu(name_);
+               QMenu::showEvent(ev);
+       }
+
+       bool const top_level_;
+
+       ///
+       Menu topLevelMenu_;
+
+       /// our owning view
+       GuiView * owner_;
+       /// the name of this menu
+       QString name_;
+};
+
+
 class MenuNamesEqual
 {
 public:
@@ -77,9 +302,136 @@ private:
        QString name_;
 };
 
+///
+typedef std::vector<Menu> MenuList;
+///
+typedef MenuList::const_iterator const_iterator;
+///
+typedef MenuList::iterator iterator;
+
+
+void GuiPopupMenu::populate(QMenu * qMenu, Menu * menu)
+{
+       LYXERR(Debug::GUI, "populating menu " << fromqstr(menu->name()));
+       if (menu->size() == 0) {
+               LYXERR(Debug::GUI, "\tERROR: empty menu " << fromqstr(menu->name()));
+               return;
+       }
+       LYXERR(Debug::GUI, " *****  menu entries " << menu->size());
+
+       Menu::const_iterator m = menu->begin();
+       Menu::const_iterator end = menu->end();
+
+       for (; m != end; ++m) {
+
+               if (m->kind() == MenuItem::Separator) {
+
+                       qMenu->addSeparator();
+                       LYXERR(Debug::GUI, "adding Menubar Separator");
+
+               } else if (m->kind() == MenuItem::Submenu) {
+
+                       LYXERR(Debug::GUI, "** creating New Sub-Menu "
+                               << fromqstr(label(*m)));
+                       QMenu * subMenu = qMenu->addMenu(label(*m));
+                       populate(subMenu, m->submenu());
+
+               } else { // we have a MenuItem::Command
+
+                       LYXERR(Debug::GUI, "creating Menu Item "
+                               << fromqstr(m->label()));
+
+                       Action * action = new Action(*owner_,
+                               QIcon(), label(*m), m->func(), QString());
+                       qMenu->addAction(action);
+               }
+       }
+}
+
+
+QString GuiPopupMenu::label(MenuItem const & mi) const
+{
+       QString label = mi.label();
+       label.replace("&", "&&");
+
+       QString shortcut = mi.shortcut();
+       if (!shortcut.isEmpty()) {
+               int pos = label.indexOf(shortcut);
+               if (pos != -1)
+                       //label.insert(pos, 1, char_type('&'));
+                       label.replace(pos, 0, "&");
+       }
+
+       QString const binding = mi.binding();
+       if (!binding.isEmpty())
+               label += '\t' + binding;
+
+       return label;
+}
+
 } // namespace anon
 
-// MacOSX specific stuff is at the end.
+struct Menus::Impl {
+       ///
+       void add(Menu const &);
+       ///
+       bool hasMenu(QString const &) const;
+       ///
+       Menu & getMenu(QString const &);
+       ///
+       Menu const & getMenu(QString const &) const;
+       ///
+       bool empty() const { return menulist_.empty(); }
+       /** This defines a menu whose entries list the FuncRequests
+           that will be removed by expand() in other menus. This is
+           used by the Qt/Mac code
+       */
+       void setSpecialMenu(Menu const & menu) { specialmenu_ = menu; }
+       ///
+       Menu const & specialMenu() { return specialmenu_; }
+
+       /// Expands some special entries of the menu
+       /** The entries with the following kind are expanded to a
+           sequence of Command MenuItems: Lastfiles, Documents,
+           ViewFormats, ExportFormats, UpdateFormats, Branches
+       */
+       void expand(Menu const & frommenu, Menu & tomenu,
+                   Buffer const *) const;
+       ///
+       const_iterator begin() const { return menulist_.begin(); }
+       ///
+       iterator begin() { return menulist_.begin(); }
+       ///
+       const_iterator end() const { return menulist_.end(); }
+       ///
+       iterator end() { return menulist_.end(); }
+
+       ///
+       MenuList menulist_;
+       ///
+       Menu menubar_;
+       ///
+       Menu specialmenu_;
+
+       /// Initialize specific MACOS X menubar
+       void macxMenuBarInit(GuiView * view);
+
+       typedef QHash<QString, GuiPopupMenu *> NameMap;
+
+       /// name to menu for \c menu() method.
+       NameMap name_map_;
+};
+
+
+Menus::Menus(): d(new Impl) {}
+
+
+bool Menus::searchMenu(FuncRequest const & func,
+       vector<docstring> & names) const
+{
+       return d->menubar_.searchMenu(func, names);
+}
+
 
 void Menus::fillMenuBar(GuiView * view)
 {
@@ -91,20 +443,20 @@ void Menus::fillMenuBar(GuiView * view)
        macxMenuBarInit(view);
 #endif
 
-       LYXERR(Debug::GUI, "populating menu bar" << fromqstr(getMenubar().name()));
+       LYXERR(Debug::GUI, "populating menu bar" << fromqstr(d->menubar_.name()));
 
-       if (getMenubar().size() == 0) {
+       if (d->menubar_.size() == 0) {
                LYXERR(Debug::GUI, "\tERROR: empty menu bar"
-                       << fromqstr(getMenubar().name()));
+                       << fromqstr(d->menubar_.name()));
                return;
        }
        else {
                LYXERR(Debug::GUI, "menu bar entries "
-                       << getMenubar().size());
+                       << d->menubar_.size());
        }
 
        Menu menu;
-       expand(getMenubar(), menu, view->buffer());
+       d->expand(d->menubar_, menu, view->buffer());
 
        Menu::const_iterator m = menu.begin();
        Menu::const_iterator end = menu.end();
@@ -120,24 +472,48 @@ void Menus::fillMenuBar(GuiView * view)
                        << " is a submenu named " << fromqstr(m->submenuname()));
 
                QString name = m->submenuname();
-               if (!hasMenu(name)) {
+               if (!d->hasMenu(name)) {
                        LYXERR(Debug::GUI, "\tERROR: " << fromqstr(name)
                                << " submenu has no menu!");
                        continue;
                }
 
-               GuiPopupMenu * qMenu = new GuiPopupMenu(view, *m, true);
-               view->menuBar()->addMenu(qMenu);
+               GuiPopupMenu * qmenu = new GuiPopupMenu(view, *m, true);
+               view->menuBar()->addMenu(qmenu);
+
+               d->name_map_[name] = qmenu;
+       }
+}
+
+
+void Menus::updateMenu(QString const & name)
+{
+       GuiPopupMenu * qmenu = d->name_map_[name];
+       LYXERR(Debug::GUI, "GuiPopupMenu::updateView()"
+               << "\tTriggered menu: " << fromqstr(qmenu->name_));
+       qmenu->clear();
+
+       if (qmenu->name_.isEmpty())
+               return;
+
+       // Here, We make sure that theLyXFunc points to the correct LyXView.
+       theLyXFunc().setLyXView(qmenu->owner_);
 
-               name_map_[name] = qMenu;
+       Menu const & fromLyxMenu = d->getMenu(qmenu->name_);
+       d->expand(fromLyxMenu, qmenu->topLevelMenu_, qmenu->owner_->buffer());
+
+       if (!d->hasMenu(qmenu->topLevelMenu_.name())) {
+               LYXERR(Debug::GUI, "\tWARNING: menu seems empty"
+                       << fromqstr(qmenu->topLevelMenu_.name()));
        }
+       qmenu->populate(qmenu, &qmenu->topLevelMenu_);
 }
 
 
 QMenu * Menus::menu(QString const & name)
 {
        LYXERR(Debug::GUI, "Context menu requested: " << fromqstr(name));
-       GuiPopupMenu * menu = name_map_.value(name, 0);
+       GuiPopupMenu * menu = d->name_map_.value(name, 0);
        if (!menu)
                LYXERR0("resquested context menu not found: " << fromqstr(name));
        return menu;
@@ -168,7 +544,7 @@ QMenu * Menus::menu(QString const & name)
   focus. (JMarc)
 */
 
-void Menus::macxMenuBarInit(GuiView * view)
+void Menus::Impl::macxMenuBarInit(GuiView * view)
 {
        // The Mac menubar initialisation must be done only once!
        static bool done = false;
@@ -1012,7 +1388,7 @@ void Menu::expandBranches(Buffer const * buf)
 }
 
 
-void Menus::expand(Menu const & frommenu, Menu & tomenu,
+void Menus::Impl::expand(Menu const & frommenu, Menu & tomenu,
                         Buffer const * buf) const
 {
        if (!tomenu.empty())
@@ -1135,17 +1511,17 @@ void Menus::read(Lexer & lex)
        while (lex.isOK() && !quit) {
                switch (lex.lex()) {
                case md_menubar:
-                       menubar_.read(lex);
+                       d->menubar_.read(lex);
                        break;
                case md_menu: {
                        lex.next(true);
                        QString const name = toqstr(lex.getDocString());
-                       if (hasMenu(name)) {
-                               getMenu(name).read(lex);
+                       if (d->hasMenu(name)) {
+                               d->getMenu(name).read(lex);
                        } else {
                                Menu menu(name);
                                menu.read(lex);
-                               add(menu);
+                               d->add(menu);
                        }
                        break;
                }
@@ -1162,19 +1538,19 @@ void Menus::read(Lexer & lex)
 }
 
 
-void Menus::add(Menu const & menu)
+void Menus::Impl::add(Menu const & menu)
 {
        menulist_.push_back(menu);
 }
 
 
-bool Menus::hasMenu(QString const & name) const
+bool Menus::Impl::hasMenu(QString const & name) const
 {
        return find_if(begin(), end(), MenuNamesEqual(name)) != end();
 }
 
 
-Menu const & Menus::getMenu(QString const & name) const
+Menu const & Menus::Impl::getMenu(QString const & name) const
 {
        const_iterator cit = find_if(begin(), end(), MenuNamesEqual(name));
        if (cit == end())
@@ -1184,7 +1560,7 @@ Menu const & Menus::getMenu(QString const & name) const
 }
 
 
-Menu & Menus::getMenu(QString const & name)
+Menu & Menus::Impl::getMenu(QString const & name)
 {
        iterator it = find_if(begin(), end(), MenuNamesEqual(name));
        if (it == end())
@@ -1194,12 +1570,6 @@ Menu & Menus::getMenu(QString const & name)
 }
 
 
-Menu const & Menus::getMenubar() const
-{
-       return menubar_;
-}
-
-
 } // namespace frontend
 } // namespace lyx
 
index 3f89f3f9d735e2ade4097a539256528c06ff482e..a266f0c9e6c77976722e85f8966717f5512e7915 100644 (file)
 #ifndef MENUS_H
 #define MENUS_H
 
-#include "FuncStatus.h"
-#include "FuncRequest.h"
-
-#include "support/strfwd.h"
-
-#include <QObject>
-#include <QHash>
-
-#include <boost/shared_ptr.hpp>
+#include "support/docstring.h"
 
 #include <vector>
 
 class QMenu;
+class QString;
 
 namespace lyx {
 
 class Lexer;
 class Buffer;
+class FuncRequest;
 class Toc;
 
 namespace frontend {
 
-class Menu;
 class GuiView;
-class GuiPopupMenu;
-class GuiView;
-
-///
-class MenuItem {
-public:
-       /// The type of elements that can be in a menu
-       enum Kind {
-               ///
-               Command,
-               ///
-               Submenu,
-               ///
-               Separator,
-               /** This is the list of last opened file,
-                   typically for the File menu. */
-               Lastfiles,
-               /** This is the list of opened Documents,
-                   typically for the Documents menu. */
-               Documents,
-               /** This is the bookmarks */
-               Bookmarks,
-               ///
-               Toc,
-               /** This is a list of viewable formats
-                   typically for the File->View menu. */
-               ViewFormats,
-               /** This is a list of updatable formats
-                   typically for the File->Update menu. */
-               UpdateFormats,
-               /** This is a list of exportable formats
-                   typically for the File->Export menu. */
-               ExportFormats,
-               /** This is a list of importable formats
-                   typically for the File->Export menu. */
-               ImportFormats,
-               /** This is the list of elements available
-                * for insertion into document. */
-               CharStyles,
-               /** This is the list of user-configurable
-               insets to insert into document */
-               Custom,
-               /** This is the list of XML elements to
-               insert into the document */
-               Elements,
-               /** This is the list of floats that we can
-                   insert a list for. */
-               FloatListInsert,
-               /** This is the list of floats that we can
-                   insert. */
-               FloatInsert,
-               /** This is the list of selections that can
-                   be pasted. */
-               PasteRecent,
-               /** toolbars */
-               Toolbars,
-               /** Available branches in document */
-               Branches
-       };
-
-       explicit MenuItem(Kind kind);
-
-       MenuItem(Kind kind,
-                QString const & label,
-                QString const & submenu = QString(),
-                bool optional = false);
-
-       MenuItem(Kind kind,
-                QString const & label,
-                FuncRequest const & func,
-                bool optional = false);
-
-       /// This one is just to please boost::shared_ptr<>
-       ~MenuItem();
-       /// The label of a given menuitem
-       QString label() const;
-       /// The keyboard shortcut (usually underlined in the entry)
-       QString shortcut() const;
-       /// The complete label, with label and shortcut separated by a '|'
-       QString fulllabel() const { return label_;}
-       /// The kind of entry
-       Kind kind() const { return kind_; }
-       /// the action (if relevant)
-       FuncRequest const & func() const { return func_; }
-       /// returns true if the entry should be ommited when disabled
-       bool optional() const { return optional_; }
-       /// returns the status of the lfun associated with this entry
-       FuncStatus const & status() const { return status_; }
-       /// returns the status of the lfun associated with this entry
-       FuncStatus & status() { return status_; }
-       /// returns the status of the lfun associated with this entry
-       void status(FuncStatus const & status) { status_ = status; }
-       ///returns the binding associated to this action.
-       QString binding() const;
-       /// the description of the  submenu (if relevant)
-       QString const & submenuname() const { return submenuname_; }
-       /// set the description of the  submenu
-       void submenuname(QString const & name) { submenuname_ = name; }
-       ///
-       Menu * submenu() const { return submenu_.get(); }
-       ///
-       void setSubmenu(Menu * menu);
-
-private:
-       ///
-       Kind kind_;
-       ///
-       QString label_;
-       ///
-       FuncRequest func_;
-       ///
-       QString submenuname_;
-       ///
-       bool optional_;
-       ///
-       FuncStatus status_;
-       ///
-       boost::shared_ptr<Menu> submenu_;
-};
-
-
-///
-class Menu {
-public:
-       ///
-       typedef std::vector<MenuItem> ItemList;
-       ///
-       typedef ItemList::const_iterator const_iterator;
-
-       ///
-       explicit Menu(QString const & name = QString()) : name_(name) {}
-
-       ///
-       void read(Lexer &);
-       ///
-       QString const & name() const { return name_; }
-       ///
-       bool empty() const { return items_.empty(); }
-       /// Clear the menu content.
-       void clear() { items_.clear(); }
-       ///
-       size_t size() const { return items_.size(); }
-       ///
-       MenuItem const & operator[](size_t) const;
-       ///
-       const_iterator begin() const { return items_.begin(); }
-       ///
-       const_iterator end() const { return items_.end(); }
-       
-       // search for func in this menu iteratively, and put menu
-       // names in a stack.
-       bool searchMenu(FuncRequest const & func, std::vector<docstring> & names)
-               const;
-
-private:
-       friend class Menus;
-       ///
-       bool hasFunc(FuncRequest const &) const;
-       /// Add the menu item unconditionally
-       void add(MenuItem const & item) { items_.push_back(item); }
-       /// Checks the associated FuncRequest status before adding the
-       /// menu item.
-       void addWithStatusCheck(MenuItem const &);
-       // Check whether the menu shortcuts are unique
-       void checkShortcuts() const;
-       ///
-       void expandLastfiles();
-       void expandDocuments();
-       void expandBookmarks();
-       void expandFormats(MenuItem::Kind kind, Buffer const * buf);
-       void expandFloatListInsert(Buffer const * buf);
-       void expandFloatInsert(Buffer const * buf);
-       void expandFlexInsert(Buffer const * buf, std::string s);
-       void expandToc2(Toc const & toc_list, size_t from, size_t to, int depth);
-       void expandToc(Buffer const * buf);
-       void expandPasteRecent();
-       void expandToolbars();
-       void expandBranches(Buffer const * buf);
-
-       ItemList items_;
-       ///
-       QString name_;
-};
-
 
 class Menus
 {
 public:
+       Menus();
+       
        ///
-       typedef std::vector<Menu> MenuList;
-       ///
-       typedef MenuList::const_iterator const_iterator;
-       ///
-       typedef MenuList::iterator iterator;
-
-
-       Menus() {}
-
+       bool searchMenu(FuncRequest const & func,
+               std::vector<docstring> & names) const;
        ///
        void fillMenuBar(GuiView * view);
 
        /// \return a top-level submenu given its name.
        QMenu * menu(QString const & name);
 
-       /// update the state of the menuitems - not needed
-       void updateView();
        ///
        void read(Lexer &);
-       ///
-       void add(Menu const &);
-       ///
-       bool hasMenu(QString const &) const;
-       ///
-       Menu & getMenu(QString const &);
-       ///
-       Menu const & getMenu(QString const &) const;
-       ///
-       Menu const & getMenubar() const;
-       ///
-       bool empty() const { return menulist_.empty(); }
-       /** This defines a menu whose entries list the FuncRequests
-           that will be removed by expand() in other menus. This is
-           used by the Qt/Mac code
-       */
-       void setSpecialMenu(Menu const & menu) { specialmenu_ = menu; }
-       ///
-       Menu const & specialMenu() { return specialmenu_; }
 
-       /// Expands some special entries of the menu
-       /** The entries with the following kind are expanded to a
-           sequence of Command MenuItems: Lastfiles, Documents,
-           ViewFormats, ExportFormats, UpdateFormats, Branches
-       */
-       void expand(Menu const & frommenu, Menu & tomenu,
-                   Buffer const *) const;
-       ///
-       const_iterator begin() const { return menulist_.begin(); }
-       ///
-       iterator begin() { return menulist_.begin(); }
        ///
-       const_iterator end() const { return menulist_.end(); }
-       ///
-       iterator end() { return menulist_.end(); }
-
-private:
-       ///
-       MenuList menulist_;
-       ///
-       Menu menubar_;
-       ///
-       Menu specialmenu_;
+       void updateMenu(QString const & name);
 
 private:
-       /// Initialize specific MACOS X menubar
-       void macxMenuBarInit(GuiView * view);
-
-       typedef QHash<QString, GuiPopupMenu *> NameMap;
-
-       /// name to menu for \c menu() method.
-       NameMap name_map_;
+       /// Use the Pimpl idiom to hide the internals.
+       struct Impl;
+       /// The pointer never changes although *d's contents may.
+       Impl * const d;
 };
 
 } // namespace frontend