]> git.lyx.org Git - lyx.git/blob - src/frontends/qt/Toolbars.cpp
Make code a bit easier to read
[lyx.git] / src / frontends / qt / 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 "Converter.h"
16 #include "Format.h"
17 #include "FuncRequest.h"
18 #include "Lexer.h"
19 #include "LyXAction.h"
20 #include "qt_helpers.h"
21
22 #include "support/debug.h"
23 #include "support/gettext.h"
24 #include "support/lstrings.h"
25
26 #include <algorithm>
27
28 using namespace std;
29 using namespace lyx::support;
30
31 namespace lyx {
32 namespace frontend {
33
34
35 /////////////////////////////////////////////////////////////////////////
36 //
37 // ToolbarItem
38 //
39 /////////////////////////////////////////////////////////////////////////
40
41 ToolbarItem::ToolbarItem(Type t, FuncRequest const & f,
42                          docstring const & l)
43         : type(t), func(make_shared<FuncRequest>(f)), label(l)
44 {
45 }
46
47
48 ToolbarItem::ToolbarItem(Type type, string const & name,
49                          docstring const & label)
50         : type(type), func(make_shared<FuncRequest>()), label(label), name(name)
51 {
52 }
53
54
55 void ToolbarInfo::add(ToolbarItem const & item)
56 {
57         items.push_back(item);
58         items.back().func->setOrigin(FuncRequest::TOOLBAR);
59 }
60
61
62 ToolbarInfo & ToolbarInfo::read(Lexer & lex)
63 {
64         enum {
65                 TO_COMMAND = 1,
66                 TO_BIDICOMMAND,
67                 TO_ENDTOOLBAR,
68                 TO_SEPARATOR,
69                 TO_LAYOUTS,
70                 TO_MINIBUFFER,
71                 TO_TABLEINSERT,
72                 TO_POPUPMENU,
73                 TO_STICKYPOPUPMENU,
74                 TO_ICONPALETTE,
75                 TO_EXPORTFORMATS,
76                 TO_IMPORTFORMATS,
77                 TO_UPDATEFORMATS,
78                 TO_VIEWFORMATS,
79                 TO_DYNAMICMENU
80         };
81
82         struct LexerKeyword toolTags[] = {
83                 { "bidiitem", TO_BIDICOMMAND},
84                 { "dynamicmenu", TO_DYNAMICMENU},
85                 { "end", TO_ENDTOOLBAR },
86                 { "exportformats", TO_EXPORTFORMATS },
87                 { "iconpalette", TO_ICONPALETTE },
88                 { "importformats", TO_IMPORTFORMATS },
89                 { "item", TO_COMMAND },
90                 { "layouts", TO_LAYOUTS },
91                 { "minibuffer", TO_MINIBUFFER },
92                 { "popupmenu", TO_POPUPMENU },
93                 { "separator", TO_SEPARATOR },
94                 { "stickypopupmenu", TO_STICKYPOPUPMENU },
95                 { "tableinsert", TO_TABLEINSERT },
96                 { "updateformats", TO_UPDATEFORMATS },
97                 { "viewformats", TO_VIEWFORMATS },
98         };
99
100         //consistency check
101         if (compare_ascii_no_case(lex.getString(), "toolbar")) {
102                 LYXERR0("ToolbarInfo::read: ERROR wrong token:`"
103                        << lex.getString() << '\'');
104         }
105
106         lex.next(true);
107         name = lex.getString();
108
109         lex.next(true);
110         gui_name = _(lex.getString());
111
112         // FIXME what to do here?
113         if (!lex) {
114                 LYXERR0("ToolbarInfo::read: Malformed toolbar "
115                         "description " <<  lex.getString());
116                 return *this;
117         }
118
119         bool quit = false;
120
121         lex.pushTable(toolTags);
122
123         if (lyxerr.debugging(Debug::PARSER))
124                 lex.printTable(lyxerr);
125
126         while (lex.isOK() && !quit) {
127                 int const code = lex.lex();
128                 switch (code) {
129                 case TO_COMMAND:
130                         if (lex.next(true)) {
131                                 docstring const tooltip = translateIfPossible(lex.getDocString());
132                                 lex.next(true);
133                                 string const func_arg = lex.getString();
134                                 LYXERR(Debug::PARSER, "ToolbarInfo::read TO_COMMAND func: `"
135                                         << func_arg << '\'');
136
137                                 FuncRequest func =
138                                         lyxaction.lookupFunc(func_arg);
139                                 add(ToolbarItem(ToolbarItem::COMMAND, func, tooltip));
140                         }
141                         break;
142
143                 case TO_BIDICOMMAND:
144                         if (lex.next(true)) {
145                                 docstring const tooltip = translateIfPossible(lex.getDocString());
146                                 lex.next(true);
147                                 string const func_arg = lex.getString();
148                                 LYXERR(Debug::PARSER, "ToolbarInfo::read TO_BIDICOMMAND func: `"
149                                         << func_arg << '\'');
150
151                                 FuncRequest func =
152                                         lyxaction.lookupFunc(func_arg);
153                                 add(ToolbarItem(ToolbarItem::BIDICOMMAND, func, tooltip));
154                         }
155                         break;
156
157                 case TO_MINIBUFFER:
158                         add(ToolbarItem(ToolbarItem::MINIBUFFER,
159                                 FuncRequest(FuncCode(ToolbarItem::MINIBUFFER))));
160                         break;
161
162                 case TO_SEPARATOR:
163                         add(ToolbarItem(ToolbarItem::SEPARATOR,
164                                 FuncRequest(FuncCode(ToolbarItem::SEPARATOR))));
165                         break;
166
167                 case TO_POPUPMENU:
168                         if (lex.next(true)) {
169                                 string const pname = lex.getString();
170                                 lex.next(true);
171                                 docstring const label = lex.getDocString();
172                                 add(ToolbarItem(ToolbarItem::POPUPMENU, pname, label));
173                         }
174                         break;
175
176                 case TO_DYNAMICMENU: {
177                         if (lex.next(true)) {
178                                 string const name = lex.getString();
179                                 lex.next(true);
180                                 docstring const label = lex.getDocString();
181                                 add(ToolbarItem(ToolbarItem::DYNAMICMENU, name, label));
182                         }
183                         break;
184                 }
185
186                 case TO_STICKYPOPUPMENU:
187                         if (lex.next(true)) {
188                                 string const pname = lex.getString();
189                                 lex.next(true);
190                                 docstring const label = lex.getDocString();
191                                 add(ToolbarItem(ToolbarItem::STICKYPOPUPMENU, pname, label));
192                         }
193                         break;
194
195                 case TO_ICONPALETTE:
196                         if (lex.next(true)) {
197                                 string const pname = lex.getString();
198                                 lex.next(true);
199                                 docstring const label = lex.getDocString();
200                                 add(ToolbarItem(ToolbarItem::ICONPALETTE, pname, label));
201                         }
202                         break;
203
204                 case TO_LAYOUTS:
205                         add(ToolbarItem(ToolbarItem::LAYOUTS,
206                                 FuncRequest(FuncCode(ToolbarItem::LAYOUTS))));
207                         break;
208
209                 case TO_TABLEINSERT:
210                         if (lex.next(true)) {
211                                 docstring const tooltip = lex.getDocString();
212                                 add(ToolbarItem(ToolbarItem::TABLEINSERT,
213                                         FuncRequest(FuncCode(ToolbarItem::TABLEINSERT)), tooltip));
214                         }
215                         break;
216
217                 case TO_ENDTOOLBAR:
218                         quit = true;
219                         break;
220
221                 case TO_EXPORTFORMATS:
222                 case TO_IMPORTFORMATS:
223                 case TO_UPDATEFORMATS:
224                 case TO_VIEWFORMATS: {
225                         FormatList formats;
226                         if (code == TO_IMPORTFORMATS)
227                                 formats = theConverters().importableFormats();
228                         else if (code == TO_EXPORTFORMATS)
229                                 formats = theConverters().exportableFormats(false);
230                         else
231                                 formats = theConverters().exportableFormats(true);
232                         sort(formats.begin(), formats.end());
233                         for (Format const * f : formats) {
234                                 if (f->dummy())
235                                         continue;
236                                 if (code != TO_IMPORTFORMATS &&
237                                     !f->documentFormat())
238                                         continue;
239
240                                 docstring const prettyname = f->prettyname();
241                                 docstring tooltip;
242                                 FuncCode lfun = LFUN_NOACTION;
243                                 switch (code) {
244                                 case TO_EXPORTFORMATS:
245                                         lfun = LFUN_BUFFER_EXPORT;
246                                         tooltip = _("Export %1$s");
247                                         break;
248                                 case TO_IMPORTFORMATS:
249                                         lfun = LFUN_BUFFER_IMPORT;
250                                         tooltip = _("Import %1$s");
251                                         break;
252                                 case TO_UPDATEFORMATS:
253                                         lfun = LFUN_BUFFER_UPDATE;
254                                         tooltip = _("Update %1$s");
255                                         break;
256                                 case TO_VIEWFORMATS:
257                                         lfun = LFUN_BUFFER_VIEW;
258                                         tooltip = _("View %1$s");
259                                         break;
260                                 }
261                                 FuncRequest func(lfun, f->name(),
262                                                 FuncRequest::TOOLBAR);
263                                 add(ToolbarItem(ToolbarItem::COMMAND, func,
264                                                 bformat(tooltip, translateIfPossible(prettyname))));
265                         }
266                         break;
267                 }
268
269                 default:
270                         lex.printError("ToolbarInfo::read: "
271                                        "Unknown toolbar tag: `$$Token'");
272                         break;
273                 }
274         }
275
276         lex.popTable();
277         return *this;
278 }
279
280
281
282 /////////////////////////////////////////////////////////////////////////
283 //
284 // Toolbars
285 //
286 /////////////////////////////////////////////////////////////////////////
287
288 void Toolbars::reset()
289 {
290         toolbar_info_.clear();
291         toolbar_visibility_.clear();
292 }
293
294
295 void Toolbars::readToolbars(Lexer & lex)
296 {
297         enum {
298                 TO_TOOLBAR = 1,
299                 TO_ENDTOOLBARSET
300         };
301
302         struct LexerKeyword toolTags[] = {
303                 { "end", TO_ENDTOOLBARSET },
304                 { "toolbar", TO_TOOLBAR }
305         };
306
307         //consistency check
308         if (compare_ascii_no_case(lex.getString(), "toolbarset")) {
309                 LYXERR0("Toolbars::readToolbars: ERROR wrong token:`"
310                        << lex.getString() << '\'');
311         }
312
313         lex.pushTable(toolTags);
314
315         if (lyxerr.debugging(Debug::PARSER))
316                 lex.printTable(lyxerr);
317
318         bool quit = false;
319         while (lex.isOK() && !quit) {
320                 switch (lex.lex()) {
321                 case TO_TOOLBAR: {
322                         ToolbarInfo tbinfo;
323                         tbinfo.read(lex);
324                         toolbar_info_.push_back(tbinfo);
325                         break;
326                         }
327                 case TO_ENDTOOLBARSET:
328                         quit = true;
329                         break;
330                 default:
331                         lex.printError("Toolbars::readToolbars: "
332                                        "Unknown toolbar tag: `$$Token'");
333                         break;
334                 }
335         }
336
337         lex.popTable();
338 }
339
340
341 void Toolbars::readToolbarSettings(Lexer & lex)
342 {
343         //consistency check
344         if (compare_ascii_no_case(lex.getString(), "toolbars")) {
345                 LYXERR0("Toolbars::readToolbarSettings: ERROR wrong token:`"
346                        << lex.getString() << '\'');
347         }
348
349         lex.next(true);
350
351         while (lex.isOK()) {
352                 string name = lex.getString();
353                 lex.next(true);
354
355                 if (!compare_ascii_no_case(name, "end"))
356                         return;
357
358                 int visibility = 0;
359                 string flagstr = lex.getString();
360                 lex.next(true);
361                 vector<string> flags = getVectorFromString(flagstr);
362
363                 vector<string>::const_iterator cit = flags.begin();
364                 vector<string>::const_iterator end = flags.end();
365
366                 for (; cit != end; ++cit) {
367                         Visibility flag = ON;
368                         if (!compare_ascii_no_case(*cit, "off"))
369                                 flag = OFF;
370                         else if (!compare_ascii_no_case(*cit, "on"))
371                                 flag = ON;
372                         else if (!compare_ascii_no_case(*cit, "math"))
373                                 flag = MATH;
374                         else if (!compare_ascii_no_case(*cit, "table"))
375                                 flag = TABLE;
376                         else if (!compare_ascii_no_case(*cit, "mathmacrotemplate"))
377                                 flag = MATHMACROTEMPLATE;
378                         else if (!compare_ascii_no_case(*cit, "review"))
379                                 flag = REVIEW;
380                         else if (!compare_ascii_no_case(*cit, "minibuffer"))
381                                 flag = MINIBUFFER;
382                         else if (!compare_ascii_no_case(*cit, "top"))
383                                 flag = TOP;
384                         else if (!compare_ascii_no_case(*cit, "bottom"))
385                                 flag = BOTTOM;
386                         else if (!compare_ascii_no_case(*cit, "left"))
387                                 flag = LEFT;
388                         else if (!compare_ascii_no_case(*cit, "right"))
389                                 flag = RIGHT;
390                         else if (!compare_ascii_no_case(*cit, "auto"))
391                                 flag = AUTO;
392                         else if (!compare_ascii_no_case(*cit, "samerow"))
393                                 flag = SAMEROW;
394                         else if (!compare_ascii_no_case(*cit, "ipa"))
395                                 flag = IPA;
396                         else {
397                                 LYXERR(Debug::ANY,
398                                         "Toolbars::readToolbarSettings: unrecognised token:`"
399                                         << *cit << '\'');
400                                 continue;
401                         }
402                         visibility |= flag;
403                 }
404                 toolbar_visibility_[name] = visibility;
405
406                 if (visibility & ALLOWAUTO) {
407                         if (ToolbarInfo const * ti = info(name))
408                                 const_cast<ToolbarInfo *>(ti)->allow_auto = true;
409                 }
410         }
411 }
412
413
414 ToolbarInfo const * Toolbars::info(std::string const & name) const
415 {
416         Infos::const_iterator end = toolbar_info_.end();
417         for (Infos::const_iterator it = toolbar_info_.begin(); it != end; ++it)
418                 if (it->name == name)
419                         return &(*it);
420         return nullptr;
421 }
422
423
424 int Toolbars::defaultVisibility(std::string const & name) const
425 {
426         map<string, int>::const_iterator it = toolbar_visibility_.find(name);
427         if (it != toolbar_visibility_.end())
428                 return it->second;
429         return OFF | BOTTOM;
430 }
431
432
433 bool Toolbars::isMainToolbar(std::string const & name) const
434 {
435         return toolbar_visibility_.find(name) != toolbar_visibility_.end();
436 }
437
438
439 } // namespace frontend
440 } // namespace lyx