diff options
-rw-r--r-- | src/MenuCreator.cc | 208 |
1 files changed, 32 insertions, 176 deletions
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc index b944bcb..cc891cc 100644 --- a/src/MenuCreator.cc +++ b/src/MenuCreator.cc | |||
@@ -138,13 +138,16 @@ void endFile() { | |||
138 | } | 138 | } |
139 | 139 | ||
140 | 140 | ||
141 | void createStyleMenu(FbTk::Menu &parent, const string &label, | 141 | std::auto_ptr<FbMenu> createStyleMenu(int screen_number, const string &label, |
142 | AutoReloadHelper *reloader, const string &directory) { | 142 | AutoReloadHelper *reloader, const string &directory) { |
143 | |||
144 | std::auto_ptr<FbMenu> menu(MenuCreator::createMenu(label, screen_number)); | ||
145 | |||
143 | // perform shell style ~ home directory expansion | 146 | // perform shell style ~ home directory expansion |
144 | string stylesdir(FbTk::StringUtil::expandFilename(directory)); | 147 | string stylesdir(FbTk::StringUtil::expandFilename(directory)); |
145 | 148 | ||
146 | if (!FbTk::FileUtil::isDirectory(stylesdir.c_str())) | 149 | if (!FbTk::FileUtil::isDirectory(stylesdir.c_str())) |
147 | return; | 150 | return menu; |
148 | 151 | ||
149 | if (reloader) | 152 | if (reloader) |
150 | reloader->addFile(stylesdir); | 153 | reloader->addFile(stylesdir); |
@@ -169,22 +172,24 @@ void createStyleMenu(FbTk::Menu &parent, const string &label, | |||
169 | (style[style.length() - 1] != '~')) || | 172 | (style[style.length() - 1] != '~')) || |
170 | FbTk::FileUtil::isRegularFile((style + "/theme.cfg").c_str()) || | 173 | FbTk::FileUtil::isRegularFile((style + "/theme.cfg").c_str()) || |
171 | FbTk::FileUtil::isRegularFile((style + "/style.cfg").c_str())) | 174 | FbTk::FileUtil::isRegularFile((style + "/style.cfg").c_str())) |
172 | parent.insert(new StyleMenuItem(filelist[file_index], style)); | 175 | menu->insert(new StyleMenuItem(filelist[file_index], style)); |
173 | } | 176 | } |
174 | // update menu graphics | 177 | // update menu graphics |
175 | parent.updateMenu(); | 178 | menu->updateMenu(); |
176 | 179 | return menu; | |
177 | } | 180 | } |
178 | 181 | ||
179 | void createRootCmdMenu(FbTk::Menu &parent, const string &label, | 182 | std::auto_ptr<FbMenu> createRootCmdMenu(int screen_number, const string &label, |
180 | const string &directory, AutoReloadHelper *reloader, | 183 | const string &directory, AutoReloadHelper *reloader, |
181 | const string &cmd) { | 184 | const string &cmd) { |
182 | 185 | ||
186 | std::auto_ptr<FbMenu> menu(MenuCreator::createMenu(label, screen_number)); | ||
187 | |||
183 | // perform shell style ~ home directory expansion | 188 | // perform shell style ~ home directory expansion |
184 | string rootcmddir(FbTk::StringUtil::expandFilename(directory)); | 189 | string rootcmddir(FbTk::StringUtil::expandFilename(directory)); |
185 | 190 | ||
186 | if (!FbTk::FileUtil::isDirectory(rootcmddir.c_str())) | 191 | if (!FbTk::FileUtil::isDirectory(rootcmddir.c_str())) |
187 | return; | 192 | return menu; |
188 | 193 | ||
189 | if (reloader) | 194 | if (reloader) |
190 | reloader->addFile(rootcmddir); | 195 | reloader->addFile(rootcmddir); |
@@ -208,11 +213,11 @@ void createRootCmdMenu(FbTk::Menu &parent, const string &label, | |||
208 | if ((FbTk::FileUtil::isRegularFile(rootcmd.c_str()) && | 213 | if ((FbTk::FileUtil::isRegularFile(rootcmd.c_str()) && |
209 | (filelist[file_index][0] != '.') && | 214 | (filelist[file_index][0] != '.') && |
210 | (rootcmd[rootcmd.length() - 1] != '~'))) | 215 | (rootcmd[rootcmd.length() - 1] != '~'))) |
211 | parent.insert(new RootCmdMenuItem(filelist[file_index], rootcmd, cmd)); | 216 | menu->insert(new RootCmdMenuItem(filelist[file_index], rootcmd, cmd)); |
212 | } | 217 | } |
213 | // update menu graphics | 218 | // update menu graphics |
214 | parent.updateMenu(); | 219 | menu->updateMenu(); |
215 | 220 | return menu; | |
216 | } | 221 | } |
217 | 222 | ||
218 | 223 | ||
@@ -249,11 +254,6 @@ public: | |||
249 | 254 | ||
250 | }; | 255 | }; |
251 | 256 | ||
252 | void translateMenuItem(FbTk::Parser &parse, ParseItem &item, | ||
253 | FbTk::StringConvertor &labelconvertor, | ||
254 | AutoReloadHelper *reloader); | ||
255 | |||
256 | |||
257 | void parseMenu(FbTk::Parser &pars, FbTk::Menu &menu, | 257 | void parseMenu(FbTk::Parser &pars, FbTk::Menu &menu, |
258 | FbTk::StringConvertor &label_convertor, | 258 | FbTk::StringConvertor &label_convertor, |
259 | AutoReloadHelper *reloader) { | 259 | AutoReloadHelper *reloader) { |
@@ -262,158 +262,7 @@ void parseMenu(FbTk::Parser &pars, FbTk::Menu &menu, | |||
262 | pitem.load(pars, label_convertor); | 262 | pitem.load(pars, label_convertor); |
263 | if (pitem.key() == "end") | 263 | if (pitem.key() == "end") |
264 | return; | 264 | return; |
265 | translateMenuItem(pars, pitem, label_convertor, reloader); | 265 | // translateMenuItem(pars, pitem, label_convertor, reloader); |
266 | } | ||
267 | } | ||
268 | |||
269 | void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, | ||
270 | FbTk::StringConvertor &labelconvertor, | ||
271 | AutoReloadHelper *reloader) { | ||
272 | if (pitem.menu() == 0) | ||
273 | throw string("translateMenuItem: We must have a menu in ParseItem!"); | ||
274 | |||
275 | FbTk::Menu &menu = *pitem.menu(); | ||
276 | const string &str_key = pitem.key(); | ||
277 | const string &str_cmd = pitem.command(); | ||
278 | const string &str_label = pitem.label(); | ||
279 | |||
280 | const int screen_number = menu.screenNumber(); | ||
281 | _FB_USES_NLS; | ||
282 | |||
283 | if (str_key == "end") { | ||
284 | return; | ||
285 | } else if (str_key == "nop") { | ||
286 | int menuSize = menu.insert(str_label); | ||
287 | menu.setItemEnabled(menuSize-1, false); | ||
288 | } else if (str_key == "icons") { | ||
289 | FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", menu.screenNumber()); | ||
290 | if (submenu == 0) | ||
291 | return; | ||
292 | if (str_label.empty()) | ||
293 | menu.insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title")); | ||
294 | else | ||
295 | menu.insert(str_label, submenu); | ||
296 | } else if (str_key == "exit") { // exit | ||
297 | FbTk::RefCount<FbTk::Command<void> > exit_cmd(FbTk::CommandParser<void>::instance().parse("exit")); | ||
298 | if (str_label.empty()) | ||
299 | menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd); | ||
300 | else | ||
301 | menu.insert(str_label, exit_cmd); | ||
302 | } else if (str_key == "exec") { | ||
303 | // execute and hide menu | ||
304 | FbTk::RefCount<FbTk::Command<void> > exec_cmd(FbTk::CommandParser<void>::instance().parse("exec " + str_cmd)); | ||
305 | menu.insert(str_label, exec_cmd); | ||
306 | } else if (str_key == "macrocmd") { | ||
307 | FbTk::RefCount<FbTk::Command<void> > macro_cmd(FbTk::CommandParser<void>::instance().parse("macrocmd " + str_cmd)); | ||
308 | menu.insert(str_label, macro_cmd); | ||
309 | } else if (str_key == "style") { // style | ||
310 | menu.insert(new StyleMenuItem(str_label, str_cmd)); | ||
311 | } else if (str_key == "config") { | ||
312 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); | ||
313 | if (screen != 0) | ||
314 | menu.insert(str_label, &screen->configMenu()); | ||
315 | } // end of config | ||
316 | else if (str_key == "include") { // include | ||
317 | |||
318 | // this will make sure we dont get stuck in a loop | ||
319 | static size_t safe_counter = 0; | ||
320 | if (safe_counter > 10) | ||
321 | return; | ||
322 | |||
323 | safe_counter++; | ||
324 | |||
325 | string newfile = FbTk::StringUtil::expandFilename(str_label); | ||
326 | if (FbTk::FileUtil::isDirectory(newfile.c_str())) { | ||
327 | // inject every file in this directory into the current menu | ||
328 | FbTk::Directory dir(newfile.c_str()); | ||
329 | |||
330 | vector<string> filelist(dir.entries()); | ||
331 | for (size_t file_index = 0; file_index < dir.entries(); ++file_index) | ||
332 | filelist[file_index] = dir.readFilename(); | ||
333 | sort(filelist.begin(), filelist.end(), less<string>()); | ||
334 | |||
335 | for (size_t file_index = 0; file_index < dir.entries(); file_index++) { | ||
336 | string thisfile(newfile + '/' + filelist[file_index]); | ||
337 | |||
338 | if (FbTk::FileUtil::isRegularFile(thisfile.c_str()) && | ||
339 | (filelist[file_index][0] != '.') && | ||
340 | (thisfile[thisfile.length() - 1] != '~')) { | ||
341 | MenuCreator::createFromFile(thisfile, menu, reloader, false); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | } else { | ||
346 | // inject this file into the current menu | ||
347 | MenuCreator::createFromFile(newfile, menu, reloader, false); | ||
348 | } | ||
349 | |||
350 | safe_counter--; | ||
351 | |||
352 | } // end of include | ||
353 | else if (str_key == "submenu") { | ||
354 | |||
355 | FbTk::Menu *submenu = MenuCreator::createMenu("", screen_number); | ||
356 | if (submenu == 0) | ||
357 | return; | ||
358 | |||
359 | if (!str_cmd.empty()) | ||
360 | submenu->setLabel(str_cmd); | ||
361 | else | ||
362 | submenu->setLabel(str_label); | ||
363 | |||
364 | parseMenu(parse, *submenu, labelconvertor, reloader); | ||
365 | submenu->updateMenu(); | ||
366 | menu.insert(str_label, submenu); | ||
367 | |||
368 | } // end of submenu | ||
369 | else if (str_key == "stylesdir" || str_key == "stylesmenu") { | ||
370 | createStyleMenu(menu, str_label, reloader, | ||
371 | str_key == "stylesmenu" ? str_cmd : str_label); | ||
372 | } // end of stylesdir | ||
373 | else if (str_key == "themesdir" || str_key == "themesmenu") { | ||
374 | createStyleMenu(menu, str_label, reloader, | ||
375 | str_key == "themesmenu" ? str_cmd : str_label); | ||
376 | } // end of themesdir | ||
377 | else if (str_key == "wallpapers" || str_key == "wallpapermenu" || | ||
378 | str_key == "rootcommands") { | ||
379 | createRootCmdMenu(menu, str_label, str_label, reloader, | ||
380 | str_cmd == "" ? realProgramName("fbsetbg") : str_cmd); | ||
381 | } // end of wallpapers | ||
382 | else if (str_key == "workspaces") { | ||
383 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); | ||
384 | if (screen != 0) { | ||
385 | screen->workspaceMenu().setInternalMenu(); | ||
386 | menu.insert(str_label, &screen->workspaceMenu()); | ||
387 | } | ||
388 | } else if (str_key == "separator") { | ||
389 | menu.insert(new FbTk::MenuSeparator()); | ||
390 | } else if (str_key == "encoding") { | ||
391 | startEncoding(str_cmd); | ||
392 | } else if (str_key == "endencoding") { | ||
393 | endEncoding(); | ||
394 | } else if (!MenuCreator::createWindowMenuItem(str_key, str_label, menu)) { | ||
395 | // if we didn't find any special menu item we try with command parser | ||
396 | // we need to attach command to arguments so command parser can parse it | ||
397 | string line = str_key + " " + str_cmd; | ||
398 | FbTk::RefCount<FbTk::Command<void> > command(FbTk::CommandParser<void>::instance().parse(line)); | ||
399 | if (command != 0) { | ||
400 | // special NLS default labels | ||
401 | if (str_label.empty()) { | ||
402 | if (str_key == "reconfig" || str_key == "reconfigure") { | ||
403 | menu.insert(_FB_XTEXT(Menu, Reconfigure, "Reload Config", "Reload all the configs"), command); | ||
404 | return; | ||
405 | } else if (str_key == "restart") { | ||
406 | menu.insert(_FB_XTEXT(Menu, Restart, "Restart", "Restart Command"), command); | ||
407 | return; | ||
408 | } | ||
409 | } | ||
410 | menu.insert(str_label, command); | ||
411 | } | ||
412 | } | ||
413 | if (menu.numberOfItems() != 0) { | ||
414 | FbTk::MenuItem *item = menu.find(menu.numberOfItems() - 1); | ||
415 | if (item != 0 && !pitem.icon().empty()) | ||
416 | item->setIcon(pitem.icon(), menu.screenNumber()); | ||
417 | } | 266 | } |
418 | } | 267 | } |
419 | 268 | ||
@@ -479,7 +328,8 @@ insertMenuItem(lua::state &l, FbMenu &menu, FbTk::StringConvertor &parent_conv, | |||
479 | const string &str_label = getField(l, -1, "label", conv); | 328 | const string &str_label = getField(l, -1, "label", conv); |
480 | const string &str_key = getField(l, -1, "type"); | 329 | const string &str_key = getField(l, -1, "type"); |
481 | const FbTk::CommandParser<void> &parser = FbTk::CommandParser<void>::instance(); | 330 | const FbTk::CommandParser<void> &parser = FbTk::CommandParser<void>::instance(); |
482 | BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); | 331 | int screen_number = menu.screenNumber(); |
332 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); | ||
483 | size_t old_size = menu.numberOfItems(); | 333 | size_t old_size = menu.numberOfItems(); |
484 | 334 | ||
485 | // first items that don't need additional parameters | 335 | // first items that don't need additional parameters |
@@ -489,7 +339,7 @@ insertMenuItem(lua::state &l, FbMenu &menu, FbTk::StringConvertor &parent_conv, | |||
489 | int size = menu.insert(str_label); | 339 | int size = menu.insert(str_label); |
490 | menu.setItemEnabled(size-1, false); | 340 | menu.setItemEnabled(size-1, false); |
491 | } else if(str_key == "icons") { | 341 | } else if(str_key == "icons") { |
492 | FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", menu.screenNumber()); | 342 | FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", screen_number); |
493 | if (submenu == 0) | 343 | if (submenu == 0) |
494 | return; | 344 | return; |
495 | if (str_label.empty()) | 345 | if (str_label.empty()) |
@@ -506,7 +356,7 @@ insertMenuItem(lua::state &l, FbMenu &menu, FbTk::StringConvertor &parent_conv, | |||
506 | menu.insert(str_label, &screen->configMenu()); | 356 | menu.insert(str_label, &screen->configMenu()); |
507 | } else if(str_key == "menu") { | 357 | } else if(str_key == "menu") { |
508 | l.pushvalue(-1); | 358 | l.pushvalue(-1); |
509 | menu.insert(str_label, createMenu_(l, menu.screenNumber(), *conv, reloader).release()); | 359 | menu.insert(str_label, createMenu_(l, screen_number, *conv, reloader).release()); |
510 | } else { | 360 | } else { |
511 | // items that have a parameter | 361 | // items that have a parameter |
512 | const string &str_cmd = getField(l, -1, "param"); | 362 | const string &str_cmd = getField(l, -1, "param"); |
@@ -520,14 +370,20 @@ insertMenuItem(lua::state &l, FbMenu &menu, FbTk::StringConvertor &parent_conv, | |||
520 | } else if(str_key == "style") | 370 | } else if(str_key == "style") |
521 | menu.insert(new StyleMenuItem(str_label, str_cmd)); | 371 | menu.insert(new StyleMenuItem(str_label, str_cmd)); |
522 | else if (str_key == "stylesdir") | 372 | else if (str_key == "stylesdir") |
523 | createStyleMenu(menu, str_label, reloader, str_cmd); | 373 | menu.insert(str_label, |
374 | createStyleMenu(screen_number, str_label, reloader, str_cmd).release()); | ||
524 | else if (str_key == "wallpapers") { | 375 | else if (str_key == "wallpapers") { |
525 | const string &program = getField(l, -1, "program"); | 376 | string program = getField(l, -1, "program"); |
526 | createRootCmdMenu(menu, str_label, str_cmd, reloader, | 377 | if(program.empty()) |
527 | program.empty() ? realProgramName("fbsetbg") : program); | 378 | program = realProgramName("fbsetbg"); |
379 | menu.insert(str_label, createRootCmdMenu(screen_number, str_label, str_cmd, | ||
380 | reloader, program).release() ); | ||
528 | } else if (str_key == "workspaces") { | 381 | } else if (str_key == "workspaces") { |
529 | /* screen->workspaceMenu().setInternalMenu(); | 382 | screen->workspaceMenu().setInternalMenu(); |
530 | menu.insert(str_label, &screen->workspaceMenu());*/ | 383 | menu.insert(str_label, &screen->workspaceMenu()); |
384 | } else { | ||
385 | // finally, try window-related commands | ||
386 | MenuCreator::createWindowMenuItem(str_key, str_label, menu); | ||
531 | } | 387 | } |
532 | } | 388 | } |
533 | 389 | ||