]> git.lyx.org Git - lyx.git/blob - src/ToolbarBackend.cpp
adjust
[lyx.git] / src / ToolbarBackend.cpp
1 /**
2  * \file ToolbarBackend.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jean-Marc Lasgouttes
7  * \author John Levon
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "ToolbarBackend.h"
15 #include "FuncRequest.h"
16 #include "Lexer.h"
17 #include "debug.h"
18 #include "gettext.h"
19 #include "LyXAction.h"
20 #include "support/lstrings.h"
21
22 #include <boost/bind.hpp>
23 #include <algorithm>
24
25 namespace lyx {
26
27 using support::compare_ascii_no_case;
28 using support::getVectorFromString;
29
30 using std::endl;
31 using std::make_pair;
32 using std::string;
33 using std::vector;
34 using std::find_if;
35
36
37 namespace {
38
39 class ToolbarNamesEqual : public std::unary_function<ToolbarInfo, bool> {
40 public:
41         ToolbarNamesEqual(string const & name)
42                 : name_(name) {}
43         bool operator()(ToolbarInfo const & tbinfo) const
44         {
45                 return tbinfo.name == name_;
46         }
47 private:
48         string name_;
49 };
50
51 } // namespace anon
52
53
54 ToolbarBackend toolbarbackend;
55
56
57 ToolbarItem::ToolbarItem(Type type, FuncRequest const & func, docstring const & label)
58         : type_(type), func_(func), label_(label)
59 {
60 }
61
62
63 ToolbarItem::ToolbarItem(Type type, string const & name, docstring const & label)
64         : type_(type), label_(label), name_(name)
65 {
66 }
67
68
69 ToolbarItem::~ToolbarItem()
70 {}
71
72
73 void ToolbarInfo::add(ToolbarItem const & item)
74 {
75         items.push_back(item);
76         items.back().func_.origin = FuncRequest::TOOLBAR;
77 }
78
79
80 ToolbarInfo & ToolbarInfo::read(Lexer & lex)
81 {
82         enum tooltags {
83                 TO_COMMAND = 1,
84                 TO_ENDTOOLBAR,
85                 TO_SEPARATOR,
86                 TO_LAYOUTS,
87                 TO_MINIBUFFER,
88                 TO_TABLEINSERT,
89                 TO_POPUPMENU,
90                 TO_ICONPALETTE,
91                 TO_LAST
92         };
93
94         struct keyword_item toolTags[TO_LAST - 1] = {
95                 { "end", TO_ENDTOOLBAR },
96                 { "iconpalette", TO_ICONPALETTE },
97                 { "item", TO_COMMAND },
98                 { "layouts", TO_LAYOUTS },
99                 { "minibuffer", TO_MINIBUFFER },
100                 { "popupmenu", TO_POPUPMENU },
101                 { "separator", TO_SEPARATOR },
102                 { "tableinsert", TO_TABLEINSERT }
103         };
104
105         //consistency check
106         if (compare_ascii_no_case(lex.getString(), "toolbar")) {
107                 lyxerr << "ToolbarInfo::read: ERROR wrong token:`"
108                        << lex.getString() << '\'' << endl;
109         }
110
111         lex.next(true);
112         name = lex.getString();
113
114         lex.next(true);
115         gui_name = lex.getString();
116
117         // FIXME what to do here?
118         if (!lex) {
119                 lyxerr << "ToolbarInfo::read: Malformed toolbar "
120                         "description " <<  lex.getString() << endl;
121                 return *this;
122         }
123
124         bool quit = false;
125
126         lex.pushTable(toolTags, TO_LAST - 1);
127
128         if (lyxerr.debugging(Debug::PARSER))
129                 lex.printTable(lyxerr);
130
131         while (lex.isOK() && !quit) {
132                 switch (lex.lex()) {
133                 case TO_COMMAND:
134                         if (lex.next(true)) {
135                                 docstring const tooltip = translateIfPossible(lex.getDocString());
136                                 lex.next(true);
137                                 string const func_arg = lex.getString();
138                                 LYXERR(Debug::PARSER)
139                                         << "ToolbarInfo::read TO_COMMAND func: `"
140                                         << func_arg << '\'' << endl;
141
142                                 FuncRequest func =
143                                         lyxaction.lookupFunc(func_arg);
144                                 add(ToolbarItem(ToolbarItem::COMMAND, func, tooltip));
145                         }
146                         break;
147
148                 case TO_MINIBUFFER:
149                         add(ToolbarItem(ToolbarItem::MINIBUFFER,
150                                 FuncRequest(kb_action(ToolbarItem::MINIBUFFER))));
151                         break;
152
153                 case TO_SEPARATOR:
154                         add(ToolbarItem(ToolbarItem::SEPARATOR,
155                                 FuncRequest(kb_action(ToolbarItem::SEPARATOR))));
156                         break;
157
158                 case TO_POPUPMENU:
159                         if (lex.next(true)) {
160                                 string const name = lex.getString();
161                                 lex.next(true);
162                                 docstring const label = lex.getDocString();
163                                 add(ToolbarItem(ToolbarItem::POPUPMENU, name, label));
164                         }
165                         break;
166
167                 case TO_ICONPALETTE:
168                         if (lex.next(true)) {
169                                 string const name = lex.getString();
170                                 lex.next(true);
171                                 docstring const label = lex.getDocString();
172                                 add(ToolbarItem(ToolbarItem::ICONPALETTE, name, label));
173                         }
174                         break;
175
176                 case TO_LAYOUTS:
177                         add(ToolbarItem(ToolbarItem::LAYOUTS,
178                                 FuncRequest(kb_action(ToolbarItem::LAYOUTS))));
179                         break;
180
181                 case TO_TABLEINSERT:
182                         if (lex.next(true)) {
183                                 docstring const tooltip = lex.getDocString();
184                                 add(ToolbarItem(ToolbarItem::TABLEINSERT,
185                                         FuncRequest(kb_action(ToolbarItem::TABLEINSERT)), tooltip));
186                         }
187                         break;
188
189                 case TO_ENDTOOLBAR:
190                         quit = true;
191                         break;
192
193                 default:
194                         lex.printError("ToolbarInfo::read: "
195                                        "Unknown toolbar tag: `$$Token'");
196                         break;
197                 }
198         }
199
200         lex.popTable();
201         return *this;
202 }
203
204
205
206
207 ToolbarBackend::ToolbarBackend()
208 {
209 }
210
211
212 void ToolbarBackend::readToolbars(Lexer & lex)
213 {
214         enum tooltags {
215                 TO_TOOLBAR = 1,
216                 TO_ENDTOOLBARSET,
217                 TO_LAST
218         };
219
220         struct keyword_item toolTags[TO_LAST - 1] = {
221                 { "end", TO_ENDTOOLBARSET },
222                 { "toolbar", TO_TOOLBAR }
223         };
224
225         //consistency check
226         if (compare_ascii_no_case(lex.getString(), "toolbarset")) {
227                 lyxerr << "ToolbarBackend::readToolbars: ERROR wrong token:`"
228                        << lex.getString() << '\'' << endl;
229         }
230
231         lex.pushTable(toolTags, TO_LAST - 1);
232
233         if (lyxerr.debugging(Debug::PARSER))
234                 lex.printTable(lyxerr);
235
236         bool quit = false;
237         while (lex.isOK() && !quit) {
238                 switch (lex.lex()) {
239                 case TO_TOOLBAR: {
240                         ToolbarInfo tbinfo;
241                         tbinfo.read(lex);
242                         toolbars.push_back(tbinfo);
243                         break;
244                         }
245                 case TO_ENDTOOLBARSET:
246                         quit = true;
247                         break;
248                 default:
249                         lex.printError("ToolbarBackend::readToolbars: "
250                                        "Unknown toolbar tag: `$$Token'");
251                         break;
252                 }
253         }
254
255         lex.popTable();
256 }
257
258
259 void ToolbarBackend::readToolbarSettings(Lexer & lex)
260 {
261         //consistency check
262         if (compare_ascii_no_case(lex.getString(), "toolbars")) {
263                 lyxerr << "ToolbarBackend::readToolbarSettings: ERROR wrong token:`"
264                        << lex.getString() << '\'' << endl;
265         }
266
267         lex.next(true);
268
269         while (lex.isOK()) {
270                 string name = lex.getString();
271                 lex.next(true);
272
273                 if (!compare_ascii_no_case(name, "end"))
274                         return;
275
276                 Toolbars::iterator tcit = toolbars.begin();
277                 Toolbars::iterator tend = toolbars.end();
278                 for (; tcit != tend; ++tcit) {
279                         if (tcit->name == name)
280                                 break;
281                 }
282
283                 if (tcit == tend) {
284                         lyxerr << "ToolbarBackend: undefined toolbar "
285                                 << name << endl;
286                         return;
287                 }
288
289                 tcit->flags = static_cast<ToolbarInfo::Flags>(0);
290                 string flagstr = lex.getString();
291                 lex.next(true);
292                 vector<string> flags = getVectorFromString(flagstr);
293
294                 vector<string>::const_iterator cit = flags.begin();
295                 vector<string>::const_iterator end = flags.end();
296
297                 for (; cit != end; ++cit) {
298                         int flag = 0;
299                         if (!compare_ascii_no_case(*cit, "off"))
300                                 flag = ToolbarInfo::OFF;
301                         else if (!compare_ascii_no_case(*cit, "on"))
302                                 flag = ToolbarInfo::ON;
303                         else if (!compare_ascii_no_case(*cit, "math"))
304                                 flag = ToolbarInfo::MATH;
305                         else if (!compare_ascii_no_case(*cit, "table"))
306                                 flag = ToolbarInfo::TABLE;
307                         else if (!compare_ascii_no_case(*cit, "review"))
308                                 flag = ToolbarInfo::REVIEW;
309                         else if (!compare_ascii_no_case(*cit, "top"))
310                                 flag = ToolbarInfo::TOP;
311                         else if (!compare_ascii_no_case(*cit, "bottom"))
312                                 flag = ToolbarInfo::BOTTOM;
313                         else if (!compare_ascii_no_case(*cit, "left"))
314                                 flag = ToolbarInfo::LEFT;
315                         else if (!compare_ascii_no_case(*cit, "right"))
316                                 flag = ToolbarInfo::RIGHT;
317                         else {
318                                 lyxerr << "ToolbarBackend::readToolbarSettings: unrecognised token:`"
319                                        << *cit << '\'' << endl;
320                         }
321                         tcit->flags = static_cast<ToolbarInfo::Flags>(tcit->flags | flag);
322                 }
323
324                 usedtoolbars.push_back(*tcit);
325         }
326 }
327
328
329 ToolbarInfo const * ToolbarBackend::getDefinedToolbarInfo(string const & name) const
330 {
331         Toolbars::const_iterator it = find_if(toolbars.begin(), toolbars.end(), ToolbarNamesEqual(name));
332         if (it == toolbars.end())
333                 return 0;
334         return &(*it);
335 }
336
337
338 ToolbarInfo * ToolbarBackend::getUsedToolbarInfo(string const &name)
339 {
340         Toolbars::iterator it = find_if(usedtoolbars.begin(), usedtoolbars.end(), ToolbarNamesEqual(name));
341         if (it == usedtoolbars.end())
342                 return 0;
343         return &(*it);
344 }
345
346 } // namespace lyx