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