diff options
Diffstat (limited to 'src/MenuCreator.cc')
-rw-r--r-- | src/MenuCreator.cc | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc index 41dcf73..b944bcb 100644 --- a/src/MenuCreator.cc +++ b/src/MenuCreator.cc | |||
@@ -433,8 +433,159 @@ bool getStart(FbMenuParser &parser, string &label, FbTk::StringConvertor &labelc | |||
433 | return true; | 433 | return true; |
434 | } | 434 | } |
435 | 435 | ||
436 | string getField(lua::state &l, int pos, const char *field, FbTk::StringConvertor *conv = NULL) { | ||
437 | lua::stack_sentry s(l); | ||
438 | l.checkstack(1); | ||
439 | _FB_USES_NLS; | ||
440 | |||
441 | string val; | ||
442 | l.rawgetfield(pos, field); { | ||
443 | if(l.isstring(-1)) | ||
444 | val = l.tostring(-1); | ||
445 | else if(! l.isnil(-1)) { | ||
446 | fprintf(stderr, _FB_CONSOLETEXT(Menu, FieldNotString, | ||
447 | "Warning: Menu field %s is not a string", "One %s for field name.").c_str(), | ||
448 | field); | ||
449 | fputs("\n", stderr); | ||
450 | } | ||
451 | } l.pop(); | ||
452 | return conv ? conv->recode(val) : val; | ||
453 | } | ||
454 | |||
455 | std::auto_ptr<FbMenu> | ||
456 | createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv, | ||
457 | FbTk::AutoReloadHelper *reloader); | ||
458 | |||
459 | void | ||
460 | insertMenuItem(lua::state &l, FbMenu &menu, FbTk::StringConvertor &parent_conv, | ||
461 | FbTk::AutoReloadHelper *reloader) { | ||
462 | lua::stack_sentry s(l, -1); | ||
463 | l.checkstack(1); | ||
464 | |||
465 | if(l.type(-1) != lua::TTABLE) | ||
466 | throw std::runtime_error(_FB_CONSOLETEXT(Menu, MenuNotTable, "Warning: Menu is not a lua table", "Menu is not a lua table")); | ||
467 | |||
468 | // if menu specifies an encoding, create a convertor for it | ||
469 | std::auto_ptr<FbTk::StringConvertor> my_conv; | ||
470 | |||
471 | FbTk::StringConvertor *conv = &parent_conv; | ||
472 | const string &encoding = getField(l, -1, "encoding"); | ||
473 | if(! encoding.empty()) { | ||
474 | my_conv.reset(new FbTk::StringConvertor(FbTk::StringConvertor::ToFbString)); | ||
475 | conv = my_conv.get(); | ||
476 | conv->setSource(encoding); | ||
477 | } | ||
478 | |||
479 | const string &str_label = getField(l, -1, "label", conv); | ||
480 | const string &str_key = getField(l, -1, "type"); | ||
481 | const FbTk::CommandParser<void> &parser = FbTk::CommandParser<void>::instance(); | ||
482 | BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); | ||
483 | size_t old_size = menu.numberOfItems(); | ||
484 | |||
485 | // first items that don't need additional parameters | ||
486 | if(str_key == "separator") | ||
487 | menu.insert(new FbTk::MenuSeparator()); | ||
488 | else if(str_key == "nop") { | ||
489 | int size = menu.insert(str_label); | ||
490 | menu.setItemEnabled(size-1, false); | ||
491 | } else if(str_key == "icons") { | ||
492 | FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", menu.screenNumber()); | ||
493 | if (submenu == 0) | ||
494 | return; | ||
495 | if (str_label.empty()) | ||
496 | menu.insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), submenu); | ||
497 | else | ||
498 | menu.insert(str_label, submenu); | ||
499 | } else if (str_key == "exit") { // exit | ||
500 | FbTk::RefCount<FbTk::Command<void> > exit_cmd(FbTk::CommandParser<void>::instance().parse("exit")); | ||
501 | if (str_label.empty()) | ||
502 | menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd); | ||
503 | else | ||
504 | menu.insert(str_label, exit_cmd); | ||
505 | } else if (str_key == "config") { | ||
506 | menu.insert(str_label, &screen->configMenu()); | ||
507 | } else if(str_key == "menu") { | ||
508 | l.pushvalue(-1); | ||
509 | menu.insert(str_label, createMenu_(l, menu.screenNumber(), *conv, reloader).release()); | ||
510 | } else { | ||
511 | // items that have a parameter | ||
512 | const string &str_cmd = getField(l, -1, "param"); | ||
513 | |||
514 | if(str_key == "command") { | ||
515 | menu.insert(str_label, FbTk::RefCount<FbTk::Command<void> >( | ||
516 | parser.parse(str_cmd)) ); | ||
517 | } else if(str_key == "exec") { | ||
518 | menu.insert(str_label, FbTk::RefCount<FbTk::Command<void> >( | ||
519 | parser.parse("exec", str_cmd)) ); | ||
520 | } else if(str_key == "style") | ||
521 | menu.insert(new StyleMenuItem(str_label, str_cmd)); | ||
522 | else if (str_key == "stylesdir") | ||
523 | createStyleMenu(menu, str_label, reloader, str_cmd); | ||
524 | else if (str_key == "wallpapers") { | ||
525 | const string &program = getField(l, -1, "program"); | ||
526 | createRootCmdMenu(menu, str_label, str_cmd, reloader, | ||
527 | program.empty() ? realProgramName("fbsetbg") : program); | ||
528 | } else if (str_key == "workspaces") { | ||
529 | /* screen->workspaceMenu().setInternalMenu(); | ||
530 | menu.insert(str_label, &screen->workspaceMenu());*/ | ||
531 | } | ||
532 | } | ||
533 | |||
534 | const string &icon = getField(l, -1, "icon"); | ||
535 | if(! icon.empty()) { | ||
536 | while(old_size < menu.numberOfItems()) | ||
537 | menu.find(old_size++)->setIcon(icon, menu.screenNumber()); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | std::auto_ptr<FbMenu> | ||
542 | createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv, | ||
543 | FbTk::AutoReloadHelper *reloader) { | ||
544 | |||
545 | lua::stack_sentry s(l, -1); | ||
546 | l.checkstack(1); | ||
547 | |||
548 | std::auto_ptr<FbMenu> menu( MenuCreator::createMenu(getField(l, -1, "label", &conv), | ||
549 | screen_number) ); | ||
550 | |||
551 | for(int i = 1; l.rawgeti(-1, i), !l.isnil(-1); ++i) { | ||
552 | try { | ||
553 | insertMenuItem(l, *menu, conv, reloader); | ||
554 | } | ||
555 | catch(std::runtime_error &e) { | ||
556 | cerr << e.what() << endl; | ||
557 | } | ||
558 | } l.pop(); | ||
559 | |||
560 | l.pop(); | ||
561 | return menu; | ||
562 | } | ||
563 | |||
436 | } // end of anonymous namespace | 564 | } // end of anonymous namespace |
437 | 565 | ||
566 | std::auto_ptr<FbMenu> | ||
567 | MenuCreator::createMenu(lua::state &l, int screen_number, FbTk::AutoReloadHelper *reloader) { | ||
568 | lua::stack_sentry s(l, -1); | ||
569 | l.checkstack(1); | ||
570 | |||
571 | if(l.type(-1) != lua::TTABLE) { | ||
572 | cerr << _FB_CONSOLETEXT(Menu, MenuNotTable, "Warning: Menu is not a lua table", | ||
573 | "Menu is not a lua table") << endl; | ||
574 | return std::auto_ptr<FbMenu>(); | ||
575 | } | ||
576 | |||
577 | std::auto_ptr<FbTk::StringConvertor> conv(new FbTk::StringConvertor(FbTk::StringConvertor::ToFbString)); | ||
578 | |||
579 | // if menu specifies an encoding, create a convertor for it | ||
580 | l.rawgetfield(-1, "encoding"); { | ||
581 | if(l.isstring(-1)) | ||
582 | conv->setSource(l.tostring(-1)); | ||
583 | } l.pop(); | ||
584 | |||
585 | return createMenu_(l, screen_number, *conv, reloader); | ||
586 | } | ||
587 | |||
588 | |||
438 | FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { | 589 | FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { |
439 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); | 590 | BScreen *screen = Fluxbox::instance()->findScreen(screen_number); |
440 | if (screen == 0) | 591 | if (screen == 0) |