+void MenuDefinition::expandToc(Buffer const * buf)
+{
+ // To make things very cleanly, we would have to pass buf to
+ // all MenuItem constructors and to expandToc2. However, we
+ // know that all the entries in a TOC will be have status_ ==
+ // OK, so we avoid this unnecessary overhead (JMarc)
+
+ if (!buf) {
+ add(MenuItem(MenuItem::Info, qt_("<No Document Open>")));
+ return;
+ }
+
+ // Add an entry for the master doc if this is a child doc
+ Buffer const * const master = buf->masterBuffer();
+ if (buf != master) {
+ ParIterator const pit = par_iterator_begin(master->inset());
+ string const arg = convert<string>(pit->id());
+ FuncRequest f(LFUN_PARAGRAPH_GOTO, arg);
+ add(MenuItem(MenuItem::Command, qt_("Master Document"), f));
+ }
+
+ MenuDefinition other_lists;
+
+ FloatList const & floatlist = buf->params().documentClass().floats();
+ TocList const & toc_list = buf->tocBackend().tocs();
+ TocList::const_iterator cit = toc_list.begin();
+ TocList::const_iterator end = toc_list.end();
+ for (; cit != end; ++cit) {
+ // Handle this later
+ if (cit->first == "tableofcontents")
+ continue;
+
+ MenuDefinition submenu;
+ if (cit->second.size() >= 30) {
+ FuncRequest f(LFUN_DIALOG_SHOW, "toc " + cit->first);
+ submenu.add(MenuItem(MenuItem::Command, qt_("Open Navigator..."), f));
+ } else {
+ TocIterator ccit = cit->second.begin();
+ TocIterator eend = cit->second.end();
+ for (; ccit != eend; ++ccit) {
+ submenu.add(MenuItem(MenuItem::Command,
+ limitStringLength(ccit->str()),
+ FuncRequest(ccit->action())));
+ }
+ }
+
+ MenuItem item(MenuItem::Submenu, guiName(cit->first, buf->params()));
+ item.setSubmenu(submenu);
+ if (floatlist.typeExist(cit->first) || cit->first == "child") {
+ // Those two types deserve to be in the main menu.
+ item.setSubmenu(submenu);
+ add(item);
+ } else
+ other_lists.add(item);
+ }
+ if (!other_lists.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_("Other Lists"));
+ item.setSubmenu(other_lists);
+ add(item);
+ }
+
+ // Handle normal TOC
+ cit = toc_list.find("tableofcontents");
+ if (cit == end)
+ LYXERR(Debug::GUI, "No table of contents.");
+ else {
+ if (cit->second.size() > 0 )
+ expandToc2(cit->second, 0, cit->second.size(), 0);
+ else
+ add(MenuItem(MenuItem::Info, qt_("<Empty Table of Contents>")));
+ }
+}
+
+
+void MenuDefinition::expandPasteRecent(Buffer const * buf)
+{
+ docstring_list const sel = cap::availableSelections(buf);
+
+ docstring_list::const_iterator cit = sel.begin();
+ docstring_list::const_iterator end = sel.end();
+
+ for (unsigned int index = 0; cit != end; ++cit, ++index) {
+ add(MenuItem(MenuItem::Command, toqstr(*cit),
+ FuncRequest(LFUN_PASTE, convert<string>(index))));
+ }
+}
+
+
+void MenuDefinition::expandToolbars()
+{
+ MenuDefinition other_lists;
+ // extracts the toolbars from the backend
+ Toolbars::Infos::const_iterator cit = guiApp->toolbars().begin();
+ Toolbars::Infos::const_iterator end = guiApp->toolbars().end();
+ for (; cit != end; ++cit) {
+ MenuItem const item(MenuItem::Command, toqstr(cit->gui_name),
+ FuncRequest(LFUN_TOOLBAR_TOGGLE, cit->name));
+ if (guiApp->toolbars().isMainToolbar(cit->name))
+ add(item);
+ else
+ other_lists.add(item);
+ }
+
+ if (!other_lists.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_("Other Toolbars"));
+ item.setSubmenu(other_lists);
+ add(item);
+ }
+}
+
+
+void MenuDefinition::expandBranches(Buffer const * buf)
+{
+ if (!buf)
+ return;
+
+ BufferParams const & master_params = buf->masterBuffer()->params();
+ BufferParams const & params = buf->params();
+ if (params.branchlist().empty() && master_params.branchlist().empty() ) {
+ add(MenuItem(MenuItem::Help, qt_("No Branches Set for Document!")));
+ return;
+ }
+
+ BranchList::const_iterator cit = master_params.branchlist().begin();
+ BranchList::const_iterator end = master_params.branchlist().end();
+
+ for (int ii = 1; cit != end; ++cit, ++ii) {
+ docstring label = cit->branch();
+ if (ii < 10) {
+ label = convert<docstring>(ii) + ". " + label
+ + char_type('|') + convert<docstring>(ii);
+ }
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
+ FuncRequest(LFUN_BRANCH_INSERT,
+ cit->branch())));
+ }
+
+ if (buf == buf->masterBuffer())
+ return;
+
+ MenuDefinition child_branches;
+
+ BranchList::const_iterator ccit = params.branchlist().begin();
+ BranchList::const_iterator cend = params.branchlist().end();
+
+ for (int ii = 1; ccit != cend; ++ccit, ++ii) {
+ docstring label = ccit->branch();
+ if (ii < 10) {
+ label = convert<docstring>(ii) + ". " + label
+ + char_type('|') + convert<docstring>(ii);
+ }
+ child_branches.addWithStatusCheck(MenuItem(MenuItem::Command,
+ toqstr(label),
+ FuncRequest(LFUN_BRANCH_INSERT,
+ ccit->branch())));
+ }
+
+ if (!child_branches.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_("Child Document"));
+ item.setSubmenu(child_branches);
+ add(item);
+ }
+}
+
+
+void MenuDefinition::expandIndices(Buffer const * buf, bool listof)
+{
+ if (!buf)
+ return;
+
+ BufferParams const & params = buf->masterBuffer()->params();
+ if (!params.use_indices) {
+ if (listof)
+ addWithStatusCheck(MenuItem(MenuItem::Command,
+ qt_("Index List|I"),
+ FuncRequest(LFUN_INDEX_PRINT,
+ from_ascii("idx"))));
+ else
+ addWithStatusCheck(MenuItem(MenuItem::Command,
+ qt_("Index Entry|d"),
+ FuncRequest(LFUN_INDEX_INSERT,
+ from_ascii("idx"))));
+ return;
+ }
+
+ if (params.indiceslist().empty())
+ return;
+
+ IndicesList::const_iterator cit = params.indiceslist().begin();
+ IndicesList::const_iterator end = params.indiceslist().end();
+
+ for (int ii = 1; cit != end; ++cit, ++ii) {
+ if (listof)
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(cit->index()),
+ FuncRequest(LFUN_INDEX_PRINT,
+ cit->shortcut())));
+ else {
+ docstring label = _("Index Entry");
+ label += " (" + cit->index() + ")";
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
+ FuncRequest(LFUN_INDEX_INSERT,
+ cit->shortcut())));
+ }
+ }
+}
+
+
+void MenuDefinition::expandIndicesContext(Buffer const * buf, bool listof)
+{
+ if (!buf)
+ return;
+
+ BufferParams const & params = buf->masterBuffer()->params();
+ if (!params.use_indices || params.indiceslist().empty())
+ return;
+
+ IndicesList::const_iterator cit = params.indiceslist().begin();
+ IndicesList::const_iterator end = params.indiceslist().end();
+
+ for (int ii = 1; cit != end; ++cit, ++ii) {
+ if (listof) {
+ InsetCommandParams p(INDEX_PRINT_CODE);
+ p["type"] = cit->shortcut();
+ string const data = InsetCommand::params2string("index_print", p);
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(cit->index()),
+ FuncRequest(LFUN_INSET_MODIFY, data)));
+ } else {
+ docstring label = _("Index Entry");
+ label += " (" + cit->index() + ")";
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
+ FuncRequest(LFUN_INSET_MODIFY,
+ from_ascii("changetype ") + cit->shortcut())));
+ }
+ }
+}
+
+
+void MenuDefinition::expandCiteStyles(BufferView const * bv)
+{
+ if (!bv)
+ return;
+
+ Inset const * inset = bv->cursor().nextInset();
+ if (!inset || inset->lyxCode() != CITE_CODE) {
+ add(MenuItem(MenuItem::Command,
+ qt_("No Citation in Scope!"),
+ FuncRequest(LFUN_NOACTION)));
+ return;
+ }
+ InsetCommand const * citinset =
+ static_cast<InsetCommand const *>(inset);
+
+ Buffer const * buf = &bv->buffer();
+ docstring key = citinset->getParam("key");
+ // we can only handle one key currently
+ if (contains(key, ','))
+ key = qstring_to_ucs4(toqstr(key).split(',')[0]);
+
+ vector<CiteStyle> citeStyleList = citeStyles(buf->params().citeEngine());
+ docstring_list citeStrings =
+ buf->masterBibInfo().getCiteStrings(key, bv->buffer());
+
+ docstring_list::const_iterator cit = citeStrings.begin();
+ docstring_list::const_iterator end = citeStrings.end();
+
+ for (int ii = 1; cit != end; ++cit, ++ii) {
+ docstring label = *cit;
+ CitationStyle cs;
+ CiteStyle cst = citeStyleList[ii - 1];
+ cs.style = cst;
+ addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
+ FuncRequest(LFUN_INSET_MODIFY,
+ "changetype " + from_utf8(citationStyleToString(cs)))));
+ }
+}
+
+} // namespace anon
+
+
+/////////////////////////////////////////////////////////////////////
+// Menu::Impl definition and implementation
+/////////////////////////////////////////////////////////////////////
+
+struct Menu::Impl
+{
+ /// populates the menu or one of its submenu
+ /// This is used as a recursive function
+ void populate(QMenu & qMenu, MenuDefinition const & menu);
+
+ /// Only needed for top level menus.
+ MenuDefinition * top_level_menu;
+ /// our owning view
+ GuiView * view;
+ /// the name of this menu
+ QString name;
+};
+
+
+
+/// Get a MenuDefinition item label from the menu backend
+static QString label(MenuItem const & mi)
+{
+ 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;
+}
+
+void Menu::Impl::populate(QMenu & qMenu, MenuDefinition const & menu)
+{
+ LYXERR(Debug::GUI, "populating menu " << menu.name());
+ if (menu.size() == 0) {
+ LYXERR(Debug::GUI, "\tERROR: empty menu " << menu.name());
+ return;
+ }
+ LYXERR(Debug::GUI, " ***** menu entries " << menu.size());
+ MenuDefinition::const_iterator m = menu.begin();
+ MenuDefinition::const_iterator end = menu.end();
+ for (; m != end; ++m) {
+ if (m->kind() == MenuItem::Separator)
+ qMenu.addSeparator();
+ else if (m->kind() == MenuItem::Submenu) {
+ QMenu * subMenu = qMenu.addMenu(label(*m));
+ populate(*subMenu, m->submenu());
+ subMenu->setEnabled(m->status().enabled());
+ } else {
+ // we have a MenuItem::Command
+ qMenu.addAction(new Action(view, QIcon(), label(*m),
+ m->func(), QString(), &qMenu));
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// Menu implementation
+/////////////////////////////////////////////////////////////////////
+
+Menu::Menu(GuiView * gv, QString const & name, bool top_level)
+: QMenu(gv), d(new Menu::Impl)