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