- if (m->kind() != MenuItem::Submenu) {
- LYXERR(Debug::GUI, "\tERROR: not a submenu " << fromqstr(m->label()));
- continue;
- }
-
- LYXERR(Debug::GUI, "menu bar item " << fromqstr(m->label())
- << " is a submenu named " << fromqstr(m->submenuname()));
-
- QString name = m->submenuname();
- 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);
-
- 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_);
-
- 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 = d->name_map_.value(name, 0);
- if (!menu)
- LYXERR0("resquested context menu not found: " << fromqstr(name));
- return menu;
-}
-
-
-/// Some special Qt/Mac support hacks
-
-/*
- Here is what the Qt documentation says about how a menubar is chosen:
-
- 1) If the window has a QMenuBar then it is used. 2) If the window
- is a modal then its menubar is used. If no menubar is specified
- then a default menubar is used (as documented below) 3) If the
- window has no parent then the default menubar is used (as
- documented below).
-
- The above 3 steps are applied all the way up the parent window
- chain until one of the above are satisifed. If all else fails a
- default menubar will be created, the default menubar on Qt/Mac is
- an empty menubar, however you can create a different default
- menubar by creating a parentless QMenuBar, the first one created
- will thus be designated the default menubar, and will be used
- whenever a default menubar is needed.
-
- Thus, for Qt/Mac, we add the menus to a free standing menubar, so
- that this menubar will be used also when one of LyX' dialogs has
- focus. (JMarc)
-*/
-
-void Menus::Impl::macxMenuBarInit(GuiView * view)
-{
- // The Mac menubar initialisation must be done only once!
- static bool done = false;
- if (done)
- return;
- done = true;
-
- /* Since Qt 4.2, the qt/mac menu code has special code for
- specifying the role of a menu entry. However, it does not
- work very well with our scheme of creating menus on demand,
- and therefore we need to put these entries in a special
- invisible menu. (JMarc)
- */
-
- /* The entries of our special mac menu. If we add support for
- * special entries in Menus, we could imagine something
- * like
- * SpecialItem About " "About LyX" "dialog-show aboutlyx"
- * and therefore avoid hardcoding. I am not sure it is worth
- * the hassle, though. (JMarc)
- */
- struct MacMenuEntry {
- kb_action action;
- char const * arg;
- char const * label;
- QAction::MenuRole role;
- };
-
- MacMenuEntry entries[] = {
- {LFUN_DIALOG_SHOW, "aboutlyx", "About LyX",
- QAction::AboutRole},
- {LFUN_DIALOG_SHOW, "prefs", "Preferences",
- QAction::PreferencesRole},
- {LFUN_RECONFIGURE, "", "Reconfigure",
- QAction::ApplicationSpecificRole},
- {LFUN_LYX_QUIT, "", "Quit LyX", QAction::QuitRole}
- };
- const size_t num_entries = sizeof(entries) / sizeof(entries[0]);
-
- // the special menu for Menus.
- Menu special;
- for (size_t i = 0 ; i < num_entries ; ++i) {
- FuncRequest const func(entries[i].action,
- from_utf8(entries[i].arg));
- special.add(MenuItem(MenuItem::Command, entries[i].label, func));
- }
- setSpecialMenu(special);
-
- // add the entries to a QMenu that will eventually be empty
- // and therefore invisible.
- QMenu * qMenu = view->menuBar()->addMenu("special");
-
- // we do not use 'special' because it is a temporary variable,
- // whereas Menus::specialMenu points to a persistent copy.
- Menu::const_iterator cit = specialMenu().begin();
- Menu::const_iterator end = specialMenu().end();
- for (size_t i = 0 ; cit != end ; ++cit, ++i) {
- Action * action = new Action(*view, QIcon(), cit->label(),
- cit->func(), QString());
- action->setMenuRole(entries[i].role);
- qMenu->addAction(action);
- }
-}
-
-
-MenuItem::MenuItem(Kind kind)
- : kind_(kind), optional_(false)
-{}
-
-
-MenuItem::MenuItem(Kind kind, QString const & label,
- QString const & submenu, bool optional)
- : kind_(kind), label_(label),
- submenuname_(submenu), optional_(optional)
-{
- BOOST_ASSERT(kind == Submenu);
-}
-
-
-MenuItem::MenuItem(Kind kind, QString const & label,
- FuncRequest const & func, bool optional)
- : kind_(kind), label_(label), func_(func), optional_(optional)
-{
- func_.origin = FuncRequest::MENU;
-}
-
-
-MenuItem::~MenuItem()
-{}
-
-
-void MenuItem::setSubmenu(Menu * menu)
-{
- submenu_.reset(menu);
-}
-
-
-QString MenuItem::label() const
-{
- return label_.split('|')[0];
-}
-
-
-QString MenuItem::shortcut() const
-{
- return label_.contains('|') ? label_.split('|')[1] : QString();
-}
-
-
-QString MenuItem::binding() const
-{
- if (kind_ != Command)
- return QString();
-
- // Get the keys bound to this action, but keep only the
- // first one later
- KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(func_);
-
- if (bindings.size())
- return toqstr(bindings.begin()->print(KeySequence::ForGui));
-
- LYXERR(Debug::KBMAP, "No binding for "
- << lyxaction.getActionName(func_.action)
- << '(' << func_.argument() << ')');
- return QString();
-}
-
-
-void Menu::addWithStatusCheck(MenuItem const & i)
-{
- switch (i.kind()) {
-
- case MenuItem::Command: {
- FuncStatus status = lyx::getStatus(i.func());
- if (status.unknown() || (!status.enabled() && i.optional()))
- break;
- items_.push_back(i);
- items_.back().status(status);
- break;
- }
-
- case MenuItem::Submenu: {
- if (i.submenu()) {
- bool enabled = false;
- for (const_iterator cit = i.submenu()->begin();
- cit != i.submenu()->end(); ++cit) {
- if ((cit->kind() == MenuItem::Command
- || cit->kind() == MenuItem::Submenu)
- && cit->status().enabled()) {
- enabled = true;
- break;
- }
- }
- if (enabled || !i.optional()) {
- items_.push_back(i);
- items_.back().status().enabled(enabled);
- }
- }
- else
- items_.push_back(i);
- break;
- }
-
- case MenuItem::Separator:
- if (!items_.empty() && items_.back().kind() != MenuItem::Separator)
- items_.push_back(i);
- break;
-
- default:
- items_.push_back(i);
- }
-}
-
-
-void Menu::read(Lexer & lex)
-{
- enum Menutags {
- md_item = 1,
- md_branches,
- md_documents,
- md_bookmarks,
- md_charstyles,
- md_custom,
- md_elements,
- md_endmenu,
- md_exportformats,
- md_importformats,
- md_lastfiles,
- md_optitem,
- md_optsubmenu,
- md_separator,
- md_submenu,
- md_toc,
- md_updateformats,
- md_viewformats,
- md_floatlistinsert,
- md_floatinsert,
- md_pasterecent,
- md_toolbars,
- md_last
- };
-
- struct keyword_item menutags[md_last - 1] = {
- { "bookmarks", md_bookmarks },
- { "branches", md_branches },
- { "charstyles", md_charstyles },
- { "custom", md_custom },
- { "documents", md_documents },
- { "elements", md_elements },
- { "end", md_endmenu },
- { "exportformats", md_exportformats },
- { "floatinsert", md_floatinsert },
- { "floatlistinsert", md_floatlistinsert },
- { "importformats", md_importformats },
- { "item", md_item },
- { "lastfiles", md_lastfiles },
- { "optitem", md_optitem },
- { "optsubmenu", md_optsubmenu },
- { "pasterecent", md_pasterecent },
- { "separator", md_separator },
- { "submenu", md_submenu },
- { "toc", md_toc },
- { "toolbars", md_toolbars },
- { "updateformats", md_updateformats },
- { "viewformats", md_viewformats }
- };
-
- lex.pushTable(menutags, md_last - 1);
- if (lyxerr.debugging(Debug::PARSER))
- lex.printTable(lyxerr);
-
- bool quit = false;
- bool optional = false;
-
- while (lex.isOK() && !quit) {
- switch (lex.lex()) {
- case md_optitem:
- optional = true;
- // fallback to md_item
- case md_item: {
- lex.next(true);
- docstring const name = translateIfPossible(lex.getDocString());
- lex.next(true);
- string const command = lex.getString();
- FuncRequest func = lyxaction.lookupFunc(command);
- add(MenuItem(MenuItem::Command, toqstr(name), func, optional));
- optional = false;
- break;
- }
-
- case md_separator:
- add(MenuItem(MenuItem::Separator));
- break;
-
- case md_lastfiles:
- add(MenuItem(MenuItem::Lastfiles));
- break;
-
- case md_charstyles:
- add(MenuItem(MenuItem::CharStyles));
- break;
-
- case md_custom:
- add(MenuItem(MenuItem::Custom));
- break;
-
- case md_elements:
- add(MenuItem(MenuItem::Elements));
- break;
-
- case md_documents:
- add(MenuItem(MenuItem::Documents));
- break;
-
- case md_bookmarks:
- add(MenuItem(MenuItem::Bookmarks));
- break;
-
- case md_toc:
- add(MenuItem(MenuItem::Toc));
- break;
-
- case md_viewformats:
- add(MenuItem(MenuItem::ViewFormats));
- break;
-
- case md_updateformats:
- add(MenuItem(MenuItem::UpdateFormats));
- break;
-
- case md_exportformats:
- add(MenuItem(MenuItem::ExportFormats));
- break;
-
- case md_importformats:
- add(MenuItem(MenuItem::ImportFormats));
- break;
-
- case md_floatlistinsert:
- add(MenuItem(MenuItem::FloatListInsert));
- break;
-
- case md_floatinsert:
- add(MenuItem(MenuItem::FloatInsert));
- break;
-
- case md_pasterecent:
- add(MenuItem(MenuItem::PasteRecent));
- break;
-
- case md_toolbars:
- add(MenuItem(MenuItem::Toolbars));
- break;
-
- case md_branches:
- add(MenuItem(MenuItem::Branches));