]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/Toolbars.cpp
Use QMessageBox for toggleWarning if possible
[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;
198                         if (code == TO_IMPORTFORMATS)
199                                 formats = theConverters().importableFormats();
200                         else if (code == TO_EXPORTFORMATS)
201                                 formats = theConverters().exportableFormats(false);
202                         else
203                                 formats = theConverters().exportableFormats(true);
204                         sort(formats.begin(), formats.end());
205                         for (Format const * f : formats) {
206                                 if (f->dummy())
207                                         continue;
208                                 if (code != TO_IMPORTFORMATS &&
209                                     !f->documentFormat())
210                                         continue;
211
212                                 docstring const prettyname = f->prettyname();
213                                 docstring tooltip;
214                                 FuncCode lfun = LFUN_NOACTION;
215                                 switch (code) {
216                                 case TO_EXPORTFORMATS:
217                                         lfun = LFUN_BUFFER_EXPORT;
218                                         tooltip = _("Export %1$s");
219                                         break;
220                                 case TO_IMPORTFORMATS:
221                                         lfun = LFUN_BUFFER_IMPORT;
222                                         tooltip = _("Import %1$s");
223                                         break;
224                                 case TO_UPDATEFORMATS:
225                                         lfun = LFUN_BUFFER_UPDATE;
226                                         tooltip = _("Update %1$s");
227                                         break;
228                                 case TO_VIEWFORMATS:
229                                         lfun = LFUN_BUFFER_VIEW;
230                                         tooltip = _("View %1$s");
231                                         break;
232                                 }
233                                 FuncRequest func(lfun, f->name(),
234                                                 FuncRequest::TOOLBAR);
235                                 add(ToolbarItem(ToolbarItem::COMMAND, func,
236                                                 bformat(tooltip, translateIfPossible(prettyname))));
237                         }
238                         break;
239                 }
240
241                 default:
242                         lex.printError("ToolbarInfo::read: "
243                                        "Unknown toolbar tag: `$$Token'");
244                         break;
245                 }
246         }
247
248         lex.popTable();
249         return *this;
250 }
251
252
253
254 /////////////////////////////////////////////////////////////////////////
255 //
256 // Toolbars
257 //
258 /////////////////////////////////////////////////////////////////////////
259
260 void Toolbars::reset()
261 {
262         toolbar_info_.clear();
263         toolbar_visibility_.clear();
264 }
265
266
267 void Toolbars::readToolbars(Lexer & lex)
268 {
269         enum {
270                 TO_TOOLBAR = 1,
271                 TO_ENDTOOLBARSET
272         };
273
274         struct LexerKeyword toolTags[] = {
275                 { "end", TO_ENDTOOLBARSET },
276                 { "toolbar", TO_TOOLBAR }
277         };
278
279         //consistency check
280         if (compare_ascii_no_case(lex.getString(), "toolbarset")) {
281                 LYXERR0("Toolbars::readToolbars: ERROR wrong token:`"
282                        << lex.getString() << '\'');
283         }
284
285         lex.pushTable(toolTags);
286
287         if (lyxerr.debugging(Debug::PARSER))
288                 lex.printTable(lyxerr);
289
290         bool quit = false;
291         while (lex.isOK() && !quit) {
292                 switch (lex.lex()) {
293                 case TO_TOOLBAR: {
294                         ToolbarInfo tbinfo;
295                         tbinfo.read(lex);
296                         toolbar_info_.push_back(tbinfo);
297                         break;
298                         }
299                 case TO_ENDTOOLBARSET:
300                         quit = true;
301                         break;
302                 default:
303                         lex.printError("Toolbars::readToolbars: "
304                                        "Unknown toolbar tag: `$$Token'");
305                         break;
306                 }
307         }
308
309         lex.popTable();
310 }
311
312
313 void Toolbars::readToolbarSettings(Lexer & lex)
314 {
315         //consistency check
316         if (compare_ascii_no_case(lex.getString(), "toolbars")) {
317                 LYXERR0("Toolbars::readToolbarSettings: ERROR wrong token:`"
318                        << lex.getString() << '\'');
319         }
320
321         lex.next(true);
322
323         while (lex.isOK()) {
324                 string name = lex.getString();
325                 lex.next(true);
326
327                 if (!compare_ascii_no_case(name, "end"))
328                         return;
329
330                 int visibility = 0;
331                 string flagstr = lex.getString();
332                 lex.next(true);
333                 vector<string> flags = getVectorFromString(flagstr);
334
335                 vector<string>::const_iterator cit = flags.begin();
336                 vector<string>::const_iterator end = flags.end();
337
338                 for (; cit != end; ++cit) {
339                         Visibility flag = ON;
340                         if (!compare_ascii_no_case(*cit, "off"))
341                                 flag = OFF;
342                         else if (!compare_ascii_no_case(*cit, "on"))
343                                 flag = ON;
344                         else if (!compare_ascii_no_case(*cit, "math"))
345                                 flag = MATH;
346                         else if (!compare_ascii_no_case(*cit, "table"))
347                                 flag = TABLE;
348                         else if (!compare_ascii_no_case(*cit, "mathmacrotemplate"))
349                                 flag = MATHMACROTEMPLATE;
350                         else if (!compare_ascii_no_case(*cit, "review"))
351                                 flag = REVIEW;
352                         else if (!compare_ascii_no_case(*cit, "minibuffer"))
353                                 flag = MINIBUFFER;
354                         else if (!compare_ascii_no_case(*cit, "top"))
355                                 flag = TOP;
356                         else if (!compare_ascii_no_case(*cit, "bottom"))
357                                 flag = BOTTOM;
358                         else if (!compare_ascii_no_case(*cit, "left"))
359                                 flag = LEFT;
360                         else if (!compare_ascii_no_case(*cit, "right"))
361                                 flag = RIGHT;
362                         else if (!compare_ascii_no_case(*cit, "auto"))
363                                 flag = AUTO;
364                         else if (!compare_ascii_no_case(*cit, "samerow"))
365                                 flag = SAMEROW;
366                         else if (!compare_ascii_no_case(*cit, "ipa"))
367                                 flag = IPA;
368                         else {
369                                 LYXERR(Debug::ANY,
370                                         "Toolbars::readToolbarSettings: unrecognised token:`"
371                                         << *cit << '\'');
372                                 continue;
373                         }
374                         visibility |= flag;
375                 }
376                 toolbar_visibility_[name] = visibility;
377
378                 if (visibility & ALLOWAUTO) {
379                         if (ToolbarInfo const * ti = info(name))
380                                 const_cast<ToolbarInfo *>(ti)->gui_name +=
381                                         " (" + _("auto") + ")";
382                 }
383         }
384 }
385
386
387 ToolbarInfo const * Toolbars::info(std::string const & name) const
388 {
389         Infos::const_iterator end = toolbar_info_.end();
390         for (Infos::const_iterator it = toolbar_info_.begin(); it != end; ++it)
391                 if (it->name == name)
392                         return &(*it);
393         return 0;
394 }
395
396
397 int Toolbars::defaultVisibility(std::string const & name) const
398 {
399         map<string, int>::const_iterator it = toolbar_visibility_.find(name);
400         if (it != toolbar_visibility_.end())
401                 return it->second;
402         return OFF | BOTTOM;
403 }
404
405
406 bool Toolbars::isMainToolbar(std::string const & name) const
407 {
408         return toolbar_visibility_.find(name) != toolbar_visibility_.end();
409 }
410
411
412 } // namespace frontend
413 } // namespace lyx