]> git.lyx.org Git - lyx.git/blobdiff - src/MenuBackend.cpp
Andre's s/getTextClass/textClass/ cleanup.
[lyx.git] / src / MenuBackend.cpp
index c96568350a20ffd038b57ab5ab9268522cda949c..05aa0b461de1e5833d62a5567ca3ff43d18f251b 100644 (file)
 #include "Buffer.h"
 #include "BufferList.h"
 #include "BufferParams.h"
+#include "Converter.h"
 #include "CutAndPaste.h"
-#include "debug.h"
-#include "Exporter.h"
 #include "Floating.h"
 #include "FloatList.h"
 #include "Format.h"
-#include "gettext.h"
-#include "Importer.h"
-#include "kb_keymap.h"
+#include "KeyMap.h"
 #include "Session.h"
 #include "LyXAction.h"
 #include "LyX.h" // for lastfiles
 #include "LyXFunc.h"
 #include "Lexer.h"
 #include "Paragraph.h"
+#include "TextClass.h"
 #include "TocBackend.h"
 #include "ToolbarBackend.h"
 
+#include "frontends/Application.h"
+
+#include "support/convert.h"
+#include "support/debug.h"
 #include "support/filetools.h"
+#include "support/gettext.h"
 #include "support/lstrings.h"
-#include "support/convert.h"
 
 #include <boost/bind.hpp>
 
 #include <algorithm>
+#include <ostream>
 
