]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/Menus.cpp
fix completion painting for RTL (inline completion and completion list)
[lyx.git] / src / frontends / qt4 / Menus.cpp
index e9b3795f0298d3260a857502a5dd83e2ff8e27ab..7acb9e11b35ee4b35c3d1d44bea6f4ddd0d47d87 100644 (file)
 #include "LyX.h" // for lastfiles
 #include "LyXFunc.h"
 #include "Paragraph.h"
+#include "ParIterator.h"
 #include "Session.h"
 #include "TextClass.h"
 #include "TocBackend.h"
-#include "ToolbarBackend.h"
+#include "Toolbars.h"
 
 #include "insets/Inset.h"
 #include "insets/InsetCitation.h"
+#include "insets/InsetGraphics.h"
 
-#include "support/assert.h"
+#include "support/lassert.h"
 #include "support/convert.h"
 #include "support/debug.h"
+#include "support/docstring_list.h"
 #include "support/filetools.h"
 #include "support/gettext.h"
 #include "support/lstrings.h"
@@ -66,7 +69,6 @@
 #include <boost/shared_ptr.hpp>
 
 #include <algorithm>
-#include <ostream>
 #include <vector>
 
 using namespace std;
@@ -138,7 +140,9 @@ public:
                /** Available branches in document */
                Branches,
                /** Available citation styles for a given citation */
-               CiteStyles
+               CiteStyles,
+               /** Available graphics groups */
+               GraphicsGroups
        };
 
        explicit MenuItem(Kind kind) : kind_(kind), optional_(false) {}
@@ -266,7 +270,7 @@ public:
        
        // search for func in this menu iteratively, and put menu
        // names in a stack.
-       bool searchMenu(FuncRequest const & func, std::vector<docstring> & names)
+       bool searchMenu(FuncRequest const & func, docstring_list & names)
                const;
        ///
        bool hasFunc(FuncRequest const &) const;
@@ -291,6 +295,7 @@ public:
        void expandToolbars();
        void expandBranches(Buffer const * buf);
        void expandCiteStyles(BufferView const *);
+       void expandGraphicsGroups(BufferView const *);
        ///
        ItemList items_;
        ///
@@ -347,7 +352,7 @@ void MenuDefinition::addWithStatusCheck(MenuItem const & i)
                        }
                        if (enabled || !i.optional()) {
                                items_.push_back(i);
-                               items_.back().status().enabled(enabled);
+                               items_.back().status().setEnabled(enabled);
                        }
                }
                else
@@ -391,7 +396,8 @@ void MenuDefinition::read(Lexer & lex)
                md_floatlistinsert,
                md_floatinsert,
                md_pasterecent,
-               md_toolbars
+               md_toolbars,
+               md_graphicsgroups
        };
 
        LexerKeyword menutags[] = {
@@ -406,6 +412,7 @@ void MenuDefinition::read(Lexer & lex)
                { "exportformats", md_exportformats },
                { "floatinsert", md_floatinsert },
                { "floatlistinsert", md_floatlistinsert },
+               { "graphicsgroups", md_graphicsgroups },
                { "importformats", md_importformats },
                { "item", md_item },
                { "lastfiles", md_lastfiles },
@@ -514,6 +521,10 @@ void MenuDefinition::read(Lexer & lex)
                        add(MenuItem(MenuItem::CiteStyles));
                        break;
 
+               case md_graphicsgroups:
+                       add(MenuItem(MenuItem::GraphicsGroups));
+                       break;
+
                case md_optsubmenu:
                        optional = true;
                        // fallback to md_submenu
@@ -565,24 +576,23 @@ void MenuDefinition::checkShortcuts() const
                if (shortcut.isEmpty())
                        continue;
                if (!it1->label().contains(shortcut))
-                       lyxerr << "Menu warning: menu entry \""
-                              << fromqstr(it1->label())
+                       LYXERR0("Menu warning: menu entry \""
+                              << it1->label()
                               << "\" does not contain shortcut `"
-                              << fromqstr(shortcut) << "'." << endl;
+                              << shortcut << "'.");
                for (const_iterator it2 = begin(); it2 != it1 ; ++it2) {
                        if (!it2->shortcut().compare(shortcut, Qt::CaseInsensitive)) {
-                               lyxerr << "Menu warning: menu entries "
-                                      << '"' << fromqstr(it1->fulllabel())
-                                      << "\" and \"" << fromqstr(it2->fulllabel())
-                                      << "\" share the same shortcut."
-                                      << endl;
+                               LYXERR0("Menu warning: menu entries "
+                                      << '"' << it1->fulllabel()
+                                      << "\" and \"" << it2->fulllabel()
+                                      << "\" share the same shortcut.");
                        }
                }
        }
 }
 
 
