aboutsummaryrefslogtreecommitdiff
path: root/src/MenuCreator.cc
diff options
context:
space:
mode:
authorPavel Labath <pavelo@centrum.sk>2011-06-27 17:34:51 (GMT)
committerPavel Labath <pavelo@centrum.sk>2011-06-27 17:34:51 (GMT)
commit4ef496df68eb7c778e4624f924de7f93829b7ae0 (patch)
treed1aca8af94a5fbb5abac44173db5051117401dff /src/MenuCreator.cc
parentb08a5a2017764170706032e79ae0a8e95a928f25 (diff)
downloadfluxbox_pavel-4ef496df68eb7c778e4624f924de7f93829b7ae0.zip
fluxbox_pavel-4ef496df68eb7c778e4624f924de7f93829b7ae0.tar.bz2
A veeeery rough implementation of lua menu parsers
Diffstat (limited to 'src/MenuCreator.cc')
-rw-r--r--src/MenuCreator.cc151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc
index 74968e3..60669db 100644
--- a/src/MenuCreator.cc
+++ b/src/MenuCreator.cc
@@ -365,8 +365,159 @@ bool getStart(FbMenuParser &parser, string &label, FbTk::StringConvertor &labelc
365 return true; 365 return true;
366} 366}
367 367
368string getField(lua::state &l, int pos, const char *field, FbTk::StringConvertor *conv = NULL) {
369 lua::stack_sentry s(l);
370 l.checkstack(1);
371 _FB_USES_NLS;
372
373 string val;
374 l.rawgetfield(pos, field); {
375 if(l.isstring(-1))
376 val = l.tostring(-1);
377 else if(! l.isnil(-1)) {
378 fprintf(stderr, _FB_CONSOLETEXT(Menu, FieldNotString,
379 "Warning: Menu field %s is not a string", "One %s for field name.").c_str(),
380 field);
381 fputs("\n", stderr);
382 }
383 } l.pop();
384 return conv ? conv->recode(val) : val;
385}
386
387std::auto_ptr<FbMenu>
388createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv,
389 FbTk::AutoReloadHelper *reloader);
390
391void
392insertMenuItem(lua::state &l, FbMenu &menu, FbTk::StringConvertor &parent_conv,
393 FbTk::AutoReloadHelper *reloader) {
394 lua::stack_sentry s(l, -1);
395 l.checkstack(1);
396
397 if(l.type(-1) != lua::TTABLE)
398 throw std::runtime_error(_FB_CONSOLETEXT(Menu, MenuNotTable, "Warning: Menu is not a lua table", "Menu is not a lua table"));
399
400 // if menu specifies an encoding, create a convertor for it
401 std::auto_ptr<FbTk::StringConvertor> my_conv;
402
403 FbTk::StringConvertor *conv = &parent_conv;
404 const string &encoding = getField(l, -1, "encoding");
405 if(! encoding.empty()) {
406 my_conv.reset(new FbTk::StringConvertor(FbTk::StringConvertor::ToFbString));
407 conv = my_conv.get();
408 conv->setSource(encoding);
409 }
410
411 const string &str_label = getField(l, -1, "label", conv);
412 const string &str_key = getField(l, -1, "type");
413 const FbTk::CommandParser<void> &parser = FbTk::CommandParser<void>::instance();
414 BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber());
415 size_t old_size = menu.numberOfItems();
416
417 // first items that don't need additional parameters
418 if(str_key == "separator")
419 menu.insert(new FbTk::MenuSeparator());
420 else if(str_key == "nop") {
421 int size = menu.insert(str_label);
422 menu.setItemEnabled(size-1, false);
423 } else if(str_key == "icons") {
424 FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", menu.screenNumber());
425 if (submenu == 0)
426 return;
427 if (str_label.empty())
428 menu.insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), submenu);
429 else
430 menu.insert(str_label, submenu);
431 } else if (str_key == "exit") { // exit
432 FbTk::RefCount<FbTk::Command<void> > exit_cmd(FbTk::CommandParser<void>::instance().parse("exit"));
433 if (str_label.empty())
434 menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd);
435 else
436 menu.insert(str_label, exit_cmd);
437 } else if (str_key == "config") {
438 menu.insert(str_label, &screen->configMenu());
439 } else if(str_key == "menu") {
440 l.pushvalue(-1);
441 menu.insert(str_label, createMenu_(l, menu.screenNumber(), *conv, reloader).release());
442 } else {
443 // items that have a parameter
444 const string &str_cmd = getField(l, -1, "param");
445
446 if(str_key == "command") {
447 menu.insert(str_label, FbTk::RefCount<FbTk::Command<void> >(
448 parser.parse(str_cmd)) );
449 } else if(str_key == "exec") {
450 menu.insert(str_label, FbTk::RefCount<FbTk::Command<void> >(
451 parser.parse("exec", str_cmd)) );
452 } else if(str_key == "style")
453 menu.insert(new StyleMenuItem(str_label, str_cmd));
454 else if (str_key == "stylesdir")
455 createStyleMenu(menu, str_label, reloader, str_cmd);
456 else if (str_key == "wallpapers") {
457 const string &program = getField(l, -1, "program");
458 createRootCmdMenu(menu, str_label, str_cmd, reloader,
459 program.empty() ? realProgramName("fbsetbg") : program);
460 } else if (str_key == "workspaces") {
461/* screen->workspaceMenu().setInternalMenu();
462 menu.insert(str_label, &screen->workspaceMenu());*/
463 }
464 }
465
466 const string &icon = getField(l, -1, "icon");
467 if(! icon.empty()) {
468 while(old_size < menu.numberOfItems())
469 menu.find(old_size++)->setIcon(icon, menu.screenNumber());
470 }
471}
472
473std::auto_ptr<FbMenu>
474createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv,
475 FbTk::AutoReloadHelper *reloader) {
476
477 lua::stack_sentry s(l, -1);
478 l.checkstack(1);
479
480 std::auto_ptr<FbMenu> menu( MenuCreator::createMenu(getField(l, -1, "label", &conv),
481 screen_number) );
482
483 for(int i = 1; l.rawgeti(-1, i), !l.isnil(-1); ++i) {
484 try {
485 insertMenuItem(l, *menu, conv, reloader);
486 }
487 catch(std::runtime_error &e) {
488 cerr << e.what() << endl;
489 }
490 } l.pop();
491
492 l.pop();
493 return menu;
494}
495
368} // end of anonymous namespace 496} // end of anonymous namespace
369 497
498std::auto_ptr<FbMenu>
499MenuCreator::createMenu(lua::state &l, int screen_number, FbTk::AutoReloadHelper *reloader) {
500 lua::stack_sentry s(l, -1);
501 l.checkstack(1);
502
503 if(l.type(-1) != lua::TTABLE) {
504 cerr << _FB_CONSOLETEXT(Menu, MenuNotTable, "Warning: Menu is not a lua table",
505 "Menu is not a lua table") << endl;
506 return std::auto_ptr<FbMenu>();
507 }
508
509 std::auto_ptr<FbTk::StringConvertor> conv(new FbTk::StringConvertor(FbTk::StringConvertor::ToFbString));
510
511 // if menu specifies an encoding, create a convertor for it
512 l.rawgetfield(-1, "encoding"); {
513 if(l.isstring(-1))
514 conv->setSource(l.tostring(-1));
515 } l.pop();
516
517 return createMenu_(l, screen_number, *conv, reloader);
518}
519
520
370FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { 521FbMenu *MenuCreator::createMenu(const string &label, int screen_number) {
371 BScreen *screen = Fluxbox::instance()->findScreen(screen_number); 522 BScreen *screen = Fluxbox::instance()->findScreen(screen_number);
372 if (screen == 0) 523 if (screen == 0)