aboutsummaryrefslogtreecommitdiff
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
parentb08a5a2017764170706032e79ae0a8e95a928f25 (diff)
downloadfluxbox_pavel-4ef496df68eb7c778e4624f924de7f93829b7ae0.zip
fluxbox_pavel-4ef496df68eb7c778e4624f924de7f93829b7ae0.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.hh7
-rw-r--r--src/Screen.cc7
6 files changed, 168 insertions, 5 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 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)
diff --git a/src/MenuCreator.hh b/src/MenuCreator.hh
index a9fb649..6c537de 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,6 +42,8 @@ class FluxboxWindow;
37 42
38class MenuCreator { 43class MenuCreator {
39public: 44public:
45 static std::auto_ptr<FbMenu>
46 createMenu(lua::state &l, int screen_number, FbTk::AutoReloadHelper *reloader = NULL);
40 static FbMenu *createMenu(const std::string &label, int screen_num); 47 static FbMenu *createMenu(const std::string &label, int screen_num);
41 static FbMenu *createMenuType(const std::string &label, int screen_num); 48 static FbMenu *createMenuType(const std::string &label, int screen_num);
42 static bool createFromFile(const std::string &filename, 49 static bool createFromFile(const std::string &filename,
diff --git a/src/Screen.cc b/src/Screen.cc
index 117cb29..f384476 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -1392,8 +1392,13 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id,
1392} 1392}
1393 1393
1394void BScreen::initMenus() { 1394void BScreen::initMenus() {
1395 lua::state &l = Fluxbox::instance()->lua();
1395 m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); 1396 m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber()));
1396 m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); 1397 l.loadfile(FbTk::StringUtil::expandFilename(Fluxbox::instance()->getMenuFilename()).c_str());
1398 l.call(0, 0);
1399 l.getglobal("menu");
1400 m_rootmenu = MenuCreator::createMenu(l, 0);
1401// m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename());
1397 m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename()); 1402 m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename());
1398} 1403}
1399 1404