aboutsummaryrefslogtreecommitdiff
path: root/src/MenuCreator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/MenuCreator.cc')
-rw-r--r--src/MenuCreator.cc150
1 files changed, 60 insertions, 90 deletions
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc
index b420d3f..1af5482 100644
--- a/src/MenuCreator.cc
+++ b/src/MenuCreator.cc
@@ -59,6 +59,7 @@ using std::string;
59using std::vector; 59using std::vector;
60using std::list; 60using std::list;
61using std::less; 61using std::less;
62using FbTk::AutoReloadHelper;
62 63
63list<string> MenuCreator::encoding_stack; 64list<string> MenuCreator::encoding_stack;
64list<size_t> MenuCreator::stacksize_stack; 65list<size_t> MenuCreator::stacksize_stack;
@@ -68,13 +69,16 @@ FbTk::StringConvertor MenuCreator::m_stringconvertor(FbTk::StringConvertor::ToFb
68namespace { 69namespace {
69 70
70void createStyleMenu(FbTk::Menu &parent, const string &label, 71void createStyleMenu(FbTk::Menu &parent, const string &label,
71 const string &directory) { 72 AutoReloadHelper *reloader, const string &directory) {
72 // perform shell style ~ home directory expansion 73 // perform shell style ~ home directory expansion
73 string stylesdir(FbTk::StringUtil::expandFilename(directory)); 74 string stylesdir(FbTk::StringUtil::expandFilename(directory));
74 75
75 if (!FbTk::FileUtil::isDirectory(stylesdir.c_str())) 76 if (!FbTk::FileUtil::isDirectory(stylesdir.c_str()))
76 return; 77 return;
77 78
79 if (reloader)
80 reloader->addFile(stylesdir);
81
78 FbTk::Directory dir(stylesdir.c_str()); 82 FbTk::Directory dir(stylesdir.c_str());
79 83
80 // create a vector of all the filenames in the directory 84 // create a vector of all the filenames in the directory
@@ -99,18 +103,21 @@ void createStyleMenu(FbTk::Menu &parent, const string &label,
99 } 103 }
100 // update menu graphics 104 // update menu graphics
101 parent.updateMenu(); 105 parent.updateMenu();
102 Fluxbox::instance()->saveMenuFilename(stylesdir.c_str());
103 106
104} 107}
105 108
106void createRootCmdMenu(FbTk::Menu &parent, const string &label, 109void createRootCmdMenu(FbTk::Menu &parent, const string &label,
107 const string &directory, const string &cmd) { 110 const string &directory, AutoReloadHelper *reloader,
111 const string &cmd) {
108 // perform shell style ~ home directory expansion 112 // perform shell style ~ home directory expansion
109 string rootcmddir(FbTk::StringUtil::expandFilename(directory)); 113 string rootcmddir(FbTk::StringUtil::expandFilename(directory));
110 114
111 if (!FbTk::FileUtil::isDirectory(rootcmddir.c_str())) 115 if (!FbTk::FileUtil::isDirectory(rootcmddir.c_str()))
112 return; 116 return;
113 117
118 if (reloader)
119 reloader->addFile(rootcmddir);
120
114 FbTk::Directory dir(rootcmddir.c_str()); 121 FbTk::Directory dir(rootcmddir.c_str());
115 122
116 // create a vector of all the filenames in the directory 123 // create a vector of all the filenames in the directory
@@ -134,7 +141,6 @@ void createRootCmdMenu(FbTk::Menu &parent, const string &label,
134 } 141 }
135 // update menu graphics 142 // update menu graphics
136 parent.updateMenu(); 143 parent.updateMenu();
137 Fluxbox::instance()->saveMenuFilename(rootcmddir.c_str());
138 144
139} 145}
140 146
@@ -172,20 +178,26 @@ public:
172 178
173}; 179};
174 180
175void translateMenuItem(FbTk::Parser &parse, ParseItem &item, FbTk::StringConvertor &labelconvertor); 181void translateMenuItem(FbTk::Parser &parse, ParseItem &item,
182 FbTk::StringConvertor &labelconvertor,
183 AutoReloadHelper *reloader);
176 184
177 185
178void parseMenu(FbTk::Parser &pars, FbTk::Menu &menu, FbTk::StringConvertor &label_convertor) { 186void parseMenu(FbTk::Parser &pars, FbTk::Menu &menu,
187 FbTk::StringConvertor &label_convertor,
188 AutoReloadHelper *reloader) {
179 ParseItem pitem(&menu); 189 ParseItem pitem(&menu);
180 while (!pars.eof()) { 190 while (!pars.eof()) {
181 pitem.load(pars, label_convertor); 191 pitem.load(pars, label_convertor);
182 if (pitem.key() == "end") 192 if (pitem.key() == "end")
183 return; 193 return;
184 translateMenuItem(pars, pitem, label_convertor); 194 translateMenuItem(pars, pitem, label_convertor, reloader);
185 } 195 }
186} 196}
187 197
188void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConvertor &labelconvertor) { 198void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem,
199 FbTk::StringConvertor &labelconvertor,
200 AutoReloadHelper *reloader) {
189 if (pitem.menu() == 0) 201 if (pitem.menu() == 0)
190 throw string("translateMenuItem: We must have a menu in ParseItem!"); 202 throw string("translateMenuItem: We must have a menu in ParseItem!");
191 203
@@ -255,13 +267,13 @@ void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConver
255 if (FbTk::FileUtil::isRegularFile(thisfile.c_str()) && 267 if (FbTk::FileUtil::isRegularFile(thisfile.c_str()) &&
256 (filelist[file_index][0] != '.') && 268 (filelist[file_index][0] != '.') &&
257 (thisfile[thisfile.length() - 1] != '~')) { 269 (thisfile[thisfile.length() - 1] != '~')) {
258 MenuCreator::createFromFile(thisfile, menu); 270 MenuCreator::createFromFile(thisfile, menu, reloader, false);
259 } 271 }
260 } 272 }
261 273
262 } else { 274 } else {
263 // inject this file into the current menu 275 // inject this file into the current menu
264 MenuCreator::createFromFile(newfile, menu); 276 MenuCreator::createFromFile(newfile, menu, reloader, false);
265 } 277 }
266 278
267 safe_counter--; 279 safe_counter--;
@@ -278,26 +290,22 @@ void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConver
278 else 290 else
279 submenu->setLabel(str_label); 291 submenu->setLabel(str_label);
280 292
281 parseMenu(parse, *submenu, labelconvertor); 293 parseMenu(parse, *submenu, labelconvertor, reloader);
282 submenu->updateMenu(); 294 submenu->updateMenu();
283 menu.insert(str_label, submenu); 295 menu.insert(str_label, submenu);
284 // save to screen list so we can delete it later
285 BScreen *screen = Fluxbox::instance()->findScreen(screen_number);
286 if (screen != 0)
287 screen->saveMenu(*submenu);
288 296
289 } // end of submenu 297 } // end of submenu
290 else if (str_key == "stylesdir" || str_key == "stylesmenu") { 298 else if (str_key == "stylesdir" || str_key == "stylesmenu") {
291 createStyleMenu(menu, str_label, 299 createStyleMenu(menu, str_label, reloader,
292 str_key == "stylesmenu" ? str_cmd : str_label); 300 str_key == "stylesmenu" ? str_cmd : str_label);
293 } // end of stylesdir 301 } // end of stylesdir
294 else if (str_key == "themesdir" || str_key == "themesmenu") { 302 else if (str_key == "themesdir" || str_key == "themesmenu") {
295 createStyleMenu(menu, str_label, 303 createStyleMenu(menu, str_label, reloader,
296 str_key == "themesmenu" ? str_cmd : str_label); 304 str_key == "themesmenu" ? str_cmd : str_label);
297 } // end of themesdir 305 } // end of themesdir
298 else if (str_key == "wallpapers" || str_key == "wallpapermenu" || 306 else if (str_key == "wallpapers" || str_key == "wallpapermenu" ||
299 str_key == "rootcommands") { 307 str_key == "rootcommands") {
300 createRootCmdMenu(menu, str_label, str_label, 308 createRootCmdMenu(menu, str_label, str_label, reloader,
301 str_cmd == "" ? realProgramName("fbsetbg") : str_cmd); 309 str_cmd == "" ? realProgramName("fbsetbg") : str_cmd);
302 } // end of wallpapers 310 } // end of wallpapers
303 else if (str_key == "workspaces") { 311 else if (str_key == "workspaces") {
@@ -339,7 +347,9 @@ void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConver
339} 347}
340 348
341 349
342void parseWindowMenu(FbTk::Parser &parse, FbTk::Menu &menu, FbTk::StringConvertor &labelconvertor) { 350void parseWindowMenu(FbTk::Parser &parse, FbTk::Menu &menu,
351 FbTk::StringConvertor &labelconvertor,
352 AutoReloadHelper *reloader) {
343 353
344 ParseItem pitem(&menu); 354 ParseItem pitem(&menu);
345 while (!parse.eof()) { 355 while (!parse.eof()) {
@@ -347,16 +357,16 @@ void parseWindowMenu(FbTk::Parser &parse, FbTk::Menu &menu, FbTk::StringConverto
347 if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu)) 357 if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu))
348 continue; 358 continue;
349 359
350 if (pitem.key() == "end") { 360 if (pitem.key() == "end")
351 return; 361 return;
352 } else if (pitem.key() == "submenu") { 362 if (pitem.key() == "submenu") {
353 FbTk::Menu *submenu = MenuCreator::createMenu(pitem.label(), menu.screenNumber()); 363 FbTk::Menu *submenu = MenuCreator::createMenu(pitem.label(), menu.screenNumber());
354 parseWindowMenu(parse, *submenu, labelconvertor); 364 parseWindowMenu(parse, *submenu, labelconvertor, reloader);
355 submenu->updateMenu(); 365 submenu->updateMenu();
356 menu.insert(pitem.label(), submenu); 366 menu.insert(pitem.label(), submenu);
357 367
358 } else { // try non window menu specific stuff 368 } else { // try non window menu specific stuff
359 translateMenuItem(parse, pitem, labelconvertor); 369 translateMenuItem(parse, pitem, labelconvertor, reloader);
360 } 370 }
361 } 371 }
362} 372}
@@ -380,12 +390,12 @@ bool getStart(FbMenuParser &parser, string &label, FbTk::StringConvertor &labelc
380 390
381}; // end of anonymous namespace 391}; // end of anonymous namespace
382 392
383FbTk::Menu *MenuCreator::createMenu(const string &label, int screen_number) { 393FbMenu *MenuCreator::createMenu(const string &label, int screen_number) {
384 BScreen *screen = Fluxbox::instance()->findScreen(screen_number); 394 BScreen *screen = Fluxbox::instance()->findScreen(screen_number);
385 if (screen == 0) 395 if (screen == 0)
386 return 0; 396 return 0;
387 397
388 FbTk::Menu *menu = new FbMenu(screen->menuTheme(), 398 FbMenu *menu = new FbMenu(screen->menuTheme(),
389 screen->imageControl(), 399 screen->imageControl(),
390 *screen->layerManager().getLayer(Layer::MENU)); 400 *screen->layerManager().getLayer(Layer::MENU));
391 if (!label.empty()) 401 if (!label.empty())
@@ -394,33 +404,9 @@ FbTk::Menu *MenuCreator::createMenu(const string &label, int screen_number) {
394 return menu; 404 return menu;
395} 405}
396 406
397FbTk::Menu *MenuCreator::createFromFile(const string &filename, int screen_number) {
398 string real_filename = FbTk::StringUtil::expandFilename(filename);
399 Fluxbox::instance()->saveMenuFilename(real_filename.c_str());
400
401 FbMenuParser parser(real_filename);
402 if (!parser.isLoaded())
403 return 0;
404
405 startFile();
406 string label;
407 if (!getStart(parser, label, m_stringconvertor)) {
408 endFile();
409 return 0;
410 }
411
412 FbTk::Menu *menu = createMenu(label, screen_number);
413 if (menu != 0)
414 parseMenu(parser, *menu, m_stringconvertor);
415
416 endFile();
417
418 return menu;
419}
420
421
422bool MenuCreator::createFromFile(const string &filename, 407bool MenuCreator::createFromFile(const string &filename,
423 FbTk::Menu &inject_into) { 408 FbTk::Menu &inject_into,
409 AutoReloadHelper *reloader, bool begin) {
424 string real_filename = FbTk::StringUtil::expandFilename(filename); 410 string real_filename = FbTk::StringUtil::expandFilename(filename);
425 411
426 FbMenuParser parser(real_filename); 412 FbMenuParser parser(real_filename);
@@ -428,75 +414,59 @@ bool MenuCreator::createFromFile(const string &filename,
428 return false; 414 return false;
429 415
430 startFile(); 416 startFile();
417 if (begin) {
418 string label;
419 if (!getStart(parser, label, m_stringconvertor)) {
420 endFile();
421 return false;
422 }
423 inject_into.setLabel(label);
424 }
431 425
432 // save menu filename, so we can check if it changes 426 // save menu filename, so we can check if it changes
433 Fluxbox::instance()->saveMenuFilename(real_filename.c_str()); 427 if (reloader)
428 reloader->addFile(real_filename);
434 429
435 parseMenu(parser, inject_into, m_stringconvertor); 430 parseMenu(parser, inject_into, m_stringconvertor, reloader);
436 endFile(); 431 endFile();
437 432
438 return true; 433 return true;
439} 434}
440 435
441 436
442bool MenuCreator::createWindowMenuFromFile(const string &filename, 437void MenuCreator::createWindowMenuFromFile(const string &filename,
443 FbTk::Menu &inject_into) { 438 FbTk::Menu &inject_into,
439 AutoReloadHelper *reloader) {
444 string real_filename = FbTk::StringUtil::expandFilename(filename); 440 string real_filename = FbTk::StringUtil::expandFilename(filename);
445 FbMenuParser parser(real_filename); 441 FbMenuParser parser(real_filename);
446 if (!parser.isLoaded()) 442 if (!parser.isLoaded())
447 return false; 443 return;
448 444
449 string label; 445 string label;
450 446
451 startFile(); 447 startFile();
452 if (!getStart(parser, label, m_stringconvertor)) { 448 if (!getStart(parser, label, m_stringconvertor)) {
453 endFile(); 449 endFile();
454 return false; 450 return;
455 } 451 }
456 452
457 parseWindowMenu(parser, inject_into, m_stringconvertor); 453 if (reloader)
458 endFile(); 454 reloader->addFile(real_filename);
459 455
460 return true; 456 parseWindowMenu(parser, inject_into, m_stringconvertor, reloader);
457 endFile();
461} 458}
462 459
463 460
464FbTk::Menu *MenuCreator::createMenuType(const string &type, int screen_num) { 461FbMenu *MenuCreator::createMenuType(const string &type, int screen_num) {
465 BScreen *screen = Fluxbox::instance()->findScreen(screen_num); 462 BScreen *screen = Fluxbox::instance()->findScreen(screen_num);
466 if (screen == 0) 463 if (screen == 0)
467 return 0; 464 return 0;
468 if (type == "iconmenu") { 465 if (type == "iconmenu")
469 return new ClientMenu(*screen, screen->iconList(), 466 return new ClientMenu(*screen, screen->iconList(),
470 &screen->iconListSig()); 467 &screen->iconListSig());
471 } else if (type == "workspacemenu") { 468 else if (type == "workspacemenu")
472 return new WorkspaceMenu(*screen); 469 return new WorkspaceMenu(*screen);
473 } else if (type == "windowmenu") {
474 FbTk::Menu *menu = screen->createMenu("");
475
476 menu->disableTitle(); // not titlebar
477 if (screen->windowMenuFilename().empty() ||
478 ! createWindowMenuFromFile(screen->windowMenuFilename(), *menu)) {
479 const char *default_menu[] = {
480 "shade",
481 "stick",
482 "maximize",
483 "iconify",
484 "raise",
485 "lower",
486 "sendto",
487 "layer",
488 "alpha",
489 "extramenus",
490 "separator",
491 "close",
492 0
493 };
494 for (unsigned int i=0; default_menu[i]; ++i)
495 createWindowMenuItem(default_menu[i], "", *menu);
496 }
497 menu->reconfigure(); // update graphics
498 return menu;
499 }
500 470
501 return 0; 471 return 0;
502} 472}