]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/Toolbars.cpp
Merge remote-tracking branch 'features/properpaint' into 2.3.2-staging
[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 "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 type, FuncRequest const & func,
42                          docstring const & label)
43         : type_(type), func_(make_shared<FuncRequest>(func)), label_(label)
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_ENDTOOLBAR,
67                 TO_SEPARATOR,
68                 TO_LAYOUTS,
69                 TO_MINIBUFFER,
70                 TO_TABLEINSERT,
71                 TO_POPUPMENU,
72                 TO_STICKYPOPUPMENU,
73                 TO_ICONPALETTE,
74                 TO_EXPORTFORMATS,
75                 TO_IMPORTFORMATS,
76                 TO_UPDATEFORMATS,
77                 TO_VIEWFORMATS
78         };
79
80         struct LexerKeyword toolTags[] = {
81                 { "end", TO_ENDTOOLBAR },
82                 { "exportformats", TO_EXPORTFORMATS },
83                 { "iconpalette", TO_ICONPALETTE },
84                 { "importformats", TO_IMPORTFORMATS },
85                 { "item", TO_COMMAND },
86                 { "layouts", TO_LAYOUTS },
87                 { "minibuffer", TO_MINIBUFFER },
88                 { "popupmenu", TO_POPUPMENU },
89                 { "separator", TO_SEPARATOR },
90                 { "stickypopupmenu", TO_STICKYPOPUPMENU },
91                 { "tableinsert", TO_TABLEINSERT },
92                 { "updateformats", TO_UPDATEFORMATS },
93                 { "viewformats", TO_VIEWFORMATS },
94         };
95
96         //consistency check
97         if (compare_ascii_no_case(lex.getString(), "toolbar")) {
98                 LYXERR0("ToolbarInfo::read: ERROR wrong token:`"
99                        << lex.getString() << '\'');
100         }
101
102         lex.next(true);
103         name = lex.getString();
104
105         lex.next(true);
106         gui_name = _(lex.getString());
107
108         // FIXME what to do here?
109         if (!lex) {
110                 LYXERR0("ToolbarInfo::read: Malformed toolbar "
111                         "description " <<  lex.getString());
112                 return *this;
113         }
114
115         bool quit = false;
116
117         lex.pushTable(toolTags);
118
119         if (lyxerr.debugging(Debug::PARSER))
120                 lex.printTable(lyxerr);
121
122         while (lex.isOK() && !quit) {
123                 int const code = lex.lex();
124                 switch (code) {
125                 case TO_COMMAND:
126                         if (lex.next(true)) {
127                                 docstring const tooltip = translateIfPossible(lex.getDocString());
128                                 lex.next(true);
129                                 string const func_arg = lex.getString();
130                                 LYXERR(Debug::PARSER, "ToolbarInfo::read TO_COMMAND func: `"
131                                         << func_arg << '\'');
132
133                                 FuncRequest func =
134                                         lyxaction.lookupFunc(func_arg);
135                                 add(ToolbarItem(ToolbarItem::COMMAND, func, tooltip));
136                         }
137                         break;
138
139                 case TO_MINIBUFFER:
140                         add(ToolbarItem(ToolbarItem::MINIBUFFER,
141                                 FuncRequest(FuncCode(ToolbarItem::MINIBUFFER))));
142                         break;
143
144                 case TO_SEPARATOR:
145                         add(ToolbarItem(ToolbarItem::SEPARATOR,
146                                 FuncRequest(FuncCode(ToolbarItem::SEPARATOR))));
147                         break;
148
149                 case TO_POPUPMENU:
150                         if (lex.next(true)) {
151                                 string const name = lex.getString();
152                                 lex.next(true);
153                                 docstring const label = lex.getDocString();
154                                 add(ToolbarItem(ToolbarItem::POPUPMENU, name, label));
155                         }
156                         break;
157
158                 case TO_STICKYPOPUPMENU:
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::STICKYPOPUPMENU, 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(FuncCode(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(FuncCode(ToolbarItem::TABLEINSERT)), tooltip));
186                         }
187                         break;
188
189                 case TO_ENDTOOLBAR:
190                         quit = true;
191                         break;
192
193                 case TO_EXPORTFORMATS:
194                 case TO_IMPORTFORMATS:
195                 case TO_UPDATEFORMATS:
196                 case TO_VIEWFORMATS: {
197                         FormatList formats = (code == TO_IMPORTFORMATS) ?
198                                 theConverters().importableFormats() :
199                                 theConverters().exportableFormats(true);
200                         sort(formats.begin(), formats.end());
201                         for (Format const * f : formats) {
202                                 if (f->dummy())
203                                         continue;
204                                 if (code != TO_IMPORTFORMATS &&
205                                     !f->documentFormat())
206                                         continue;
207
208                                 docstring const prettyname = f->prettyname();
209                                 docstring tooltip;
210                                 FuncCode lfun = LFUN_NOACTION;
211                                 switch (code) {
212                                 case TO_EXPORTFORMATS:
213                                         lfun = LFUN_BUFFER_EXPORT;
214                                         tooltip = _("Export %1$s");
215                                         break;
216                                 case TO_IMPORTFORMATS:
217                                         lfun = LFUN_BUFFER_IMPORT;
218                                         tooltip = _("Import %1$s");
219                                         break;
220                                 case TO_UPDATEFORMATS:
221                                         lfun = LFUN_BUFFER_UPDATE;
222                                         tooltip = _("Update %1$s");
223                                         break;
224                                 case TO_VIEWFORMATS:
225                                         lfun = LFUN_BUFFER_VIEW;
226                                         tooltip = _("View %1$s");
227                                         break;
228                                 }
229                                 FuncRequest func(lfun, f->name(),
230                                                 FuncRequest::TOOLBAR);
231                                 add(ToolbarItem(ToolbarItem::COMMAND, func,
232                                                 bformat(tooltip, prettyname)));
233                         }
234                         break;
235                 }
236
237                 default:
238                         lex.printError("ToolbarInfo::read: "
239                                        "Unknown toolbar tag: `$$Token'");
240                         break;
241                 }
242         }
243
244         lex.popTable();
245         return *this;
246 }
247
248
249
250 /////////////////////////////////////////////////////////////////////////
251 //
252 // Toolbars
253 //
254 /////////////////////////////////////////////////////////////////////////
255
256 void Toolbars::reset()
257 {
258         toolbar_info_.clear();
259         toolbar_visibility_.clear();
260 }
261
262
263 void Toolbars::readToolbars(Lexer & lex)
264 {
265         enum {
266                 TO_TOOLBAR = 1,
267                 TO_ENDTOOLBARSET
268         };
269
270         struct LexerKeyword toolTags[] = {
271                 { "end", TO_ENDTOOLBARSET },
272                 { "toolbar", TO_TOOLBAR }
273         };
274
275         //consistency check
276         if (compare_ascii_no_case(lex.getString(), "toolbarset")) {
277                 LYXERR0("Toolbars::readToolbars: ERROR wrong token:`"
278                        << lex.getString() << '\'');
279         }
280
281         lex.pushTable(toolTags);
282
283         if (lyxerr.debugging(Debug::PARSER))
284                 lex.printTable(lyxerr);
285
286         bool quit = false;
287         while (lex.isOK() && !quit) {
288                 switch (lex.lex()) {
289                 case TO_TOOLBAR: {
290                         ToolbarInfo tbinfo;
291                         tbinfo.read(lex);
292                         toolbar_info_.push_back(tbinfo);
293                         break;
294                         }
295                 case TO_ENDTOOLBARSET:
296                         quit = true;
297                         break;
298                 default:
299                         lex.printError("Toolbars::readToolbars: "
300                                        "Unknown toolbar tag: `$$Token'");
301                         break;
302                 }
303         }
304
305         lex.popTable();
306 }
307
308
309 void Toolbars::readToolbarSettings(Lexer & lex)
310 {
311         //consistency check
312         if (compare_ascii_no_case(lex.getString(), "toolbars")) {
313                 LYXERR0("Toolbars::readToolbarSettings: ERROR wrong token:`"
314                        << lex.getString() << '\'');
315         }
316
317         lex.next(true);
318
319         while (lex.isOK()) {
320                 string name = lex.getString();
321                 lex.next(true);
322
323                 if (!compare_ascii_no_case(name, "end"))
324                         return;
325
326                 int visibility = 0;
327                 string flagstr = lex.getString();
328                 lex.next(true);
329                 vector<string> flags = getVectorFromString(flagstr);
330
331                 vector<string>::const_iterator cit = flags.begin();
332                 vector<string>::const_iterator end = flags.end();
333
334                 for (; cit != end; ++cit) {
335                         Visibility flag = ON;
336                         if (!compare_ascii_no_case(*cit, "off"))
337                                 flag = OFF;
338                         else if (!compare_ascii_no_case(*cit, "on"))
339                                 flag = ON;
340                         else if (!compare_ascii_no_case(*cit, "math"))
341                                 flag = MATH;
342                         else if (!compare_ascii_no_case(*cit, "table"))
343                                 flag = TABLE;
344                         else if (!compare_ascii_no_case(*cit, "mathmacrotemplate"))
345                                 flag = MATHMACROTEMPLATE;
346                         else if (!compare_ascii_no_case(*cit, "review"))
347                                 flag = REVIEW;
348                         else if (!compare_ascii_no_case(*cit, "minibuffer"))
349                                 flag = MINIBUFFER;
350                         else if (!compare_ascii_no_case(*cit, "top"))
351                                 flag = TOP;
352                         else if (!compare_ascii_no_case(*cit, "bottom"))
353                                 flag = BOTTOM;
354                         else if (!compare_ascii_no_case(*cit, "left"))
355                                 flag = LEFT;
356                         else if (!compare_ascii_no_case(*cit, "right"))
357                                 flag = RIGHT;
358                         else if (!compare_ascii_no_case(*cit, "auto"))
359                                 flag = AUTO;
360                         else if (!compare_ascii_no_case(*cit, "samerow"))
361                                 flag = SAMEROW;
362                         else if (!compare_ascii_no_case(*cit, "ipa"))
363                                 flag = IPA;
364                         else {
365                                 LYXERR(Debug::ANY,
366                                         "Toolbars::readToolbarSettings: unrecognised token:`"
367                                         << *cit << '\'');
368                                 continue;
369                         }
370                         visibility |= flag;
371                 }
372                 toolbar_visibility_[name] = visibility;
373
374                 if (visibility & ALLOWAUTO) {
375                         if (ToolbarInfo const * ti = info(name))
376                                 const_cast<ToolbarInfo *>(ti)->gui_name +=
377                                         " (" + _("auto") + ")";
378                 }
379         }
380 }
381
382
383 ToolbarInfo const * Toolbars::info(std::string const & name) const
384 {
385         Infos::const_iterator end = toolbar_info_.end();
386         for (Infos::const_iterator it = toolbar_info_.begin(); it != end; ++it)
387                 if (it->name == name)
388                         return &(*it);
389         return 0;
390 }
391
392
393 int Toolbars::defaultVisibility(std::string const & name) const
394 {
395         map<string, int>::const_iterator it = toolbar_visibility_.find(name);
396         if (it != toolbar_visibility_.end())
397                 return it->second;
398         return OFF | BOTTOM;
399 }
400
401
402 bool Toolbars::isMainToolbar(std::string const & name) const
403 {
404         return toolbar_visibility_.find(name) != toolbar_visibility_.end();
405 }
406
407
408 } // namespace frontend
409 } // namespace lyx