]> git.lyx.org Git - features.git/blobdiff - src/frontends/qt/Menus.cpp
Additional check for empty word to avoid potential crash if no WordLangTuple is assig...
[features.git] / src / frontends / qt / Menus.cpp
index cb30e075363118e8258169f940e3b7a6a1c6307c..f4a2358f3cf79f286bfce00bde57de191a16e7ee 100644 (file)
@@ -31,6 +31,7 @@
 #include "BufferParams.h"
 #include "BufferView.h"
 #include "Converter.h"
+#include "Cursor.h"
 #include "CutAndPaste.h"
 #include "Floating.h"
 #include "FloatList.h"
@@ -148,9 +149,6 @@ public:
                /** 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,
@@ -199,7 +197,9 @@ public:
                /** Commands to separate environments (context menu version). */
                EnvironmentSeparatorsContext,
                /** This is the list of quotation marks available */
-               SwitchQuotes
+               SwitchQuotes,
+               /** Options in the Zoom menu **/
+               ZoomOptions
        };
 
        explicit MenuItem(Kind kind) : kind_(kind), optional_(false) {}
@@ -358,9 +358,9 @@ public:
        void expandFormats(MenuItem::Kind const kind, Buffer const * buf);
        void expandFloatListInsert(Buffer const * buf);
        void expandFloatInsert(Buffer const * buf);
-       void expandFlexInsert(Buffer const * buf, InsetLayout::InsetLyXType type);
+       void expandFlexInsert(Buffer const * buf, InsetLyXType type);
        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 expandToc2(Toc const & toc_list, size_t from, size_t to, int depth, const string & toc_type);
        void expandToc(Buffer const * buf);
        void expandPasteRecent(Buffer const * buf);
        void expandToolbars();
@@ -376,6 +376,7 @@ public:
        void expandCaptions(Buffer const * buf, bool switchcap = false);
        void expandEnvironmentSeparators(BufferView const *, bool contextmenu = false);
        void expandQuotes(BufferView const *);
+       void expandZoomOptions(BufferView const *);
        ///
        ItemList items_;
        ///
@@ -461,7 +462,6 @@ void MenuDefinition::read(Lexer & lex)
                md_bookmarks,
                md_charstyles,
                md_custom,
-               md_elements,
                md_endmenu,
                md_exportformat,
                md_exportformats,
@@ -492,7 +492,8 @@ void MenuDefinition::read(Lexer & lex)
                md_switchcaptions,
                md_env_separators,
                md_env_separatorscontext,
-               md_switchquotes
+               md_switchquotes,
+               md_zoomoptions
        };
 
        LexerKeyword menutags[] = {
@@ -504,7 +505,6 @@ void MenuDefinition::read(Lexer & lex)
                { "citestyles", md_citestyles },
                { "custom", md_custom },
                { "documents", md_documents },
-               { "elements", md_elements },
                { "end", md_endmenu },
                { "environmentseparators", md_env_separators },
                { "environmentseparatorscontext", md_env_separatorscontext },
@@ -534,7 +534,8 @@ void MenuDefinition::read(Lexer & lex)
                { "toc", md_toc },
                { "toolbars", md_toolbars },
                { "updateformats", md_updateformats },
-               { "viewformats", md_viewformats }
+               { "viewformats", md_viewformats },
+               { "zoomoptions", md_zoomoptions }
        };
 
        lex.pushTable(menutags);
@@ -574,10 +575,6 @@ void MenuDefinition::read(Lexer & lex)
                        add(MenuItem(MenuItem::Custom));
                        break;
 
-               case md_elements:
-                       add(MenuItem(MenuItem::Elements));
-                       break;
-
                case md_documents:
                        add(MenuItem(MenuItem::Documents));
                        break;
@@ -695,6 +692,10 @@ void MenuDefinition::read(Lexer & lex)
                        add(MenuItem(MenuItem::SwitchQuotes));
                        break;
 
