X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FMenus.cpp;h=627ec4c4c95c31be9ff7c4694c7a3266488c1fab;hb=28be7d552f62cc02fa86d7f79201d089bfb2d7b5;hp=b75221b8b397a2433ed208dc83aea596cf94dee0;hpb=21eea1e77a9a664f7a1a96b5f3aa2ba96eb11188;p=lyx.git diff --git a/src/frontends/qt4/Menus.cpp b/src/frontends/qt4/Menus.cpp index b75221b8b3..627ec4c4c9 100644 --- a/src/frontends/qt4/Menus.cpp +++ b/src/frontends/qt4/Menus.cpp @@ -60,6 +60,7 @@ #include "insets/Inset.h" #include "insets/InsetCitation.h" #include "insets/InsetGraphics.h" +#include "insets/InsetQuotes.h" #include "support/lassert.h" #include "support/convert.h" @@ -78,9 +79,8 @@ #include #endif -#include "support/shared_ptr.h" - #include +#include #include using namespace std; @@ -135,6 +135,9 @@ public: /** This is a list of exportable formats typically for the File->Export menu. */ ExportFormats, + /** This exports the document default format + typically for the File->Export menu. */ + ExportFormat, /** This is a list of importable formats typically for the File->Import menu. */ ImportFormats, @@ -189,7 +192,9 @@ public: in the InsetCaption context menu. */ SwitchCaptions, /** Commands to separate environments. */ - EnvironmentSeparators + EnvironmentSeparators, + /** This is the list of quotation marks available */ + SwitchQuotes }; explicit MenuItem(Kind kind) : kind_(kind), optional_(false) {} @@ -199,8 +204,8 @@ public: QString const & submenu = QString(), QString const & tooltip = QString(), bool optional = false) - : kind_(kind), label_(label), submenuname_(submenu), - tooltip_(tooltip), optional_(optional) + : kind_(kind), label_(label), func_(make_shared()), + submenuname_(submenu), tooltip_(tooltip), optional_(optional) { LATTEST(kind == Submenu || kind == Help || kind == Info); } @@ -211,15 +216,12 @@ public: QString const & tooltip = QString(), bool optional = false, FuncRequest::Origin origin = FuncRequest::MENU) - : kind_(kind), label_(label), func_(func), + : kind_(kind), label_(label), func_(make_shared(func)), tooltip_(tooltip), optional_(optional) { - func_.setOrigin(origin); + func_->setOrigin(origin); } - // shared_ptr needs this apprently... - ~MenuItem() {} - /// The label of a given menuitem QString label() const { @@ -238,7 +240,7 @@ public: /// The kind of entry Kind kind() const { return kind_; } /// the action (if relevant) - FuncRequest const & func() const { return func_; } + shared_ptr func() const { return func_; } /// the tooltip QString const & tooltip() const { return tooltip_; } /// returns true if the entry should be omitted when disabled @@ -257,13 +259,13 @@ public: return QString(); // Get the keys bound to this action, but keep only the // first one later - KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(func_); + KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(*func_); if (!bindings.empty()) return toqstr(bindings.begin()->print(KeySequence::ForGui)); LYXERR(Debug::KBMAP, "No binding for " - << lyxaction.getActionName(func_.action()) - << '(' << func_.argument() << ')'); + << lyxaction.getActionName(func_->action()) + << '(' << func_->argument() << ')'); return QString(); } @@ -289,7 +291,7 @@ private: /// QString label_; /// - FuncRequest func_; + shared_ptr func_;// non-null /// QString submenuname_; /// @@ -323,8 +325,6 @@ public: /// 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(); } @@ -354,7 +354,8 @@ public: void expandFloatListInsert(Buffer const * buf); void expandFloatInsert(Buffer const * buf); void expandFlexInsert(Buffer const * buf, InsetLayout::InsetLyXType type); - void expandToc2(Toc const & toc_list, size_t from, size_t to, int depth); + void expandTocSubmenu(std::string const & type, Toc const & toc_list); + void expandToc2(Toc const & toc_list, size_t from, size_t to, int depth, string toc_type); void expandToc(Buffer const * buf); void expandPasteRecent(Buffer const * buf); void expandToolbars(); @@ -368,6 +369,7 @@ public: void expandArguments(BufferView const *, bool switcharg = false); void expandCaptions(Buffer const * buf, bool switchcap = false); void expandEnvironmentSeparators(BufferView const *); + void expandQuotes(BufferView const *); /// ItemList items_; /// @@ -402,7 +404,7 @@ void MenuDefinition::addWithStatusCheck(MenuItem const & i) switch (i.kind()) { case MenuItem::Command: { - FuncStatus status = lyx::getStatus(i.func()); + FuncStatus status = lyx::getStatus(*i.func()); if (status.unknown() || (!status.enabled() && i.optional())) break; items_.push_back(i); @@ -417,8 +419,9 @@ void MenuDefinition::addWithStatusCheck(MenuItem const & i) cit != i.submenu().end(); ++cit) { // Only these kind of items affect the status of the submenu if ((cit->kind() == MenuItem::Command - || cit->kind() == MenuItem::Submenu - || cit->kind() == MenuItem::Help)) { + || cit->kind() == MenuItem::Submenu + || cit->kind() == MenuItem::Help) + && cit->status().enabled()) { enabled = true; break; } @@ -454,6 +457,7 @@ void MenuDefinition::read(Lexer & lex) md_custom, md_elements, md_endmenu, + md_exportformat, md_exportformats, md_importformats, md_indices, @@ -479,7 +483,8 @@ void MenuDefinition::read(Lexer & lex) md_switcharguments, md_captions, md_switchcaptions, - md_env_separators + md_env_separators, + md_switchquotes }; LexerKeyword menutags[] = { @@ -494,6 +499,7 @@ void MenuDefinition::read(Lexer & lex) { "elements", md_elements }, { "end", md_endmenu }, { "environmentseparators", md_env_separators }, + { "exportformat", md_exportformat }, { "exportformats", md_exportformats }, { "floatinsert", md_floatinsert }, { "floatlistinsert", md_floatlistinsert }, @@ -514,6 +520,7 @@ void MenuDefinition::read(Lexer & lex) { "submenu", md_submenu }, { "switcharguments", md_switcharguments }, { "switchcaptions", md_switchcaptions }, + { "switchquotes", md_switchquotes }, { "toc", md_toc }, { "toolbars", md_toolbars }, { "updateformats", md_updateformats }, @@ -585,6 +592,10 @@ void MenuDefinition::read(Lexer & lex) add(MenuItem(MenuItem::ExportFormats)); break; + case md_exportformat: + add(MenuItem(MenuItem::ExportFormat)); + break; + case md_importformats: add(MenuItem(MenuItem::ImportFormats)); break; @@ -661,6 +672,10 @@ void MenuDefinition::read(Lexer & lex) add(MenuItem(MenuItem::EnvironmentSeparators)); break; + case md_switchquotes: + add(MenuItem(MenuItem::SwitchQuotes)); + break; + case md_optsubmenu: case md_submenu: { lex.next(true); @@ -685,16 +700,10 @@ void MenuDefinition::read(Lexer & lex) } -MenuItem const & MenuDefinition::operator[](size_type i) const -{ - return items_[i]; -} - - bool MenuDefinition::hasFunc(FuncRequest const & func) const { for (const_iterator it = begin(), et = end(); it != et; ++it) - if (it->func() == func) + if (*it->func() == func) return true; return false; } @@ -744,7 +753,7 @@ bool MenuDefinition::searchMenu(FuncRequest const & func, docstring_list & names const_iterator m = begin(); const_iterator m_end = end(); for (; m != m_end; ++m) { - if (m->kind() == MenuItem::Command && m->func() == func) { + if (m->kind() == MenuItem::Command && *m->func() == func) { names.push_back(qstring_to_ucs4(m->label())); return true; } @@ -981,6 +990,8 @@ void MenuDefinition::expandDocuments() QString label = toqstr(b.fileName().displayName(20)); if (!b.isClean()) label += "*"; + if (b.notifiesExternalModification()) + label += QChar(0x26a0); if (i < 10) label = QString::number(i) + ". " + label + '|' + QString::number(i); add(MenuItem(MenuItem::Command, label, @@ -998,6 +1009,8 @@ void MenuDefinition::expandDocuments() QString label = toqstr(b->fileName().displayName(20)); if (!b->isClean()) label += "*"; + if (b->notifiesExternalModification()) + label += QChar(0x26a0); if (i < 10) label = QString::number(i) + ". " + label + '|' + QString::number(i); item.submenu().add(MenuItem(MenuItem::Command, label, @@ -1037,8 +1050,7 @@ void MenuDefinition::expandFormats(MenuItem::Kind const kind, Buffer const * buf if (!buf && kind != MenuItem::ImportFormats) return; - typedef vector Formats; - Formats formats; + FormatList formats; FuncCode action = LFUN_NOACTION; switch (kind) { @@ -1062,7 +1074,6 @@ void MenuDefinition::expandFormats(MenuItem::Kind const kind, Buffer const * buf LATTEST(false); return; } - sort(formats.begin(), formats.end(), Format::formatSorter); bool const view_update = (kind == MenuItem::ViewFormats || kind == MenuItem::UpdateFormats); @@ -1075,14 +1086,12 @@ void MenuDefinition::expandFormats(MenuItem::Kind const kind, Buffer const * buf MenuItem item(MenuItem::Submenu, smenue); item.setSubmenu(MenuDefinition(smenue)); - Formats::const_iterator fit = formats.begin(); - Formats::const_iterator end = formats.end(); - for (; fit != end ; ++fit) { - if ((*fit)->dummy()) + for (Format const * f : formats) { + if (f->dummy()) continue; - docstring lab = from_utf8((*fit)->prettyname()); - docstring const scut = from_utf8((*fit)->shortcut()); + docstring lab = f->prettyname(); + docstring const scut = from_utf8(f->shortcut()); docstring const tmplab = lab; if (!scut.empty()) @@ -1099,7 +1108,7 @@ void MenuDefinition::expandFormats(MenuItem::Kind const kind, Buffer const * buf break; case MenuItem::ViewFormats: case MenuItem::UpdateFormats: - if ((*fit)->name() == buf->params().getDefaultOutputFormat()) { + if (f->name() == buf->params().getDefaultOutputFormat()) { docstring lbl = (kind == MenuItem::ViewFormats ? bformat(_("View [%1$s]|V"), label) : bformat(_("Update [%1$s]|U"), label)); @@ -1108,7 +1117,7 @@ void MenuDefinition::expandFormats(MenuItem::Kind const kind, Buffer const * buf } // fall through case MenuItem::ExportFormats: - if (!(*fit)->inExportMenu()) + if (!f->inExportMenu()) continue; break; default: @@ -1123,14 +1132,14 @@ void MenuDefinition::expandFormats(MenuItem::Kind const kind, Buffer const * buf // note that at this point, we know that buf is not null LATTEST(buf); item.submenu().addWithStatusCheck(MenuItem(MenuItem::Command, - toqstr(label), FuncRequest(action, (*fit)->name()))); + toqstr(label), FuncRequest(action, f->name()))); } else { if (buf) addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label), - FuncRequest(action, (*fit)->name()))); + FuncRequest(action, f->name()))); else add(MenuItem(MenuItem::Command, toqstr(label), - FuncRequest(action, (*fit)->name()))); + FuncRequest(action, f->name()))); } } if (view_update) @@ -1212,15 +1221,23 @@ void MenuDefinition::expandFlexInsert( } } // FIXME This is a little clunky. - if (items_.empty() && type == InsetLayout::CUSTOM && !buf->isReadonly()) + if (items_.empty() && type == InsetLayout::CUSTOM && !buf->hasReadonlyFlag()) add(MenuItem(MenuItem::Help, qt_("No Custom Insets Defined!"))); } +// Threshold before we stop displaying sub-items alongside items +// (for display purposes). Ideally this should fit on a screen. size_t const max_number_of_items = 30; +// Size limit for the menu. This is for performance purposes, +// because qt already displays a scrollable menu when necessary. +// Ideally this should be the menu size from which scrollable +// menus become unpractical. +size_t const menu_size_limit = 80; void MenuDefinition::expandToc2(Toc const & toc_list, - size_t from, size_t to, int depth) + size_t from, size_t to, int depth, + string toc_type) { int shortcut_count = 0; @@ -1250,6 +1267,7 @@ void MenuDefinition::expandToc2(Toc const & toc_list, } } else { size_t pos = from; + size_t size = 1; while (pos < to) { size_t new_pos = pos + 1; while (new_pos < to && toc_list[new_pos].depth() > depth) @@ -1264,16 +1282,22 @@ void MenuDefinition::expandToc2(Toc const & toc_list, label += QString::number(++shortcut_count); } } + if (size >= menu_size_limit) { + FuncRequest f(LFUN_DIALOG_SHOW, "toc " + toc_type); + add(MenuItem(MenuItem::Command, "...", f)); + break; + } if (new_pos == pos + 1) { add(MenuItem(MenuItem::Command, label, FuncRequest(toc_list[pos].action()))); } else { MenuDefinition sub; - sub.expandToc2(toc_list, pos, new_pos, depth + 1); + sub.expandToc2(toc_list, pos, new_pos, depth + 1, toc_type); MenuItem item(MenuItem::Submenu, label); item.setSubmenu(sub); add(item); } + ++size; pos = new_pos; } } @@ -1300,25 +1324,20 @@ void MenuDefinition::expandToc(Buffer const * buf) } 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) { + // In the navigation menu, only add tocs from this document + TocBackend const & backend = buf->tocBackend(); + TocList const & toc_list = backend.tocs(); + for (pair> const & toc : toc_list) { // Handle table of contents later - if (cit->first == "tableofcontents" || cit->second->empty()) + if (toc.first == "tableofcontents" || toc.second->empty()) continue; MenuDefinition submenu; - // "Open outliner..." entry - FuncRequest f(LFUN_DIALOG_SHOW, "toc " + cit->first); - submenu.add(MenuItem(MenuItem::Command, qt_("Open Outliner..."), f)); - submenu.add(MenuItem(MenuItem::Separator)); - // add entries - submenu.expandToc2(* cit->second, 0, cit->second->size(), 0); - MenuItem item(MenuItem::Submenu, guiName(cit->first, buf->params())); + submenu.expandTocSubmenu(toc.first, *toc.second); + docstring const toc_name = backend.outlinerName(toc.first); + MenuItem item(MenuItem::Submenu, toqstr(toc_name)); item.setSubmenu(submenu); // deserves to be in the main menu? - if (floatlist.typeExist(cit->first) || cit->first == "child") + if (!TocBackend::isOther(toc.first)) add(item); else other_lists.add(item); @@ -1330,18 +1349,30 @@ void MenuDefinition::expandToc(Buffer const * buf) } // Handle normal TOC add(MenuItem(MenuItem::Separator)); - cit = toc_list.find("tableofcontents"); - if (cit == end) + TocList::const_iterator cit = toc_list.find("tableofcontents"); + if (cit == toc_list.end()) LYXERR(Debug::GUI, "No table of contents."); else { if (!cit->second->empty()) - expandToc2(* cit->second, 0, cit->second->size(), 0); + expandToc2(*cit->second, 0, cit->second->size(), 0, + "tableofcontents"); else add(MenuItem(MenuItem::Info, qt_("(Empty Table of Contents)"))); } } +void MenuDefinition::expandTocSubmenu(std::string const & type, Toc const & toc) +{ + // "Open outliner..." entry + FuncRequest f(LFUN_DIALOG_SHOW, "toc " + type); + add(MenuItem(MenuItem::Command, qt_("Open Outliner..."), f)); + add(MenuItem(MenuItem::Separator)); + // add entries + expandToc2(toc, 0, toc.size(), 0, type); +} + + void MenuDefinition::expandPasteRecent(Buffer const * buf) { docstring_list const sel = cap::availableSelections(buf); @@ -1381,7 +1412,7 @@ void MenuDefinition::expandToolbars() void MenuDefinition::expandBranches(Buffer const * buf) { - if (!buf || buf->isReadonly()) + if (!buf || buf->hasReadonlyFlag()) return; BufferParams const & master_params = buf->masterBuffer()->params(); @@ -1518,10 +1549,11 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv) FuncRequest(LFUN_NOACTION))); return; } - InsetCommand const * citinset = - static_cast(inset); + InsetCitation const * citinset = + static_cast(inset); Buffer const * buf = &bv->buffer(); + BufferParams const & bp = buf->masterParams(); string const cmd = citinset->params().getCmdName(); docstring const & key = citinset->getParam("key"); @@ -1532,33 +1564,85 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv) return; } - docstring const & before = citinset->getParam("before"); - docstring const & after = citinset->getParam("after"); - size_t const n = cmd.size(); - bool const force = cmd[0] == 'C'; - bool const full = cmd[n] == '*'; + bool const force = isUpperCase(cmd[0]); + bool const star = cmd[n] == '*'; vector const keys = getVectorFromString(key); - vector const citeStyleList = buf->params().citeStyles(); - static const size_t max_length = 40; - vector citeStrings = - buf->masterBibInfo().getCiteStrings(keys, citeStyleList, bv->buffer(), - before, after, from_utf8("dialog"), max_length); - - vector::const_iterator cit = citeStrings.begin(); - vector::const_iterator end = citeStrings.end(); + vector const citeStyleList = bp.citeStyles(); + + CitationStyle cs = citinset->getCitationStyle(bp, cmd, citeStyleList); + bool const qualified = cs.hasQualifiedList + && (keys.size() > 1 + || !citinset->getParam("pretextlist").empty() + || !citinset->getParam("posttextlist").empty()); + std::map pres = + citinset->getQualifiedLists(citinset->getParam("pretextlist")); + std::map posts = + citinset->getQualifiedLists(citinset->getParam("posttextlist")); + + CiteItem ci; + ci.textBefore = citinset->getParam("before"); + ci.textAfter = citinset->getParam("after"); + ci.forceUpperCase = force; + ci.Starred = star; + ci.context = CiteItem::Dialog; + ci.max_size = 40; + ci.isQualified = qualified; + ci.pretexts = pres; + ci.posttexts = posts; + BiblioInfo::CiteStringMap citeStrings = + buf->masterBibInfo().getCiteStrings(keys, citeStyleList, bv->buffer(), ci); + + BiblioInfo::CiteStringMap::const_iterator cit = citeStrings.begin(); + BiblioInfo::CiteStringMap::const_iterator end = citeStrings.end(); for (int ii = 1; cit != end; ++cit, ++ii) { - docstring label = *cit; + docstring label = cit->second; CitationStyle cs = citeStyleList[ii - 1]; cs.forceUpperCase &= force; - cs.fullAuthorList &= full; + cs.hasStarredVersion &= star; addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label), FuncRequest(LFUN_INSET_MODIFY, "changetype " + from_utf8(citationStyleToString(cs))))); } + + if (cs.hasStarredVersion) { + docstring starred = _("All authors|h"); + // Check if we have a custom string/tooltip for the starred version + if (!cs.stardesc.empty()) { + string val = + bp.documentClass().getCiteMacro(buf->params().citeEngineType(), cs.stardesc); + if (!val.empty()) + starred = translateIfPossible(from_utf8(val)); + // Transform qt-style accelerators to menu-style + int const amps = count_char(starred, '&'); + if (amps > 0) { + if (amps > 1) + starred = subst(starred, from_ascii("&&"), from_ascii("<:amp:>")); + size_t n = starred.find('&'); + char_type accel = char_type(); + if (n != docstring::npos && n < starred.size() - 1) + accel = starred[n + 1]; + starred = subst(starred, from_ascii("&"), from_ascii("")); + if (amps > 1) + starred = subst(starred, from_ascii("<:amp:>"), from_ascii("&&")); + if (accel != char_type()) + starred = starred + '|' + accel; + } + } + add(MenuItem(MenuItem::Separator)); + addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(starred), + FuncRequest(LFUN_INSET_MODIFY, "toggleparam star"))); + } + + if (cs.forceUpperCase) { + if (!cs.hasStarredVersion) + add(MenuItem(MenuItem::Separator)); + addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(_("Force upper case|u")), + FuncRequest(LFUN_INSET_MODIFY, "toggleparam casing"))); + } } @@ -1600,47 +1684,37 @@ void MenuDefinition::expandCaptions(Buffer const * buf, bool switchcap) if (!buf) return; - vector caps; DocumentClass const & dc = buf->params().documentClass(); - TextClass::InsetLayouts::const_iterator lit = dc.insetLayouts().begin(); - TextClass::InsetLayouts::const_iterator len = dc.insetLayouts().end(); - for (; lit != len; ++lit) { - if (prefixIs(lit->first, from_ascii("Caption:"))) - caps.push_back(lit->first); + vector< pair > caps; + for (pair const & il : dc.insetLayouts()) { + docstring instype; + docstring const type = split(il.first, instype, ':'); + if (instype == from_ascii("Caption")) { + // skip forbidden caption types + FuncRequest const cmd = switchcap + ? FuncRequest(LFUN_INSET_MODIFY, from_ascii("changetype ") + type) + : FuncRequest(LFUN_CAPTION_INSERT, type); + if (getStatus(cmd).enabled()) + caps.push_back(make_pair(type, cmd)); + } } if (caps.empty() || (switchcap && caps.size() == 1)) return; if (caps.size() == 1) { - docstring dummy; - docstring const type = split(*caps.begin(), dummy, ':'); - add(MenuItem(MenuItem::Command, qt_("Caption"), - FuncRequest(LFUN_CAPTION_INSERT, translateIfPossible(type)))); + add(MenuItem(MenuItem::Command, qt_("Caption"), caps.front().second)); return; } MenuDefinition captions; - - vector::const_iterator cit = caps.begin(); - vector::const_iterator end = caps.end(); - - for (int ii = 1; cit != end; ++cit, ++ii) { - docstring dummy; - docstring const type = split(*cit, dummy, ':'); + for (pair const & cap : caps) { + docstring const type = cap.first; docstring const trtype = translateIfPossible(type); docstring const cmitem = bformat(_("Caption (%1$s)"), trtype); - // make menu item optional, otherwise we would also see - // forbidden caption types if (switchcap) - addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(cmitem), - FuncRequest(LFUN_INSET_MODIFY, - from_ascii("changetype ") - + type), QString(), true)); + add(MenuItem(MenuItem::Command, toqstr(cmitem), cap.second)); else - captions.addWithStatusCheck(MenuItem(MenuItem::Command, - toqstr(trtype), - FuncRequest(LFUN_CAPTION_INSERT, - type), QString(), true)); + captions.add(MenuItem(MenuItem::Command, toqstr(trtype), cap.second)); } if (!captions.empty()) { MenuItem item(MenuItem::Submenu, qt_("Caption")); @@ -1650,6 +1724,128 @@ void MenuDefinition::expandCaptions(Buffer const * buf, bool switchcap) } +void MenuDefinition::expandQuotes(BufferView const * bv) +{ + if (!bv) + return; + + if (!bv->cursor().inTexted()) + return; + + Inset const * inset = bv->cursor().nextInset(); + if (!inset || inset->lyxCode() != QUOTE_CODE) { + add(MenuItem(MenuItem::Command, + qt_("No Quote in Scope!"), + FuncRequest(LFUN_NOACTION))); + return; + } + InsetQuotes const * qinset = + static_cast(inset); + + map styles = quoteparams.getTypes(); + string const qtype = qinset->getType(); + + map::const_iterator qq = styles.begin(); + map::const_iterator end = styles.end(); + + MenuDefinition aqs; + + BufferParams const & bp = bv->buffer().masterBuffer()->params(); + + // The global setting + InsetQuotesParams::QuoteStyle globalqs = bp.quotes_style; + char const globalqsc = quoteparams.getStyleChar(globalqs); + + // The current language's default + InsetQuotesParams::QuoteStyle langdefqs = + bp.getQuoteStyle(bv->cursor().current_font.language()->quoteStyle()); + char const langqs = quoteparams.getStyleChar(langdefqs); + + bool main_global_qs = false; + bool main_langdef_qs = false; + bool main_dynamic_qs = false; + docstring const subcmd = from_ascii("changetype "); + docstring const wildcards = from_ascii(".."); + // Add the items + // First the top level menu (all glyphs of the current style) ... + // Begin with dynamic (if they are current style), + if (qtype[0] == 'x') { + FuncRequest cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + from_ascii("xld")); + docstring desc = bformat(_("%1$s (dynamic)"), + quoteparams.getShortGuiLabel(globalqsc + from_ascii("ld"))); + add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + from_ascii("xls")); + desc = bformat(_("%1$s (dynamic)"), + quoteparams.getShortGuiLabel(globalqsc + from_ascii("ls"))); + add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + from_ascii("xrd")); + desc = bformat(_("%1$s (dynamic)"), + quoteparams.getShortGuiLabel(globalqsc + from_ascii("rd"))); + add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + from_ascii("xrs")); + desc = bformat(_("%1$s (dynamic)"), + quoteparams.getShortGuiLabel(globalqsc + from_ascii("rs"))); + add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + main_dynamic_qs = true; + } + // now traverse through the static styles ... + for (; qq != end; ++qq) { + docstring const style = from_ascii(qq->first); + bool langdef = (style[0] == langqs); + bool globaldef = (style[0] == globalqsc); + + if (prefixIs(style, qtype[0])) { + FuncRequest cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + style); + docstring const desc = quoteparams.getShortGuiLabel(style); + add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + main_global_qs = globaldef; + main_langdef_qs = langdef; + } + else if (!langdef && !globaldef && suffixIs(style, from_ascii("ld"))) { + docstring const desc = + quoteparams.getGuiLabel(quoteparams.getQuoteStyle(to_ascii(style))); + FuncRequest cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + style[0] + ".."); + aqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + } + } + + add(MenuItem(MenuItem::Separator)); + + bool display_static = false; + // ... then potentially items to reset to the defaults and to dynamic style ... + if (!main_dynamic_qs && globalqsc != 'x') { + FuncRequest cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + 'x' + wildcards); + docstring const desc = bformat(_("Use dynamic quotes (%1$s)|d"), + quoteparams.getGuiLabel(globalqs)); + add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + display_static = true; + } + if (!main_global_qs && langdefqs != globalqs) { + docstring const variant = main_dynamic_qs ? _("dynamic[[Quotes]]") : _("static[[Quotes]]"); + FuncRequest cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + globalqsc + wildcards); + docstring const desc = bformat(_("Reset to document default (%1$s, %2$s)|o"), + quoteparams.getGuiLabel(globalqs), variant); + add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + } + if (!main_langdef_qs) { + FuncRequest cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + globalqsc + wildcards); + docstring const desc = (main_dynamic_qs || display_static) + ? bformat(_("Reset to language default (%1$s, %2$s)|l"), + quoteparams.getGuiLabel(langdefqs), _("static[[Quotes]]")) + : bformat(_("Reset to language default (%1$s)|l"), + quoteparams.getGuiLabel(langdefqs)); + add(MenuItem(MenuItem::Command, toqstr(desc), cmd)); + } + + add(MenuItem(MenuItem::Separator)); + + // ... and a subitem with the rest + MenuItem item(MenuItem::Submenu, qt_("Change Style|y")); + item.setSubmenu(aqs); + add(item); +} + + void MenuDefinition::expandEnvironmentSeparators(BufferView const * bv) { if (!bv) @@ -1705,7 +1901,7 @@ 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); + void populate(QMenu * qMenu, MenuDefinition const & menu); /// Only needed for top level menus. MenuDefinition * top_level_menu; @@ -1738,7 +1934,7 @@ static QString label(MenuItem const & mi) return label; } -void Menu::Impl::populate(QMenu & qMenu, MenuDefinition const & menu) +void Menu::Impl::populate(QMenu * qMenu, MenuDefinition const & menu) { LYXERR(Debug::GUI, "populating menu " << menu.name()); if (menu.empty()) { @@ -1746,21 +1942,26 @@ void Menu::Impl::populate(QMenu & qMenu, MenuDefinition const & menu) 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(QIcon(), label(*m), - m->func(), m->tooltip(), &qMenu)); + for (MenuItem const & m : menu) + switch (m.kind()) { + case MenuItem::Separator: + qMenu->addSeparator(); + break; + case MenuItem::Submenu: { + QMenu * subMenu = qMenu->addMenu(label(m)); + populate(subMenu, m.submenu()); + subMenu->setEnabled(!subMenu->isEmpty()); + break; + } + case MenuItem::Command: + default: + // FIXME: A previous comment assured that MenuItem::Command was the + // only possible case in practice, but this is wrong. It would be + // good to document which cases are actually treated here. + qMenu->addAction(new Action(m.func(), QIcon(), label(m), + m.tooltip(), qMenu)); + break; } - } } #if (defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)) && (QT_VERSION >= 0x040600) @@ -1918,7 +2119,7 @@ void Menus::Impl::macxMenuBarInit(QMenuBar * qmb) QAction::MenuRole role; }; - static MacMenuEntry entries[] = { + static const MacMenuEntry entries[] = { {LFUN_DIALOG_SHOW, "aboutlyx", "About LyX", QAction::AboutRole}, {LFUN_DIALOG_SHOW, "prefs", "Preferences", @@ -1947,13 +2148,13 @@ void Menus::Impl::macxMenuBarInit(QMenuBar * qmb) // add the entries to a QMenu that will eventually be empty // and therefore invisible. QMenu * qMenu = qmb->addMenu("special"); - MenuDefinition::const_iterator cit = mac_special_menu_.begin(); - MenuDefinition::const_iterator end = mac_special_menu_.end(); - for (size_t i = 0 ; cit != end ; ++cit, ++i) { - Action * action = new Action(QIcon(), cit->label(), - cit->func(), QString(), qMenu); + size_t i = 0; + for (MenuItem const & m : mac_special_menu_) { + Action * action = new Action(m.func(), QIcon(), m.label(), + QString(), qMenu); action->setMenuRole(entries[i].role); qMenu->addAction(action); + ++i; } } @@ -1987,6 +2188,19 @@ void Menus::Impl::expand(MenuDefinition const & frommenu, tomenu.expandFormats(cit->kind(), buf); break; + case MenuItem::ExportFormat: { + if (!buf) + break; + string const format = buf->params().getDefaultOutputFormat(); + Format const * f = theFormats().getFormat(format); + docstring const name = f ? f->prettyname() : from_utf8(format); + docstring const label = bformat(_("Export [%1$s]|E"), name); + MenuItem item(MenuItem::Command, toqstr(label), + FuncRequest(LFUN_BUFFER_EXPORT)); + tomenu.addWithStatusCheck(item); + break; + } + case MenuItem::CharStyles: tomenu.expandFlexInsert(buf, InsetLayout::CHARSTYLE); break; @@ -2075,6 +2289,10 @@ void Menus::Impl::expand(MenuDefinition const & frommenu, tomenu.expandEnvironmentSeparators(bv); break; + case MenuItem::SwitchQuotes: + tomenu.expandQuotes(bv); + break; + case MenuItem::Submenu: { MenuItem item(*cit); item.setSubmenu(MenuDefinition(cit->submenuname())); @@ -2090,7 +2308,7 @@ void Menus::Impl::expand(MenuDefinition const & frommenu, break; case MenuItem::Command: - if (!mac_special_menu_.hasFunc(cit->func())) + if (!mac_special_menu_.hasFunc(*cit->func())) tomenu.addWithStatusCheck(*cit); } } @@ -2329,7 +2547,7 @@ void Menus::updateMenu(Menu * qmenu) if (qmenu->d->view) bv = qmenu->d->view->currentBufferView(); d->expand(fromLyxMenu, *qmenu->d->top_level_menu, bv); - qmenu->d->populate(*qmenu, *qmenu->d->top_level_menu); + qmenu->d->populate(qmenu, *qmenu->d->top_level_menu); }