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