]> git.lyx.org Git - lyx.git/blob - src/MenuBackend.C
get builddir!=srcdir compiling working; allow successful make even without noweb...
[lyx.git] / src / MenuBackend.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2000 The LyX Team.
8  *
9  *
10  * ====================================================== */
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 #include <config.h>
17 #include <memory>
18 #include "support/LAssert.h"
19 #include "MenuBackend.h"
20 #include "lyxlex.h"
21 #include "LyXAction.h"
22 #include "debug.h"
23 #include "gettext.h"
24
25 extern LyXAction lyxaction;
26
27 using std::endl;
28
29 // This is the global menu definition
30 MenuBackend menubackend;
31
32
33 MenuItem::MenuItem(Kind kind, string const & label, 
34                    string const & command, bool optional) 
35         : kind_(kind), label_(label), optional_(optional)
36 {
37         switch(kind) {
38         case Separator:
39         case Documents:
40         case Lastfiles:
41         case Toc:
42         case References:
43         case ViewFormats:
44         case UpdateFormats:
45         case ExportFormats:
46                 break;
47         case Command:
48                 action_ = lyxaction.LookupFunc(command);
49
50                 if (action_ == LFUN_UNKNOWN_ACTION) {
51                         lyxerr << "MenuItem(): LyX command `"
52                                << command << "' does not exist." << endl; 
53                 }
54                 if (optional_)
55                         lyxerr[Debug::GUI] << "Optional item " 
56                                            << command << endl; 
57                 break;
58         case Submenu:
59                 submenu_ = command;
60                 break;
61         }
62 }
63
64
65 Menu & Menu::add(MenuItem const & i)
66 {
67         items_.push_back(i);
68         return *this;
69 }
70
71
72 Menu & Menu::read(LyXLex & lex)
73 {
74         enum Menutags {
75                 md_item = 1,
76                 md_documents,
77                 md_endmenu,
78                 md_exportformats,
79                 md_lastfiles,
80                 md_optitem,
81                 md_references,
82                 md_separator,
83                 md_submenu,
84                 md_toc,
85                 md_updateformats,
86                 md_viewformats,
87                 md_last
88         };
89
90         struct keyword_item menutags[md_last-1] = {
91                 { "documents", md_documents },
92                 { "end", md_endmenu },
93                 { "exportformats", md_exportformats },
94                 { "item", md_item },
95                 { "lastfiles", md_lastfiles },
96                 { "optitem", md_optitem }, 
97                 { "references", md_references },
98                 { "separator", md_separator },
99                 { "submenu", md_submenu },
100                 { "toc", md_toc },
101                 { "updateformats", md_updateformats },
102                 { "viewformats", md_viewformats }
103         };
104
105         lex.pushTable(menutags, md_last - 1);
106         if (lyxerr.debugging(Debug::PARSER))
107                 lex.printTable(lyxerr);
108
109         bool quit = false;
110         bool optional = false;
111
112         while (lex.IsOK() && !quit) {
113                 switch(lex.lex()) {
114                 case md_optitem:
115                         optional = true;
116                         // fallback to md_item
117                 case md_item: {
118                         lex.next();
119                         char * tmp = ::strdup(lex.GetString().c_str());
120                         string name = _(tmp);
121                         free(tmp);
122                         lex.next();
123                         string command = lex.GetString();
124                         add(MenuItem(MenuItem::Command, name, 
125                                      command, optional));
126                         optional = false;
127                         break;
128                 }
129
130                 case md_separator:
131                         add(MenuItem(MenuItem::Separator));
132                         break;
133
134                 case md_lastfiles:
135                         add(MenuItem(MenuItem::Lastfiles));
136                         break;
137
138                 case md_documents:
139                         add(MenuItem(MenuItem::Documents));
140                         break;
141
142                 case md_toc:
143                         add(MenuItem(MenuItem::Toc));
144                         break;
145
146                 case md_references:
147                         add(MenuItem(MenuItem::References));
148                         break;
149
150                 case md_viewformats:
151                         add(MenuItem(MenuItem::ViewFormats));
152                         break;
153
154                 case md_updateformats:
155                         add(MenuItem(MenuItem::UpdateFormats));
156                         break;
157
158                 case md_exportformats:
159                         add(MenuItem(MenuItem::ExportFormats));
160                         break;
161
162                 case md_submenu: {
163                         lex.next();
164                         char * tmp = ::strdup(lex.GetString().c_str());
165                         string mlabel = _(tmp);
166                         free(tmp);
167                         lex.next();
168                         string mname = lex.GetString();
169                         add(MenuItem(MenuItem::Submenu, mlabel, mname));
170                         break;
171                 }
172
173                 case md_endmenu:
174                         quit = true;
175                         break;
176
177                 default:
178                         lex.printError("menubar::read: "
179                                        "Unknown menu tag: `$$Token'");
180                         break;
181                 }
182         }
183         lex.popTable();
184         return *this;
185 }
186
187
188 void MenuBackend::read(LyXLex & lex)
189 {
190         enum Menutags {
191                 md_menu = 1,
192                 md_menubar,
193                 md_endmenuset,
194                 md_last
195         };
196
197         struct keyword_item menutags[md_last - 1] = {
198                 { "end", md_endmenuset },
199                 { "menu", md_menu },
200                 { "menubar", md_menubar }
201         };
202
203         //consistency check
204         if (compare_no_case(lex.GetString(), "menuset"))
205                 lyxerr << "Menubackend::read: ERROR wrong token:`"
206                        << lex.GetString() << '\'' << endl;
207
208         lex.pushTable(menutags, md_last - 1);
209         if (lyxerr.debugging(Debug::PARSER))
210                 lex.printTable(lyxerr);
211
212         bool quit = false;
213         bool menubar = false;
214
215         while (lex.IsOK() && !quit) {
216                 switch(lex.lex()) {
217                 case md_menubar: 
218                         menubar = true;
219                         // fallback to md_menu
220                 case md_menu: {
221                         lex.next();
222                         string name = lex.GetString();
223                         if (hasMenu(name)) {
224                                 if (getMenu(name).menubar() == menubar) {
225                                         getMenu(name).read(lex);
226                                 } else {
227                                         lex.printError("Cannot append to menu `$$Token' unless it is of the same type");
228                                         return;
229                                 }
230                         } else {                                
231                                 Menu menu(name, menubar);
232                                 menu.read(lex);
233                                 add(menu);
234                         }
235                         menubar = false;
236                         break;
237                 }
238                 case md_endmenuset:
239                         quit = true;
240                         break;
241                 default:
242                         lex.printError("menubackend::read: "
243                                        "Unknown menu tag: `$$Token'");
244                         break;
245                 }
246         }
247         lex.popTable();
248 }
249
250
251 void MenuBackend::defaults()
252 {
253         menulist_.clear();
254
255         lyxerr[Debug::GUI] << "MenuBackend::defaults: using default values" 
256                            << endl;
257
258         Menu file("file");
259         file
260                 .add(MenuItem(MenuItem::Command, _("New...|N"), "buffer-new"))
261                 .add(MenuItem(MenuItem::Command, _("Open...|O"), "buffer-open"))
262                 .add(MenuItem(MenuItem::Submenu, _("Import|I"), "import"))
263                 .add(MenuItem(MenuItem::Command, _("Quit|Q"), "lyx-quit"))
264                 .add(MenuItem(MenuItem::Separator))
265                 .add(MenuItem(MenuItem::Lastfiles));
266         add(file);
267
268         Menu import("import");
269         import
270                 .add(MenuItem(MenuItem::Command,
271                               _("LaTeX...|L"), "buffer-import latex"))
272                 .add(MenuItem(MenuItem::Command,
273                               _("LinuxDoc...|L"), "buffer-import linuxdoc"));
274         add(import);
275  
276         Menu edit("edit");
277         edit
278                 .add(MenuItem(MenuItem::Command, _("Cut"), "cut"))
279                 .add(MenuItem(MenuItem::Command, _("Copy"), "copy"))
280                 .add(MenuItem(MenuItem::Command, _("Paste"), "paste"))
281                 .add(MenuItem(MenuItem::Command, _("Emphasize"), "font-emph"));
282         add(edit);
283
284         Menu documents("documents");
285         documents.add(MenuItem(MenuItem::Documents));
286         add(documents);
287
288         Menu main("main", true);
289         main
290                 .add(MenuItem(MenuItem::Submenu, _("File|F"), "file"))
291                 .add(MenuItem(MenuItem::Submenu, _("Edit|E"), "edit"))
292                 .add(MenuItem(MenuItem::Submenu,
293                               _("Documents|D"), "documents"));
294         add(main);
295
296         Menu main_nobuffer("main_nobuffer", true);
297         main_nobuffer.add(MenuItem(MenuItem::Submenu, _("File|F"), "file"));
298         add(main_nobuffer);
299
300         if (lyxerr.debugging(Debug::GUI)) {
301                 for(const_iterator cit = begin();
302                     cit != end() ; ++cit)
303                         lyxerr << "Menu name: " << cit->name() 
304                                << ", Menubar: " << cit->menubar() 
305                                << endl;
306         }
307 }
308
309
310 void MenuBackend::add(Menu const & menu)
311 {
312         menulist_.push_back(menu);
313 }
314
315
316 bool MenuBackend::hasMenu(string const & name) const
317 {
318         const_iterator mend = end();
319         for (const_iterator cit = begin(); cit != mend; ++cit) {
320                 if ((*cit).name() == name)
321                         return true;
322         }
323         return false;
324 }
325
326
327 Menu const & MenuBackend::getMenu(string const & name) const
328 {
329         const_iterator mend = end();
330         for (const_iterator cit = begin(); cit != mend; ++cit) {
331                 if ((*cit).name() == name)
332                         return (*cit);
333         }
334         Assert(false); // we actually require the name to exist.
335         return menulist_.front();
336 }
337
338
339 Menu & MenuBackend::getMenu(string const & name)
340 {
341         MenuList::iterator end = menulist_.end();
342         for (MenuList::iterator cit = menulist_.begin(); 
343              cit != end; ++cit) {
344                 if ((*cit).name() == name)
345                         return (*cit);
346         }
347         Assert(false); // we actually require the name to exist.
348         return menulist_.front();
349 }
350