]> git.lyx.org Git - lyx.git/blobdiff - src/ToolbarBackend.C
Fix bug 2474; partial fix for 1777. Added last_reference_ member to QRef class and...
[lyx.git] / src / ToolbarBackend.C
index 4ef1df0eedca6ca1afecfcf9d29a67bcabac372a..0c339c454737cd2df072b96fad348038aa86a5cc 100644 (file)
 
 #include "ToolbarBackend.h"
 #include "funcrequest.h"
-#include "LyXAction.h"
 #include "lyxlex.h"
 #include "debug.h"
 #include "gettext.h"
-
+#include "LyXAction.h"
 #include "support/lstrings.h"
-#include "support/filetools.h"
+
+#include <boost/bind.hpp>
+#include <algorithm>
 
 #include "frontends/controllers/ControlMath.h"
 
-using lyx::support::compare_ascii_no_case;
-using lyx::support::getVectorFromString;
-using lyx::support::LibFileSearch;
-using lyx::support::subst;
+namespace lyx {
+
+using support::compare_ascii_no_case;
+using support::getVectorFromString;
 
 using std::endl;
 using std::make_pair;
-
+using std::string;
 using std::vector;
+using std::find_if;
 
 
-ToolbarBackend toolbarbackend;
-
 namespace {
 
-enum tooltags {
-       TO_ADD = 1,
-       TO_ENDTOOLBAR,
-       TO_SEPARATOR,
-       TO_LAYOUTS,
-       TO_MINIBUFFER,
-       TO_LAST
+class ToolbarNamesEqual : public std::unary_function<ToolbarInfo, bool> {
+public:
+       ToolbarNamesEqual(string const & name)
+               : name_(name) {}
+       bool operator()(ToolbarInfo const & tbinfo) const
+       {
+               return tbinfo.name == name_;
+       }
+private:
+       string name_;
 };
 
-struct keyword_item toolTags[TO_LAST - 1] = {
-       { "end", TO_ENDTOOLBAR },
-       { "item", TO_ADD },
-       { "layouts", TO_LAYOUTS },
-       { "minibuffer", TO_MINIBUFFER },
-       { "separator", TO_SEPARATOR }
-};
+} // namespace anon
 
-} // end of anon namespace
 
+ToolbarBackend toolbarbackend;
 
-ToolbarBackend::ToolbarBackend()
+
+ToolbarItem::ToolbarItem(Type type, FuncRequest const & func, docstring const & label)
+       : type_(type), func_(func), label_(label)
+{
+}
+
+
+ToolbarItem::ToolbarItem(Type type, string const & name, docstring const & label)
+       : type_(type), name_(name), label_(label)
+{
+}
+
+
+ToolbarItem::~ToolbarItem()
+{}
+
+
+void ToolbarInfo::add(ToolbarItem const & item)
 {
+       items.push_back(item);
+       items.back().func_.origin = FuncRequest::TOOLBAR;
 }
 
 
-void ToolbarBackend::read(LyXLex & lex)
+ToolbarInfo & ToolbarInfo::read(LyXLex & lex)
 {
+       enum tooltags {
+               TO_COMMAND = 1,
+               TO_ENDTOOLBAR,
+               TO_SEPARATOR,
+               TO_LAYOUTS,
+               TO_MINIBUFFER,
+               TO_TABLEINSERT,
+               TO_POPUPMENU,
+               TO_ICONPALETTE,
+               TO_LAST
+       };
+       
+       struct keyword_item toolTags[TO_LAST - 1] = {
+               { "end", TO_ENDTOOLBAR },
+               { "iconpalette", TO_ICONPALETTE },
+               { "item", TO_COMMAND },
+               { "layouts", TO_LAYOUTS },
+               { "minibuffer", TO_MINIBUFFER },
+               { "popupmenu", TO_POPUPMENU },
+               { "separator", TO_SEPARATOR },
+               { "tableinsert", TO_TABLEINSERT }
+       };
+
        //consistency check
        if (compare_ascii_no_case(lex.getString(), "toolbar")) {
-               lyxerr << "ToolbarBackend::read: ERROR wrong token:`"
+               lyxerr << "ToolbarInfo::read: ERROR wrong token:`"
                       << lex.getString() << '\'' << endl;
        }
 
        lex.next(true);
+       name = lex.getString();
 
-       Toolbar tb;
-       tb.name = lex.getString();
+       lex.next(true);
+       gui_name = lex.getString();
+
+       // FIXME what to do here?
+       if (!lex) {
+               lyxerr << "ToolbarInfo::read: Malformed toolbar "
+                       "description " <<  lex.getString() << endl;
+               return *this;
+       }
 
        bool quit = false;
 
@@ -85,51 +132,134 @@ void ToolbarBackend::read(LyXLex & lex)
 
        while (lex.isOK() && !quit) {
                switch (lex.lex()) {
-               case TO_ADD:
+               case TO_COMMAND:
                        if (lex.next(true)) {
-                               string const tooltip = _(lex.getString());
+                               docstring const tooltip = translateIfPossible(lex.getDocString());
                                lex.next(true);
-                               string const func = lex.getString();
-                               lyxerr[Debug::PARSER]
-                                       << "ToolbarBackend::read TO_ADD func: `"
-                                       << func << '\'' << endl;
-                               add(tb, func, tooltip);
+                               string const func_arg = lex.getString();
+                               LYXERR(Debug::PARSER)
+                                       << "ToolbarInfo::read TO_COMMAND func: `"
+                                       << func_arg << '\'' << endl;
+
+                               FuncRequest func =
+                                       lyxaction.lookupFunc(func_arg);
+                               add(ToolbarItem(ToolbarItem::COMMAND, func, tooltip));
                        }
                        break;
 
                case TO_MINIBUFFER:
-                       add(tb, MINIBUFFER);
+                       add(ToolbarItem(ToolbarItem::MINIBUFFER,
+                               FuncRequest(kb_action(ToolbarItem::MINIBUFFER))));
                        break;
 
                case TO_SEPARATOR:
-                       add(tb, SEPARATOR);
+                       add(ToolbarItem(ToolbarItem::SEPARATOR,
+                               FuncRequest(kb_action(ToolbarItem::SEPARATOR))));
                        break;
 
+               case TO_POPUPMENU:
+                       if (lex.next(true)) {
+                               string const name = lex.getString();
+                               lex.next(true);
+                               docstring const label = lex.getDocString();
+                               add(ToolbarItem(ToolbarItem::POPUPMENU, name, label));
+                       }
+                       break;
+                       
+               case TO_ICONPALETTE:
+                       if (lex.next(true)) {
+                               string const name = lex.getString();
+                               lex.next(true);
+                               docstring const label = lex.getDocString();
+                               add(ToolbarItem(ToolbarItem::ICONPALETTE, name, label));
+                       }
+                       break;
+                       
                case TO_LAYOUTS:
-                       add(tb, LAYOUTS);
+                       add(ToolbarItem(ToolbarItem::LAYOUTS,
+                               FuncRequest(kb_action(ToolbarItem::LAYOUTS))));
                        break;
-
+                       
+               case TO_TABLEINSERT:
+                       add(ToolbarItem(ToolbarItem::TABLEINSERT,
+                               FuncRequest(kb_action(ToolbarItem::TABLEINSERT))));
+                       break;
+                       
                case TO_ENDTOOLBAR:
                        quit = true;
                        break;
+
                default:
-                       lex.printError("ToolbarBackend::read: "
+                       lex.printError("ToolbarInfo::read: "
                                       "Unknown toolbar tag: `$$Token'");
                        break;
                }
        }
 
-       toolbars.push_back(tb);
-
        lex.popTable();
+       return *this;
+}
+
+
+
+
+ToolbarBackend::ToolbarBackend()
+{
 }
 
 
 void ToolbarBackend::readToolbars(LyXLex & lex)
+{
+       enum tooltags {
+               TO_TOOLBAR = 1,
+               TO_ENDTOOLBARSET,
+               TO_LAST
+       };
+       
+       struct keyword_item toolTags[TO_LAST - 1] = {
+               { "end", TO_ENDTOOLBARSET },
+               { "toolbar", TO_TOOLBAR }
+       };
+
+       //consistency check
+       if (compare_ascii_no_case(lex.getString(), "toolbarset")) {
+               lyxerr << "ToolbarBackend::readToolbars: ERROR wrong token:`"
+                      << lex.getString() << '\'' << endl;
+       }
+
+       lex.pushTable(toolTags, TO_LAST - 1);
+
+       if (lyxerr.debugging(Debug::PARSER))
+               lex.printTable(lyxerr);
+
+       bool quit = false;
+       while (lex.isOK() && !quit) {
+               switch (lex.lex()) {
+               case TO_TOOLBAR: {
+                       ToolbarInfo tbinfo;
+                       tbinfo.read(lex);
+                       toolbars.push_back(tbinfo);
+                       break;
+                       }
+               case TO_ENDTOOLBARSET:
+                       quit = true;
+                       break;
+               default:
+                       lex.printError("ToolbarBackend::readToolbars: "
+                                      "Unknown toolbar tag: `$$Token'");
+                       break;
+               }
+       }
+
+       lex.popTable();
+}
+
+
+void ToolbarBackend::readToolbarSettings(LyXLex & lex)
 {
        //consistency check
        if (compare_ascii_no_case(lex.getString(), "toolbars")) {
-               lyxerr << "ToolbarBackend::read: ERROR wrong token:`"
+               lyxerr << "ToolbarBackend::readToolbarSettings: ERROR wrong token:`"
                       << lex.getString() << '\'' << endl;
        }
 
@@ -155,7 +285,7 @@ void ToolbarBackend::readToolbars(LyXLex & lex)
                        return;
                }
 
-               tcit->flags = static_cast<Flags>(0);
+               tcit->flags = static_cast<ToolbarInfo::Flags>(0);
                string flagstr = lex.getString();
                lex.next(true);
                vector<string> flags = getVectorFromString(flagstr);
@@ -166,26 +296,28 @@ void ToolbarBackend::readToolbars(LyXLex & lex)
                for (; cit != end; ++cit) {
                        int flag = 0;
                        if (!compare_ascii_no_case(*cit, "off"))
-                               flag = OFF;
+                               flag = ToolbarInfo::OFF;
                        else if (!compare_ascii_no_case(*cit, "on"))
-                               flag = ON;
+                               flag = ToolbarInfo::ON;
                        else if (!compare_ascii_no_case(*cit, "math"))
-                               flag = MATH;
+                               flag = ToolbarInfo::MATH;
                        else if (!compare_ascii_no_case(*cit, "table"))
-                               flag = TABLE;
+                               flag = ToolbarInfo::TABLE;
+                       else if (!compare_ascii_no_case(*cit, "review"))
+                               flag = ToolbarInfo::REVIEW;
                        else if (!compare_ascii_no_case(*cit, "top"))
-                               flag = TOP;
+                               flag = ToolbarInfo::TOP;
                        else if (!compare_ascii_no_case(*cit, "bottom"))
-                               flag = BOTTOM;
+                               flag = ToolbarInfo::BOTTOM;
                        else if (!compare_ascii_no_case(*cit, "left"))
-                               flag = LEFT;
+                               flag = ToolbarInfo::LEFT;
                        else if (!compare_ascii_no_case(*cit, "right"))
-                               flag = RIGHT;
+                               flag = ToolbarInfo::RIGHT;
                        else {
-                               lyxerr << "ToolbarBackend::read: unrecognised token:`"
+                               lyxerr << "ToolbarBackend::readToolbarSettings: unrecognised token:`"
                                       << *cit << '\'' << endl;
                        }
-                       tcit->flags = static_cast<Flags>(tcit->flags | flag);
+                       tcit->flags = static_cast<ToolbarInfo::Flags>(tcit->flags | flag);
                }
 
                usedtoolbars.push_back(*tcit);
@@ -193,58 +325,24 @@ void ToolbarBackend::readToolbars(LyXLex & lex)
 }
 
 
-void ToolbarBackend::add(Toolbar & tb, int action, string const & tooltip)
+ToolbarInfo const & ToolbarBackend::getToolbar(string const & name) const
 {
-       tb.items.push_back(make_pair(action, tooltip));
+       Toolbars::const_iterator cit = find_if(toolbars.begin(), toolbars.end(), ToolbarNamesEqual(name));
+       if (cit == toolbars.end())
+               lyxerr << "No toolbar named " << name << endl;
+       BOOST_ASSERT(cit != toolbars.end());
+       return (*cit);
 }
 
 
-void ToolbarBackend::add(Toolbar & tb, string const & func, string const & tooltip)
+ToolbarInfo & ToolbarBackend::getToolbar(string const & name)
 {
-       int const tf = lyxaction.LookupFunc(func);
-
-       if (tf == -1) {
-               lyxerr << "ToolbarBackend::add: no LyX command called `"
-                      << func << "' exists!" << endl;
-       } else {
-               add(tb, tf, tooltip);
-       }
+       Toolbars::iterator it = find_if(toolbars.begin(), toolbars.end(), ToolbarNamesEqual(name));
+       if (it == toolbars.end())
+               lyxerr << "No toolbar named " << name << endl;
+       BOOST_ASSERT(it != toolbars.end());
+       return (*it);
 }
 
 
-string const ToolbarBackend::getIcon(int action)
-{
-       string fullname;
-       FuncRequest f = lyxaction.retrieveActionArg(action);
-
-       if (f.action == LFUN_INSERT_MATH) {
-               if (!f.argument.empty())
-                       fullname = find_xpm(f.argument.substr(1));
-       } else if (f.action == LFUN_MATH_DELIM) {
-               fullname = find_xpm(f.argument);
-       } else {
-               string const name = lyxaction.getActionName(f.action);
-               string xpm_name(name);
-
-               if (!f.argument.empty())
-                       xpm_name = subst(name + ' ' + f.argument, ' ', '_');
-
-               fullname = LibFileSearch("images", xpm_name, "xpm");
-
-               if (fullname.empty()) {
-                       // try without the argument
-                       fullname = LibFileSearch("images", name, "xpm");
-               }
-       }
-
-       if (!fullname.empty()) {
-               lyxerr[Debug::GUI] << "Full icon name is `"
-                                  << fullname << '\'' << endl;
-               return fullname;
-       }
-
-       lyxerr[Debug::GUI] << "Cannot find icon for command \""
-                          << lyxaction.getActionName(f.action)
-                          << ' ' << f.argument << '"' << endl;
-       return LibFileSearch("images", "unknown", "xpm");
-}
+} // namespace lyx