+               case md_zoomoptions:
+                       add(MenuItem(MenuItem::ZoomOptions));
+                       break;
+
                case md_optsubmenu:
                case md_submenu: {
                        lex.next(true);
@@ -721,8 +722,8 @@ void MenuDefinition::read(Lexer & lex)
 
 bool MenuDefinition::hasFunc(FuncRequest const & func) const
 {
-       for (const_iterator it = begin(), et = end(); it != et; ++it)
-               if (*it->func() == func)
+       for (auto const & it : *this)
+               if (*it.func() == func)
                        return true;
        return false;
 }
@@ -855,7 +856,9 @@ void MenuDefinition::expandSpellingSuggestions(BufferView const * bv)
                                                                true,     // match word
                                                                false,    // all words
                                                                true,     // forward
-                                                               false))); // find next
+                                                               false,    // find next
+                                                               false,    // auto-wrap
+                                                               false))); // only selection
                                        if (i < m)
                                                add(w);
                                        else
@@ -868,26 +871,34 @@ void MenuDefinition::expandSpellingSuggestions(BufferView const * bv)
                                docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
                                add(MenuItem(MenuItem::Command, qt_("Add to personal dictionary|n"),
                                                FuncRequest(LFUN_SPELLING_ADD, arg)));
-                               add(MenuItem(MenuItem::Command, qt_("Ignore all|I"),
+                               add(MenuItem(MenuItem::Command, qt_("Ignore this occurrence|g"),
+                                               FuncRequest(LFUN_FONT_NO_SPELLCHECK, arg)));
+                               add(MenuItem(MenuItem::Command, qt_("Ignore all for this session|I"),
                                                FuncRequest(LFUN_SPELLING_IGNORE, arg)));
+                               add(MenuItem(MenuItem::Command, qt_("Ignore all in this document|d"),
+                                               FuncRequest(LFUN_SPELLING_ADD_LOCAL, arg)));
                        }
                }
                break;
-       case SpellChecker::LEARNED_WORD: {
-                       LYXERR(Debug::GUI, "Learned Word.");
+       case SpellChecker::WORD_OK: {
+                       if (wl.word().empty())
+                               break;
+                       LYXERR(Debug::GUI, "Valid Word.");
                        docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
                        add(MenuItem(MenuItem::Command, qt_("Remove from personal dictionary|r"),
                                        FuncRequest(LFUN_SPELLING_REMOVE, arg)));
                }
                break;
+       case SpellChecker::DOCUMENT_LEARNED_WORD: {
+                       LYXERR(Debug::GUI, "Document-Learned Word.");
+                       docstring const arg = wl.word() + " " + from_ascii(wl.lang()->lang());
+                       add(MenuItem(MenuItem::Command, qt_("Remove from document dictionary|r"),
+                                       FuncRequest(LFUN_SPELLING_REMOVE_LOCAL, arg)));
+               }
+               break;
        case SpellChecker::NO_DICTIONARY:
                LYXERR(Debug::GUI, "No dictionary for language " + from_ascii(wl.lang()->lang()));
                // FALLTHROUGH
-       case SpellChecker::WORD_OK:
-       case SpellChecker::COMPOUND_WORD:
-       case SpellChecker::ROOT_FOUND:
-       case SpellChecker::IGNORED_WORD:
-               break;
        }
 }
 
@@ -995,9 +1006,9 @@ void MenuDefinition::expandDocuments()
        MenuItem item(MenuItem::Submenu, qt_("Hidden|H"));
        item.setSubmenu(MenuDefinition(qt_("Hidden|H")));
 
-       Buffer * first = theBufferList().first();
+       Buffer * const first = theBufferList().first();
        if (!first) {
-               add(MenuItem(MenuItem::Info, qt_("<No Documents Open>")));
+               add(MenuItem(MenuItem::Info, qt_("(No Documents Open)")));
                return;
        }
 
