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