/** * \file ToolbarBackend.C * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Jean-Marc Lasgouttes * \author John Levon * * Full author contact details are available in file CREDITS. */ #include #include "ToolbarBackend.h" #include "funcrequest.h" #include "lyxlex.h" #include "debug.h" #include "gettext.h" #include "LyXAction.h" #include "support/lstrings.h" #include #include #include "frontends/controllers/ControlMath.h" 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; namespace { class ToolbarNamesEqual : public std::unary_function { public: ToolbarNamesEqual(string const & name) : name_(name) {} bool operator()(ToolbarInfo const & tbinfo) const { return tbinfo.name == name_; } private: string name_; }; } // namespace anon 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; } 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 << "ToolbarInfo::read: ERROR wrong token:`" << lex.getString() << '\'' << endl; } lex.next(true); 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; lex.pushTable(toolTags, TO_LAST - 1); if (lyxerr.debugging(Debug::PARSER)) lex.printTable(lyxerr); while (lex.isOK() && !quit) { switch (lex.lex()) { case TO_COMMAND: if (lex.next(true)) { docstring const tooltip = translateIfPossible(lex.getDocString()); lex.next(true); 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(ToolbarItem(ToolbarItem::MINIBUFFER, FuncRequest(kb_action(ToolbarItem::MINIBUFFER)))); break; case TO_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(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("ToolbarInfo::read: " "Unknown toolbar tag: `$$Token'"); break; } } 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::readToolbarSettings: ERROR wrong token:`" << lex.getString() << '\'' << endl; } lex.next(true); while (lex.isOK()) { string name = lex.getString(); lex.next(true); if (!compare_ascii_no_case(name, "end")) return; Toolbars::iterator tcit = toolbars.begin(); Toolbars::iterator tend = toolbars.end(); for (; tcit != tend; ++tcit) { if (tcit->name == name) break; } if (tcit == tend) { lyxerr << "ToolbarBackend: undefined toolbar " << name << endl; return; } tcit->flags = static_cast(0); string flagstr = lex.getString(); lex.next(true); vector flags = getVectorFromString(flagstr); vector::const_iterator cit = flags.begin(); vector::const_iterator end = flags.end(); for (; cit != end; ++cit) { int flag = 0; if (!compare_ascii_no_case(*cit, "off")) flag = ToolbarInfo::OFF; else if (!compare_ascii_no_case(*cit, "on")) flag = ToolbarInfo::ON; else if (!compare_ascii_no_case(*cit, "math")) flag = ToolbarInfo::MATH; else if (!compare_ascii_no_case(*cit, "table")) flag = ToolbarInfo::TABLE; else if (!compare_ascii_no_case(*cit, "review")) flag = ToolbarInfo::REVIEW; else if (!compare_ascii_no_case(*cit, "top")) flag = ToolbarInfo::TOP; else if (!compare_ascii_no_case(*cit, "bottom")) flag = ToolbarInfo::BOTTOM; else if (!compare_ascii_no_case(*cit, "left")) flag = ToolbarInfo::LEFT; else if (!compare_ascii_no_case(*cit, "right")) flag = ToolbarInfo::RIGHT; else { lyxerr << "ToolbarBackend::readToolbarSettings: unrecognised token:`" << *cit << '\'' << endl; } tcit->flags = static_cast(tcit->flags | flag); } usedtoolbars.push_back(*tcit); } } ToolbarInfo const & ToolbarBackend::getToolbar(string const & name) const { 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); } ToolbarInfo & ToolbarBackend::getToolbar(string const & name) { 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); } } // namespace lyx