@@ -1013,7 +1024,7 @@ void MenuDefinition::expandDocuments()
                if (!b.isClean())
                        label += "*";
                if (b.notifiesExternalModification())
-                       label += QChar(0x26a0);
+                       label += QChar(0x26a0); // warning sign ⚠
                if (i < 10)
                        label = QString::number(i) + ". " + label + '|' + QString::number(i);
                add(MenuItem(MenuItem::Command, label,
@@ -1063,7 +1074,7 @@ void MenuDefinition::expandBookmarks()
                }
        }
        if (empty)
-               add(MenuItem(MenuItem::Info, qt_("<No Bookmarks Saved Yet>")));
+               add(MenuItem(MenuItem::Info, qt_("(No Bookmarks Saved Yet)")));
 }
 
 
@@ -1224,7 +1235,7 @@ void MenuDefinition::expandFloatInsert(Buffer const * buf)
 
 
 void MenuDefinition::expandFlexInsert(
-               Buffer const * buf, InsetLayout::InsetLyXType type)
+               Buffer const * buf, InsetLyXType type)
 {
        if (!buf)
                return;
@@ -1250,8 +1261,8 @@ void MenuDefinition::expandFlexInsert(
                }
        }
        // FIXME This is a little clunky.
-       if (items_.empty() && type == InsetLayout::CUSTOM && !buf->hasReadonlyFlag())
-               add(MenuItem(MenuItem::Help, qt_("No Custom Insets Defined!")));
+       if (items_.empty() && type == InsetLyXType::CUSTOM && !buf->hasReadonlyFlag())
+               add(MenuItem(MenuItem::Help, qt_("(No Custom Insets Defined)")));
 }
 
 
@@ -1266,7 +1277,7 @@ size_t const menu_size_limit = 80;
 
 void MenuDefinition::expandToc2(Toc const & toc_list,
                                 size_t from, size_t to, int depth,
-                                string toc_type)
+                                string const & toc_type)
 {
        int shortcut_count = 0;
 
@@ -1288,8 +1299,7 @@ void MenuDefinition::expandToc2(Toc const & toc_list,
                                                label += QString::number(++shortcut_count);
                                }
                        }
-                       add(MenuItem(MenuItem::Command, label,
-                                           FuncRequest(toc_list[i].action())));
+                       add(MenuItem(MenuItem::Command, label, toc_list[i].action()));
                        // separator after the menu heading
                        if (toc_list[i].depth() < depth)
                                add(MenuItem(MenuItem::Separator));
@@ -1317,8 +1327,7 @@ void MenuDefinition::expandToc2(Toc const & toc_list,
                                break;
                        }
                        if (new_pos == pos + 1) {
-                               add(MenuItem(MenuItem::Command,
-                                                   label, FuncRequest(toc_list[pos].action())));
+                               add(MenuItem(MenuItem::Command, label, toc_list[pos].action()));
                        } else {
                                MenuDefinition sub;
                                sub.expandToc2(toc_list, pos, new_pos, depth + 1, toc_type);
@@ -1378,7 +1387,7 @@ void MenuDefinition::expandToc(Buffer const * buf)
        }
        // Handle normal TOC
        add(MenuItem(MenuItem::Separator));
-       TocList::const_iterator cit = toc_list.find("tableofcontents");
+       TocList::const_iterator const cit = toc_list.find("tableofcontents");
        if (cit == toc_list.end())
                LYXERR(Debug::GUI, "No table of contents.");
        else {
@@ -1423,8 +1432,19 @@ void MenuDefinition::expandToolbars()
        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));
+               MenuItem item(MenuItem::Command, toqstr(cit->gui_name),
+                             FuncRequest(LFUN_TOOLBAR_TOGGLE, cit->name));
+               if (cit->allow_auto) {
+                       MenuDefinition tristate;
+                       tristate.add(MenuItem(MenuItem::Command, qt_("[[Toolbar]]On|O"),
+                                             FuncRequest(LFUN_TOOLBAR_SET, cit->name + " on")));
+                       tristate.add(MenuItem(MenuItem::Command, qt_("[[Toolbar]]Off|f"),
+                                             FuncRequest(LFUN_TOOLBAR_SET, cit->name + " off")));
+                       tristate.add(MenuItem(MenuItem::Command, qt_("[[Toolbar]]Automatic|A"),
+                                             FuncRequest(LFUN_TOOLBAR_SET, cit->name + " auto")));
+                       item = MenuItem(MenuItem::Submenu,toqstr(cit->gui_name));
+                       item.setSubmenu(tristate);
+               }
                if (guiApp->toolbars().isMainToolbar(cit->name))
                        add(item);
                else
@@ -1799,6 +1819,48 @@ void MenuDefinition::expandCaptions(Buffer const * buf, bool switchcap)
 }
 
 
+void MenuDefinition::expandZoomOptions(BufferView const * bv)
+{
+       if (!bv)
+               return;
+
+       add(MenuItem(MenuItem::Command,
+                    toqstr(bformat(_("Reset to Default (%1$d%)|R"),
+                                   lyxrc.defaultZoom)),
+                    FuncRequest(LFUN_BUFFER_ZOOM)));
+       add(MenuItem(MenuItem::Command, qt_("Zoom In|I"),
+                    FuncRequest(LFUN_BUFFER_ZOOM_IN)));
+       add(MenuItem(MenuItem::Command, qt_("Zoom Out|O"),
+                    FuncRequest(LFUN_BUFFER_ZOOM_OUT)));
+       add(MenuItem(MenuItem::Separator));
+       // Offer some fractional values of the default
+       int z = lyxrc.defaultZoom * 1.75;
+       add(MenuItem(MenuItem::Command,
+                    toqstr(bformat(_("[[ZOOM]]%1$d%"), z)),
+                    FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(z))));
+       z = lyxrc.defaultZoom * 1.5;
+       add(MenuItem(MenuItem::Command,
+                    toqstr(bformat(_("[[ZOOM]]%1$d%"), z)),
+                    FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(z))));
+       z = lyxrc.defaultZoom * 1.25;
+       add(MenuItem(MenuItem::Command,
+                    toqstr(bformat(_("[[ZOOM]]%1$d%"), z)),
+                    FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(z))));
+       z = lyxrc.defaultZoom * 0.75;
+       add(MenuItem(MenuItem::Command,
+                    toqstr(bformat(_("[[ZOOM]]%1$d%"), z)),
+                    FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(z))));
+       z = lyxrc.defaultZoom * 0.5;
+       add(MenuItem(MenuItem::Command,
+                    toqstr(bformat(_("[[ZOOM]]%1$d%"), z)),
+                    FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(z))));
+       z = lyxrc.defaultZoom * 0.25;
+       add(MenuItem(MenuItem::Command,
+                    toqstr(bformat(_("[[ZOOM]]%1$d%"), z)),
+                    FuncRequest(LFUN_BUFFER_ZOOM, convert<string>(z))));
+}
+
+
 void MenuDefinition::expandQuotes(BufferView const * bv)
 {
        if (!bv)
@@ -1817,22 +1879,18 @@ void MenuDefinition::expandQuotes(BufferView const * bv)
        InsetQuotes const * qinset =
                static_cast<InsetQuotes const *>(inset);
 
-       map<string, docstring> styles = quoteparams.getTypes();
        string const qtype = qinset->getType();
 
-       map<string, docstring>::const_iterator qq = styles.begin();
-       map<string, docstring>::const_iterator end = styles.end();
-
        MenuDefinition aqs;
 
        BufferParams const & bp = bv->buffer().masterBuffer()->params();
 
        // The global setting
-       InsetQuotesParams::QuoteStyle globalqs = bp.quotes_style;
+       QuoteStyle globalqs = bp.quotes_style;
        char const globalqsc = quoteparams.getStyleChar(globalqs);
 
        // The current language's default
-       InsetQuotesParams::QuoteStyle langdefqs =
+       QuoteStyle langdefqs =
                bp.getQuoteStyle(bv->cursor().current_font.language()->quoteStyle());
        char const langqs = quoteparams.getStyleChar(langdefqs);
 
@@ -1864,10 +1922,12 @@ void MenuDefinition::expandQuotes(BufferView const * bv)
                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);
+       map<string, docstring> styles = quoteparams.getTypes();
+       for (auto const & s : styles) {
+               char style_char = (s.first)[0];
+               bool langdef = (style_char == langqs);
+               bool globaldef = (style_char == globalqsc);
+               docstring const style = from_ascii(s.first);
 
                if (prefixIs(style, qtype[0])) {
                        FuncRequest cmd = FuncRequest(LFUN_INSET_MODIFY, subcmd + style);
@@ -1938,12 +1998,11 @@ void MenuDefinition::expandEnvironmentSeparators(BufferView const * bv,
        docstring prevlayout;
        depth_type current_depth = par.params().depth();
        // check if we have an environment in our scope
-       Paragraph cpar = par;
        while (true) {
                if (pit == 0)
                        break;
                --pit;
-               cpar = text->getPar(pit);
+               Paragraph cpar = text->getPar(pit);
                if (cpar.layout().isEnvironment() && prevlayout.empty()
                    && cpar.params().depth() <= current_depth)
                                prevlayout = cpar.layout().name();
@@ -2088,7 +2147,7 @@ void Menu::Impl::populate(QMenu * qMenu, MenuDefinition const & menu)
 class AlwaysMnemonicStyle : public QProxyStyle {
 public:
        int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
-               QStyleHintReturn *returnData = 0) const
+               QStyleHintReturn *returnData = 0) const override
        {
                if (hint == QStyle::SH_UnderlineShortcut)
                        return 1;
@@ -2205,7 +2264,7 @@ MenuDefinition Menus::Impl::mac_special_menu_;
      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
+     chain until one of the above are satisfied. 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
@@ -2313,7 +2372,8 @@ void Menus::Impl::expand(MenuDefinition const & frommenu,
                                break;
                        string const format = buf->params().getDefaultOutputFormat();
                        Format const * f = theFormats().getFormat(format);
-                       docstring const name = f ? f->prettyname() : from_utf8(format);
+                       docstring const name = f ? translateIfPossible(f->prettyname())
+                                                : from_utf8(format);
                        docstring const label = bformat(_("Export [%1$s]|E"), name);
                        MenuItem item(MenuItem::Command, toqstr(label),
                                      FuncRequest(LFUN_BUFFER_EXPORT));
@@ -2322,15 +2382,11 @@ void Menus::Impl::expand(MenuDefinition const & frommenu,
                }
 
                case MenuItem::CharStyles:
-                       tomenu.expandFlexInsert(buf, InsetLayout::CHARSTYLE);
+                       tomenu.expandFlexInsert(buf, InsetLyXType::CHARSTYLE);
                        break;
 
                case MenuItem::Custom:
-                       tomenu.expandFlexInsert(buf, InsetLayout::CUSTOM);
-                       break;
-
-               case MenuItem::Elements:
-                       tomenu.expandFlexInsert(buf, InsetLayout::ELEMENT);
+                       tomenu.expandFlexInsert(buf, InsetLyXType::CUSTOM);
                        break;
 
                case MenuItem::FloatListInsert:
@@ -2422,6 +2478,10 @@ void Menus::Impl::expand(MenuDefinition const & frommenu,
                        tomenu.expandQuotes(bv);
                        break;
 
+               case MenuItem::ZoomOptions:
+                       tomenu.expandZoomOptions(bv);
+                       break;
+
                case MenuItem::Submenu: {
                        MenuItem item(*cit);
                        item.setSubmenu(MenuDefinition(cit->submenuname()));