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 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 | ||
368 | string 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 | |||
387 | std::auto_ptr<FbMenu> | ||
388 | createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv, | ||
389 | FbTk::AutoReloadHelper *reloader); | ||
390 | |||
391 | void | ||
392 | insertMenuItem(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 | |||
473 | std::auto_ptr<FbMenu> | ||
474 | createMenu_(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 | ||
498 | std::auto_ptr<FbMenu> | ||
499 | MenuCreator::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 | |||
370 | FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { | 521 | FbMenu *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) |