-bool MenuDefinition::searchMenu(FuncRequest const & func, vector<docstring> & names) const
+bool MenuDefinition::searchMenu(FuncRequest const & func, docstring_list & names) const
 {
        const_iterator m = begin();
        const_iterator m_end = end();
@@ -595,8 +605,7 @@ bool MenuDefinition::searchMenu(FuncRequest const & func, vector<docstring> & na
                        names.push_back(qstring_to_ucs4(m->label()));
                        if (!m->hasSubmenu()) {
                                LYXERR(Debug::GUI, "Warning: non existing sub menu label="
-                                       << fromqstr(m->label())
-                                       << " name=" << fromqstr(m->submenuname()));
+                                       << m->label() << " name=" << m->submenuname());
                                names.pop_back();
                                continue;
                        }
@@ -626,6 +635,25 @@ QString limitStringLength(docstring const & str)
 }
 
 
+void MenuDefinition::expandGraphicsGroups(BufferView const * bv)
+{
+       if (!bv)
+               return;
+       set<string> grp;
+       graphics::getGraphicsGroups(bv->buffer(), grp);
+       if (grp.empty())
+               return;
+
+       set<string>::const_iterator it = grp.begin();
+       set<string>::const_iterator end = grp.end();
+       add(MenuItem(MenuItem::Command, qt_("No Group"), 
+                    FuncRequest(LFUN_SET_GRAPHICS_GROUP)));
+       for (; it != end; it++) {
+               addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(*it),
+                               FuncRequest(LFUN_SET_GRAPHICS_GROUP, *it)));
+       }
+}
+
 void MenuDefinition::expandLastfiles()
 {
        LastFilesSection::LastFiles const & lf = LyX::cref().session().lastFiles().lastFiles();
@@ -722,17 +750,24 @@ void MenuDefinition::expandFormats(MenuItem::Kind kind, Buffer const * buf)
        for (; fit != end ; ++fit) {
                if ((*fit)->dummy())
                        continue;
-               QString label = toqstr((*fit)->prettyname());
-               QString const shortcut = toqstr((*fit)->shortcut());
+
+               docstring lab = from_utf8((*fit)->prettyname());
+               docstring scut = from_utf8((*fit)->shortcut());
+               docstring const tmplab = lab;
+               if (!scut.empty())
+                       lab += char_type('|') + scut;
+               docstring lab_i18n = translateIfPossible(lab);
+               bool const untranslated = (lab == lab_i18n);
+               QString const shortcut = toqstr(split(lab_i18n, lab, '|'));
+               QString label = toqstr(lab);
+               if (untranslated)
+                       // this might happen if the shortcut
+                       // has been redefined
+                       label = toqstr(translateIfPossible(tmplab));
 
                switch (kind) {
                case MenuItem::ImportFormats:
-                       // FIXME: This is a hack, we should rather solve
-                       // FIXME: bug 2488 instead.
-                       if ((*fit)->name() == "text")
-                               label = qt_("Plain Text");
-                       else if ((*fit)->name() == "textparagraph")
-                               label = qt_("Plain Text, Join Lines");
                        label += "...";
                        break;
                case MenuItem::ViewFormats:
@@ -745,12 +780,7 @@ void MenuDefinition::expandFormats(MenuItem::Kind kind, Buffer const * buf)
                        LASSERT(false, /**/);
                        break;
                }
-               // FIXME: if we had proper support for translating the
-               // format names defined in configure.py, there would
-               // not be a need to check whether the shortcut is
-               // correct. If we add it uncondiitonally, it would
-               // create useless warnings on bad shortcuts
-               if (!shortcut.isEmpty() && label.contains(shortcut))
+               if (!shortcut.isEmpty())
                        label += '|' + shortcut;
 
                if (buf)
@@ -777,7 +807,7 @@ void MenuDefinition::expandFloatListInsert(Buffer const * buf)
        for (; cit != end; ++cit) {
                addWithStatusCheck(MenuItem(MenuItem::Command,
                                    qt_(cit->second.listName()),
-                                   FuncRequest(LFUN_FLOAT_LIST,
+                                   FuncRequest(LFUN_FLOAT_LIST_INSERT,
                                                cit->second.type())));
        }
 }
@@ -918,45 +948,7 @@ void MenuDefinition::expandToc(Buffer const * buf)
                if (cit->first == "tableofcontents")
                        continue;
 
-               string const & floatName = floatlist.getType(cit->first).listName();
-               QString label;
-               bool in_other_list = true;
-               if (!floatName.empty()) {
-                       label = qt_(floatName);
-                       in_other_list = false;
-               }
-               else if (cit->first == "child") {
-                       label = qt_("Child Documents");
-                       in_other_list = false;
-               } else if (cit->first == "graphics")
-                       label = qt_("List of Graphics");
-               else if (cit->first == "equation")
-                       label = qt_("List of Equations");
-               else if (cit->first == "index")
-                       label = qt_("List of Indexes");
-               else if (cit->first == "listing") {
-                       // FIXME: the listing navigate menu causes a crash for unknown
-                       // reason. See http://bugzilla.lyx.org/show_bug.cgi?id=4613
-                       // This is a temporary fix:
-                       //label = qt_("List of Listings");
-                       continue;
-               }
-               else if (cit->first == "marginalnote")
-                       label = qt_("List of Marginal notes");
-               else if (cit->first == "note")
-                       label = qt_("List of Notes");
-               else if (cit->first == "footnote")
-                       label = qt_("List of Footnotes");
-               else if (cit->first == "label")
-                       label = qt_("Labels and References");
-               else if (cit->first == "citation")
-                       label = qt_("List of Citations");
-               else
-                       // This should not happen unless the entry is missing above.
-                       label = qt_("Other floats: ") + toqstr(cit->first);
-
                MenuDefinition submenu;
-
                if (cit->second.size() >= 30) {
                        FuncRequest f(LFUN_DIALOG_SHOW, "toc " + cit->first);
                        submenu.add(MenuItem(MenuItem::Command, qt_("Open Navigator..."), f));
@@ -964,20 +956,20 @@ void MenuDefinition::expandToc(Buffer const * buf)
                        TocIterator ccit = cit->second.begin();
                        TocIterator eend = cit->second.end();
                        for (; ccit != eend; ++ccit) {
-                               QString const label = limitStringLength(ccit->str());
-                               submenu.add(MenuItem(MenuItem::Command, label,
+                               submenu.add(MenuItem(MenuItem::Command,
+                                       limitStringLength(ccit->str()),
                                        FuncRequest(ccit->action())));
                        }
                }
 
-               MenuItem item(MenuItem::Submenu, label);
+               MenuItem item(MenuItem::Submenu, guiName(cit->first, buf->params()));
                item.setSubmenu(submenu);
-               if (in_other_list)
-                       other_lists.add(item);
-               else {
+               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"));
@@ -985,25 +977,23 @@ void MenuDefinition::expandToc(Buffer const * buf)
                add(item);
        }
 
-
        // Handle normal TOC
        cit = toc_list.find("tableofcontents");
        if (cit == end) {
                addWithStatusCheck(MenuItem(MenuItem::Command,
                                    qt_("No Table of contents"),
                                    FuncRequest()));
-       } else {
+       } else
                expandToc2(cit->second, 0, cit->second.size(), 0);
-       }
 }
 
 
 void MenuDefinition::expandPasteRecent()
 {
-       vector<docstring> const sel = cap::availableSelections();
+       docstring_list const sel = cap::availableSelections();
 
-       vector<docstring>::const_iterator cit = sel.begin();
-       vector<docstring>::const_iterator end = sel.end();
+       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),
@@ -1014,27 +1004,23 @@ void MenuDefinition::expandPasteRecent()
 
 void MenuDefinition::expandToolbars()
 {
-       //
+       MenuDefinition other_lists;
        // extracts the toolbars from the backend
-       ToolbarBackend::Toolbars::const_iterator cit = toolbarbackend.begin();
-       ToolbarBackend::Toolbars::const_iterator end = toolbarbackend.end();
-
+       Toolbars::Infos::const_iterator cit = guiApp->toolbars().begin();
+       Toolbars::Infos::const_iterator end = guiApp->toolbars().end();
        for (; cit != end; ++cit) {
-               QString label = qt_(cit->gui_name);
-               // frontends are not supposed to turn on/off toolbars,
-               // if they cannot update ToolbarBackend::flags. That
-               // is to say, ToolbarsBackend::flags should reflect
-               // the true state of toolbars.
-               //
-               // menu is displayed as
-               //       on/off review
-               // and
-               //              review (auto)
-               // in the case of auto.
-               if (cit->flags & ToolbarInfo::AUTO)
-                       label += qt_(" (auto)");
-               add(MenuItem(MenuItem::Command, label,
-                                   FuncRequest(LFUN_TOOLBAR_TOGGLE, cit->name + " allowauto")));
+               MenuItem const item(MenuItem::Command, qt_(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);
        }
 }
 
@@ -1091,13 +1077,16 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
        
        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());
-       vector<docstring> citeStrings =
+       docstring_list citeStrings =
                buf->masterBibInfo().getCiteStrings(key, bv->buffer());
 
-       vector<docstring>::const_iterator cit = citeStrings.begin();
-       vector<docstring>::const_iterator end = citeStrings.end();
+       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;
@@ -1156,9 +1145,9 @@ static QString label(MenuItem const & mi)
 
 void Menu::Impl::populate(QMenu & qMenu, MenuDefinition const & menu)
 {
-       LYXERR(Debug::GUI, "populating menu " << fromqstr(menu.name()));
+       LYXERR(Debug::GUI, "populating menu " << menu.name());
        if (menu.size() == 0) {
-               LYXERR(Debug::GUI, "\tERROR: empty menu " << fromqstr(menu.name()));
+               LYXERR(Debug::GUI, "\tERROR: empty menu " << menu.name());
                return;
        }
        LYXERR(Debug::GUI, " *****  menu entries " << menu.size());
@@ -1396,6 +1385,10 @@ void Menus::Impl::expand(MenuDefinition const & frommenu,
                        tomenu.expandToc(buf);
                        break;
 
+               case MenuItem::GraphicsGroups:
+                       tomenu.expandGraphicsGroups(bv);
+                       break;
+
                case MenuItem::Submenu: {
                        MenuItem item(*cit);
                        item.setSubmenu(MenuDefinition(cit->submenuname()));
@@ -1435,7 +1428,7 @@ MenuDefinition const & Menus::Impl::getMenu(QString const & name) const
        const_iterator cit = find_if(menulist_.begin(), menulist_.end(),
                MenuNamesEqual(name));
        if (cit == menulist_.end())
-               lyxerr << "No submenu named " << fromqstr(name) << endl;
+               LYXERR0("No submenu named " << name);
        LASSERT(cit != menulist_.end(), /**/);
        return (*cit);
 }
@@ -1446,7 +1439,7 @@ MenuDefinition & Menus::Impl::getMenu(QString const & name)
        iterator it = find_if(menulist_.begin(), menulist_.end(),
                MenuNamesEqual(name));
        if (it == menulist_.end())
-               lyxerr << "No submenu named " << fromqstr(name) << endl;
+               LYXERR0("No submenu named " << name);
        LASSERT(it != menulist_.end(), /**/);
        return (*it);
 }
@@ -1518,7 +1511,7 @@ void Menus::read(Lexer & lex)
 
 
 bool Menus::searchMenu(FuncRequest const & func,
-       vector<docstring> & names) const
+       docstring_list & names) const
 {
        MenuDefinition menu;
        d->expand(d->menubar_, menu, 0);
@@ -1538,11 +1531,11 @@ void Menus::fillMenuBar(QMenuBar * qmb, GuiView * view, bool initial)
                qmb->clear();
        }
 
-       LYXERR(Debug::GUI, "populating menu bar" << fromqstr(d->menubar_.name()));
+       LYXERR(Debug::GUI, "populating menu bar" << d->menubar_.name());
 
        if (d->menubar_.size() == 0) {
                LYXERR(Debug::GUI, "\tERROR: empty menu bar"
-                       << fromqstr(d->menubar_.name()));
+                       << d->menubar_.name());
                return;
        }
        LYXERR(Debug::GUI, "menu bar entries " << d->menubar_.size());
@@ -1559,16 +1552,16 @@ void Menus::fillMenuBar(QMenuBar * qmb, GuiView * view, bool initial)
        for (; m != end; ++m) {
 
                if (m->kind() != MenuItem::Submenu) {
-                       LYXERR(Debug::GUI, "\tERROR: not a submenu " << fromqstr(m->label()));
+                       LYXERR(Debug::GUI, "\tERROR: not a submenu " << m->label());
                        continue;
                }
 
-               LYXERR(Debug::GUI, "menu bar item " << fromqstr(m->label())
-                       << " is a submenu named " << fromqstr(m->submenuname()));
+               LYXERR(Debug::GUI, "menu bar item " << m->label()
+                       << " is a submenu named " << m->submenuname());
 
                QString name = m->submenuname();
                if (!d->hasMenu(name)) {
-                       LYXERR(Debug::GUI, "\tERROR: " << fromqstr(name)
+                       LYXERR(Debug::GUI, "\tERROR: " << name
                                << " submenu has no menu!");
                        continue;
                }
@@ -1584,7 +1577,7 @@ void Menus::fillMenuBar(QMenuBar * qmb, GuiView * view, bool initial)
 
 void Menus::updateMenu(Menu * qmenu)
 {
-       LYXERR(Debug::GUI, "Triggered menu: " << fromqstr(qmenu->d->name));
+       LYXERR(Debug::GUI, "Triggered menu: " << qmenu->d->name);
        qmenu->clear();
 
        if (qmenu->d->name.isEmpty())
@@ -1596,7 +1589,7 @@ void Menus::updateMenu(Menu * qmenu)
        if (!d->hasMenu(qmenu->d->name)) {
                qmenu->addAction(qt_("No action defined!"));
                LYXERR(Debug::GUI, "\tWARNING: non existing menu: "
-                       << fromqstr(qmenu->d->name));
+                       << qmenu->d->name);
                return;
        }
 
@@ -1611,10 +1604,10 @@ void Menus::updateMenu(Menu * qmenu)
 
 Menu * Menus::menu(QString const & name, GuiView & view)
 {
-       LYXERR(Debug::GUI, "Context menu requested: " << fromqstr(name));
+       LYXERR(Debug::GUI, "Context menu requested: " << name);
        Menu * menu = d->name_map_[&view].value(name, 0);
        if (!menu && !name.startsWith("context-")) {
-               LYXERR0("requested context menu not found: " << fromqstr(name));
+               LYXERR0("requested context menu not found: " << name);
                return 0;
        }