-
-namespace lyx {
-
-using support::compare_ascii_no_case;
-using support::contains;
-using support::makeDisplayPath;
-using support::token;
-
+using namespace std;
 using boost::bind;
+using namespace lyx::support;
 
-using std::auto_ptr;
-using std::endl;
-using std::equal_to;
-using std::find_if;
-using std::max;
-using std::sort;
-using std::string;
-using std::vector;
-
+namespace lyx {
 
 namespace {
 
-class MenuNamesEqual : public std::unary_function<Menu, bool> {
+class MenuNamesEqual : public unary_function<Menu, bool> {
 public:
        MenuNamesEqual(docstring const & name)
                : name_(name) {}
-       bool operator()(Menu const & menu) const
-       {
+       bool operator()(Menu const & menu) const {
                return menu.name() == name_;
        }
 private:
@@ -84,10 +72,6 @@ private:
 } // namespace anon
 
 
-// This is the global menu definition
-MenuBackend menubackend;
-
-
 MenuItem::MenuItem(Kind kind)
        : kind_(kind), optional_(false)
 {}
@@ -132,25 +116,22 @@ docstring const MenuItem::shortcut() const
 }
 
 
-docstring const MenuItem::binding(bool forgui) const
+docstring const MenuItem::binding() const
 {
        if (kind_ != Command)
                return docstring();
 
        // Get the keys bound to this action, but keep only the
        // first one later
-       kb_keymap::Bindings bindings = theTopLevelKeymap().findbindings(func_);
+       KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(func_);
 
-       if (bindings.size()) {
-               return bindings.begin()->print(forgui);
-       } else {
-               LYXERR(Debug::KBMAP)
-                       << "No binding for "
-                       << lyxaction.getActionName(func_.action)
-                       << '(' << to_utf8(func_.argument()) << ')' << endl;
-               return docstring();
-       }
+       if (bindings.size())
+               return bindings.begin()->print(KeySequence::ForGui);
 
+       LYXERR(Debug::KBMAP, "No binding for "
+               << lyxaction.getActionName(func_.action)
+               << '(' << to_utf8(func_.argument()) << ')');
+       return docstring();
 }
 
 
@@ -218,6 +199,8 @@ Menu & Menu::read(Lexer & lex)
                md_documents,
                md_bookmarks,
                md_charstyles,
+               md_custom,
+               md_elements,
                md_endmenu,
                md_exportformats,
                md_importformats,
@@ -240,7 +223,9 @@ Menu & Menu::read(Lexer & lex)
                { "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 },
@@ -294,6 +279,14 @@ Menu & Menu::read(Lexer & lex)
                        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;
@@ -380,7 +373,7 @@ MenuItem const & Menu::operator[](size_type i) const
 bool Menu::hasFunc(FuncRequest const & func) const
 {
        return find_if(begin(), end(),
-                      bind(std::equal_to<FuncRequest>(),
+                      bind(equal_to<FuncRequest>(),
                            bind(&MenuItem::func, _1),
                            func)) != end();
 }
@@ -411,6 +404,27 @@ void Menu::checkShortcuts() const
 }
 
 
+bool Menu::searchFunc(FuncRequest & func, stack<docstring> & names) const
+{
+       const_iterator m = begin();
+       const_iterator m_end = end();
+       for (; m != m_end; ++m) {
+               if (m->kind() == MenuItem::Command && m->func() == func) {
+                       names.push(m->label());
+                       return true;
+               } else if (m->kind() == MenuItem::Submenu) {
+                       names.push(m->label());
+                       Menu submenu = theApp()->menuBackend().getMenu(m->submenuname());
+                       if (submenu.searchFunc(func, names))
+                               return true;
+                       else
+                               names.pop();
+               }
+       }
+       return false;
+}
+
+
 void MenuBackend::specialMenu(Menu const & menu)
 {
        specialmenu_ = menu;
@@ -456,23 +470,27 @@ void expandLastfiles(Menu & tomenu)
 
 void expandDocuments(Menu & tomenu)
 {
-       typedef vector<string> Strings;
-       Strings const names = theBufferList().getFileNames();
-
-       if (names.empty()) {
+       Buffer * first = theBufferList().first();
+       if (first) {
+               Buffer * b = first;
+               int ii = 1;
+               
+               // We cannot use a for loop as the buffer list cycles.
+               do {
+                       docstring label = b->fileName().displayName(20);
+                       if (!b->isClean())
+                               label = label + "*";
+                       if (ii < 10)
+                               label = convert<docstring>(ii) + ". " + label + '|' + convert<docstring>(ii);
+                       tomenu.add(MenuItem(MenuItem::Command, label,
+                               FuncRequest(LFUN_BUFFER_SWITCH, b->absFileName())));
+                       
+                       b = theBufferList().next(b);
+                       ++ii;
+               } while (b != first); 
+       } else {
                tomenu.add(MenuItem(MenuItem::Command, _("No Documents Open!"),
-                                   FuncRequest(LFUN_NOACTION)));
-               return;
-       }
-
-       int ii = 1;
-       Strings::const_iterator docit = names.begin();
-       Strings::const_iterator end = names.end();
-       for (; docit != end; ++docit, ++ii) {
-               docstring label = makeDisplayPath(*docit, 20);
-               if (ii < 10)
-                       label = convert<docstring>(ii) + ". " + label + char_type('|') + convert<docstring>(ii);
-               tomenu.add(MenuItem(MenuItem::Command, label, FuncRequest(LFUN_BUFFER_SWITCH, *docit)));
+                          FuncRequest(LFUN_NOACTION)));
        }
 }
 
@@ -486,7 +504,7 @@ void expandBookmarks(Menu & tomenu)
                        docstring const label = convert<docstring>(i) + ". "
                                + makeDisplayPath(bm.bookmark(i).filename.absFilename(), 20)
                                + char_type('|') + convert<docstring>(i);
-                       tomenu.add(MenuItem(MenuItem::Command, label, FuncRequest(LFUN_BOOKMARK_GOTO, 
+                       tomenu.add(MenuItem(MenuItem::Command, label, FuncRequest(LFUN_BOOKMARK_GOTO,
                                convert<docstring>(i))));
                }
        }
@@ -497,7 +515,7 @@ void expandFormats(MenuItem::Kind kind, Menu & tomenu, Buffer const * buf)
 {
        if (!buf && kind != MenuItem::ImportFormats) {
                tomenu.add(MenuItem(MenuItem::Command,
-                                   _("No Documents Open!"),
+                                   _("No Document Open!"),
                                    FuncRequest(LFUN_NOACTION)));
                return;
        }
@@ -508,19 +526,19 @@ void expandFormats(MenuItem::Kind kind, Menu & tomenu, Buffer const * buf)
 
        switch (kind) {
        case MenuItem::ImportFormats:
-               formats = Importer::GetImportableFormats();
+               formats = theConverters().importableFormats();
                action = LFUN_BUFFER_IMPORT;
                break;
        case MenuItem::ViewFormats:
-               formats = Exporter::getExportableFormats(*buf, true);
+               formats = buf->exportableFormats(true);
                action = LFUN_BUFFER_VIEW;
                break;
        case MenuItem::UpdateFormats:
-               formats = Exporter::getExportableFormats(*buf, true);
+               formats = buf->exportableFormats(true);
                action = LFUN_BUFFER_UPDATE;
                break;
        default:
-               formats = Exporter::getExportableFormats(*buf, false);
+               formats = buf->exportableFormats(false);
                action = LFUN_BUFFER_EXPORT;
        }
        sort(formats.begin(), formats.end(), compare_format());
@@ -531,6 +549,7 @@ void expandFormats(MenuItem::Kind kind, Menu & tomenu, Buffer const * buf)
                if ((*fit)->dummy())
                        continue;
                docstring label = from_utf8((*fit)->prettyname());
+               docstring const shortcut = from_utf8((*fit)->shortcut());
 
                switch (kind) {
                case MenuItem::ImportFormats:
@@ -552,8 +571,13 @@ void expandFormats(MenuItem::Kind kind, Menu & tomenu, Buffer const * buf)
                        BOOST_ASSERT(false);
                        break;
                }
-               if (!(*fit)->shortcut().empty())
-                       label += char_type('|') + from_utf8((*fit)->shortcut());
+               // 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.empty() && contains(label, shortcut))
+                       label += char_type('|') + shortcut;
 
                if (buf)
                        tomenu.addWithStatusCheck(MenuItem(MenuItem::Command, label,
@@ -569,13 +593,13 @@ void expandFloatListInsert(Menu & tomenu, Buffer const * buf)
 {
        if (!buf) {
                tomenu.add(MenuItem(MenuItem::Command,
-                                   _("No Documents Open!"),
+                                   _("No Document Open!"),
                                    FuncRequest(LFUN_NOACTION)));
                return;
        }
 
        FloatList const & floats =
-               buf->params().getLyXTextClass().floats();
+               buf->params().textClass().floats();
        FloatList::const_iterator cit = floats.begin();
        FloatList::const_iterator end = floats.end();
        for (; cit != end; ++cit) {
@@ -591,13 +615,13 @@ void expandFloatInsert(Menu & tomenu, Buffer const * buf)
 {
        if (!buf) {
                tomenu.add(MenuItem(MenuItem::Command,
-                                   _("No Documents Open!"),
+                                   _("No Document Open!"),
                                    FuncRequest(LFUN_NOACTION)));
                return;
        }
 
        FloatList const & floats =
-               buf->params().getLyXTextClass().floats();
+               buf->params().textClass().floats();
        FloatList::const_iterator cit = floats.begin();
        FloatList::const_iterator end = floats.end();
        for (; cit != end; ++cit) {
@@ -610,22 +634,23 @@ void expandFloatInsert(Menu & tomenu, Buffer const * buf)
 }
 
 
-void expandCharStyleInsert(Menu & tomenu, Buffer const * buf)
+void expandFlexInsert(Menu & tomenu, Buffer const * buf, string s)
 {
        if (!buf) {
                tomenu.add(MenuItem(MenuItem::Command,
-                                   _("No Documents Open!"),
+                                   _("No Document Open!"),
                                    FuncRequest(LFUN_NOACTION)));
                return;
        }
-       CharStyles & charstyles =
-               buf->params().getLyXTextClass().charstyles();
-       CharStyles::iterator cit = charstyles.begin();
-       CharStyles::iterator end = charstyles.end();
+       InsetLayouts const & insetLayouts =
+               buf->params().textClass().insetLayouts();
+       InsetLayouts::const_iterator cit = insetLayouts.begin();
+       InsetLayouts::const_iterator end = insetLayouts.end();
        for (; cit != end; ++cit) {
-               docstring const label = from_utf8(cit->name);
-               tomenu.addWithStatusCheck(MenuItem(MenuItem::Command, label,
-                                   FuncRequest(LFUN_CHARSTYLE_INSERT,
+               docstring const label = cit->first;
+               if (cit->second.lyxtype() == s)
+                       tomenu.addWithStatusCheck(MenuItem(MenuItem::Command, 
+                               label, FuncRequest(LFUN_FLEX_INSERT,
                                                label)));
        }
 }
@@ -643,7 +668,7 @@ void expandToc2(Menu & tomenu,
        // check whether depth is smaller than the smallest depth in toc.
        int min_depth = 1000;
        for (Toc::size_type i = from; i < to; ++i)
-               min_depth = std::min(min_depth, toc_list[i].depth());
+               min_depth = min(min_depth, toc_list[i].depth());
        if (min_depth > depth)
                depth = min_depth;
 
@@ -700,13 +725,17 @@ void expandToc(Menu & tomenu, Buffer const * buf)
 
        if (!buf) {
                tomenu.add(MenuItem(MenuItem::Command,
-                                   _("No Documents Open!"),
+                                   _("No Document Open!"),
                                    FuncRequest(LFUN_NOACTION)));
                return;
        }
 
+       Buffer* cbuf = const_cast<Buffer*>(buf);
+       cbuf->tocBackend().update();
+       cbuf->structureChanged();
+
        // Add an entry for the master doc if this is a child doc
-       Buffer const * const master = buf->getMasterBuffer();
+       Buffer const * const master = buf->masterBuffer();
        if (buf != master) {
                ParIterator const pit = par_iterator_begin(master->inset());
                string const arg = convert<string>(pit->id());
@@ -714,7 +743,7 @@ void expandToc(Menu & tomenu, Buffer const * buf)
                tomenu.add(MenuItem(MenuItem::Command, _("Master Document"), f));
        }
 
-       FloatList const & floatlist = buf->params().getLyXTextClass().floats();
+       FloatList const & floatlist = buf->params().textClass().floats();
        TocList const & toc_list = buf->tocBackend().tocs();
        TocList::const_iterator cit = toc_list.begin();
        TocList::const_iterator end = toc_list.end();
@@ -734,7 +763,28 @@ void expandToc(Menu & tomenu, Buffer const * buf)
                                           FuncRequest(ccit->action())));
                }
                string const & floatName = floatlist.getType(cit->first).listName();
-               MenuItem item(MenuItem::Submenu, _(floatName));
+               docstring label;
+               if (!floatName.empty())
+                       label = _(floatName);
+               // BUG3633: listings is not a proper float so its name
+               // is not shown in floatlist.
+               else if (cit->first == "equation")
+                       label = _("List of Equations");
+               else if (cit->first == "index")
+                       label = _("List of Indexes");
+               else if (cit->first == "listing")
+                       label = _("List of Listings");
+               else if (cit->first == "marginalnote")
+                       label = _("List of Marginal notes");
+               else if (cit->first == "note")
+                       label = _("List of Notes");
+               else if (cit->first == "footnote")
+                       label = _("List of Foot notes");
+               // this should not happen now, but if something else like
+               // listings is added later, this can avoid an empty menu name.
+               else
+                       label = _("Other floats");
+               MenuItem item(MenuItem::Submenu, label);
                item.submenu(menu.release());
                tomenu.add(item);
        }
@@ -778,29 +828,40 @@ void expandToolbars(Menu & tomenu)
 
        for (; cit != end; ++cit) {
                docstring label = _(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 
+               // 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 
+               // and
                //              review (auto)
                // in the case of auto.
                if (cit->flags & ToolbarInfo::AUTO)
                        label += _(" (auto)");
                tomenu.add(MenuItem(MenuItem::Command, label,
-                                   FuncRequest(LFUN_TOOLBAR_TOGGLE_STATE, cit->name)));
+                                   FuncRequest(LFUN_TOOLBAR_TOGGLE, cit->name + " allowauto")));
        }
 }
 
 
 void expandBranches(Menu & tomenu, Buffer const * buf)
 {
-       if (!buf)
+       if (!buf) {
+               tomenu.add(MenuItem(MenuItem::Command,
+                                   _("No Document Open!"),
+                                   FuncRequest(LFUN_NOACTION)));
                return;
+       }
 
-       BufferParams const & params = buf->getMasterBuffer()->params();
+       BufferParams const & params = buf->masterBuffer()->params();
+       if (params.branchlist().empty()) {
+               tomenu.add(MenuItem(MenuItem::Command,
+                                   _("No Branch in Document!"),
+                                   FuncRequest(LFUN_NOACTION)));
+               return;
+       }
 
        BranchList::const_iterator cit = params.branchlist().begin();
        BranchList::const_iterator end = params.branchlist().end();
@@ -848,7 +909,15 @@ void MenuBackend::expand(Menu const & frommenu, Menu & tomenu,
                        break;
 
                case MenuItem::CharStyles:
-                       expandCharStyleInsert(tomenu, buf);
+                       expandFlexInsert(tomenu, buf, "charstyle");
+                       break;
+
+               case MenuItem::Custom:
+                       expandFlexInsert(tomenu, buf, "custom");
+                       break;
+
+               case MenuItem::Elements:
+                       expandFlexInsert(tomenu, buf, "element");
                        break;
 
                case MenuItem::FloatListInsert: