aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Labath <pavelo@centrum.sk>2011-06-27 17:34:51 (GMT)
committerPavel Labath <pavelo@centrum.sk>2011-11-01 09:57:20 (GMT)
commit16ec402647fd50126625c22c70d2faa89885d09f (patch)
tree2f852e820b132712cfa65f0236235cb59c6ba491
parenta247a342e6c352dfdb0bb16726a496a807065cda (diff)
downloadfluxbox_pavel-16ec402647fd50126625c22c70d2faa89885d09f.zip
fluxbox_pavel-16ec402647fd50126625c22c70d2faa89885d09f.tar.bz2
A veeeery rough implementation of lua menu parsers
-rw-r--r--src/FbTk/Menu.cc2
-rw-r--r--src/FbTk/Menu.hh2
-rw-r--r--src/FbTk/MenuItem.hh4
-rw-r--r--src/MenuCreator.cc151
-rw-r--r--src/MenuCreator.hh15
-rw-r--r--src/Screen.cc7
6 files changed, 172 insertions, 9 deletions
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc
index 40f81c8..e52b4dd 100644
--- a/src/FbTk/Menu.cc
+++ b/src/FbTk/Menu.cc
@@ -219,7 +219,7 @@ Menu::~Menu() {
219 s_focused = 0; 219 s_focused = 0;
220} 220}
221 221
222int Menu::insert(const FbString &label, RefCount<Command<void> > &cmd, int pos) { 222int Menu::insert(const FbString &label, const RefCount<Command<void> > &cmd, int pos) {
223 return insert(new MenuItem(label, cmd, this), pos); 223 return insert(new MenuItem(label, cmd, this), pos);
224} 224}
225 225
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh
index bd830b4..4096295 100644
--- a/src/FbTk/Menu.hh
+++ b/src/FbTk/Menu.hh
@@ -61,7 +61,7 @@ public:
61 */ 61 */
62 //@{ 62 //@{
63 /// add a menu item with a label and a command 63 /// add a menu item with a label and a command
64 int insert(const FbString &label, RefCount<Command<void> > &cmd, int pos=-1); 64 int insert(const FbString &label, const RefCount<Command<void> > &cmd, int pos=-1);
65 /// add empty menu item 65 /// add empty menu item
66 int insert(const FbString &label, int pos=-1); 66 int insert(const FbString &label, int pos=-1);
67 /// add submenu 67 /// add submenu
diff --git a/src/FbTk/MenuItem.hh b/src/FbTk/MenuItem.hh
index 2149559..cc24228 100644
--- a/src/FbTk/MenuItem.hh
+++ b/src/FbTk/MenuItem.hh
@@ -69,7 +69,7 @@ public:
69 m_toggle_item(false) 69 m_toggle_item(false)
70 { } 70 { }
71 /// create a menu item with a specific command to be executed on click 71 /// create a menu item with a specific command to be executed on click
72 MenuItem(const BiDiString &label, RefCount<Command<void> > &cmd, Menu *menu = 0) 72 MenuItem(const BiDiString &label, const RefCount<Command<void> > &cmd, Menu *menu = 0)
73 : m_label(label), 73 : m_label(label),
74 m_menu(menu), 74 m_menu(menu),
75 m_submenu(0), 75 m_submenu(0),
@@ -91,7 +91,7 @@ public:
91 { } 91 { }
92 virtual ~MenuItem() { } 92 virtual ~MenuItem() { }
93 93
94 void setCommand(RefCount<Command<void> > &cmd) { m_command = cmd; } 94 void setCommand(const RefCount<Command<void> > &cmd) { m_command = cmd; }
95 virtual void setSelected(bool selected) { m_selected = selected; } 95 virtual void setSelected(bool selected) { m_selected = selected; }
96 virtual void setEnabled(bool enabled) { m_enabled = enabled; } 96 virtual void setEnabled(bool enabled) { m_enabled = enabled; }
97 virtual void setLabel(const BiDiString &label) { m_label = label; } 97 virtual void setLabel(const BiDiString &label) { m_label = label; }
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
436string 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
455std::auto_ptr<FbMenu>
456createMenu_(lua::state &l, int screen_number, FbTk::StringConvertor &conv,
457 FbTk::AutoReloadHelper *reloader);
458
459void
460insertMenuItem(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
541std::auto_ptr<FbMenu>
542createMenu_(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
566std::auto_ptr<FbMenu>
567MenuCreator::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
438FbMenu *MenuCreator::createMenu(const string &label, int screen_number) { 589FbMenu *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)
diff --git a/src/MenuCreator.hh b/src/MenuCreator.hh
index 91add47..4329639 100644
--- a/src/MenuCreator.hh
+++ b/src/MenuCreator.hh
@@ -26,6 +26,11 @@
26#include "FbTk/FbString.hh" 26#include "FbTk/FbString.hh"
27 27
28#include <list> 28#include <list>
29#include <memory>
30
31namespace lua {
32class state;
33}
29 34
30namespace FbTk { 35namespace FbTk {
31class AutoReloadHelper; 36class AutoReloadHelper;
@@ -37,14 +42,16 @@ class FluxboxWindow;
37 42
38namespace MenuCreator { 43namespace MenuCreator {
39 44
45 std::auto_ptr<FbMenu>
46 createMenu(lua::state &l, int screen_number, FbTk::AutoReloadHelper *reloader = NULL);
40 FbMenu *createMenu(const std::string &label, int screen_num); 47 FbMenu *createMenu(const std::string &label, int screen_num);
41 FbMenu *createMenuType(const std::string &label, int screen_num); 48 FbMenu *createMenuType(const std::string &label, int screen_num);
42 bool createFromFile(const std::string &filename, 49 bool createFromFile(const std::string &filename,
43 FbTk::Menu &inject_into, 50 FbTk::Menu &inject_into,
44 FbTk::AutoReloadHelper *reloader = NULL, 51 FbTk::AutoReloadHelper *reloader = NULL,
45 bool begin = true); 52 bool begin = true);
46 bool createWindowMenuItem(const std::string &type, const std::string &label, 53 bool createWindowMenuItem(const std::string &type, const std::string &label,
47 FbTk::Menu &inject_into); 54 FbTk::Menu &inject_into);
48}; 55}
49 56
50#endif // MENUCREATOR_HH 57#endif // MENUCREATOR_HH
diff --git a/src/Screen.cc b/src/Screen.cc
index 8ce0528..4492092 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -1384,8 +1384,13 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id,
1384} 1384}
1385 1385
1386void BScreen::initMenus() { 1386void BScreen::initMenus() {
1387 lua::state &l = Fluxbox::instance()->lua();
1387 m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); 1388 m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber()));
1388 m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); 1389 l.loadfile(FbTk::StringUtil::expandFilename(Fluxbox::instance()->getMenuFilename()).c_str());
1390 l.call(0, 0);
1391 l.getglobal("menu");
1392 m_rootmenu = MenuCreator::createMenu(l, 0);
1393// m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename());
1389 m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename()); 1394 m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename());
1390} 1395}
1391 1396