aboutsummaryrefslogtreecommitdiff
path: root/src/MenuCreator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/MenuCreator.cc')
-rw-r--r--src/MenuCreator.cc113
1 files changed, 52 insertions, 61 deletions
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc
index 25f99ca..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, false); 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, false); 276 MenuCreator::createFromFile(newfile, menu, reloader, false);
265 } 277 }
266 278
267 safe_counter--; 279 safe_counter--;
@@ -278,22 +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 296
285 } // end of submenu 297 } // end of submenu
286 else if (str_key == "stylesdir" || str_key == "stylesmenu") { 298 else if (str_key == "stylesdir" || str_key == "stylesmenu") {
287 createStyleMenu(menu, str_label, 299 createStyleMenu(menu, str_label, reloader,
288 str_key == "stylesmenu" ? str_cmd : str_label); 300 str_key == "stylesmenu" ? str_cmd : str_label);
289 } // end of stylesdir 301 } // end of stylesdir
290 else if (str_key == "themesdir" || str_key == "themesmenu") { 302 else if (str_key == "themesdir" || str_key == "themesmenu") {
291 createStyleMenu(menu, str_label, 303 createStyleMenu(menu, str_label, reloader,
292 str_key == "themesmenu" ? str_cmd : str_label); 304 str_key == "themesmenu" ? str_cmd : str_label);
293 } // end of themesdir 305 } // end of themesdir
294 else if (str_key == "wallpapers" || str_key == "wallpapermenu" || 306 else if (str_key == "wallpapers" || str_key == "wallpapermenu" ||
295 str_key == "rootcommands") { 307 str_key == "rootcommands") {
296 createRootCmdMenu(menu, str_label, str_label, 308 createRootCmdMenu(menu, str_label, str_label, reloader,
297 str_cmd == "" ? realProgramName("fbsetbg") : str_cmd); 309 str_cmd == "" ? realProgramName("fbsetbg") : str_cmd);
298 } // end of wallpapers 310 } // end of wallpapers
299 else if (str_key == "workspaces") { 311 else if (str_key == "workspaces") {
@@ -335,7 +347,9 @@ void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConver
335} 347}
336 348
337 349
338void 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) {
339 353
340 ParseItem pitem(&menu); 354 ParseItem pitem(&menu);
341 while (!parse.eof()) { 355 while (!parse.eof()) {
@@ -343,16 +357,16 @@ void parseWindowMenu(FbTk::Parser &parse, FbTk::Menu &menu, FbTk::StringConverto
343 if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu)) 357 if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu))
344 continue; 358 continue;
345 359
346 if (pitem.key() == "end") { 360 if (pitem.key() == "end")
347 return; 361 return;
348 } else if (pitem.key() == "submenu") { 362 if (pitem.key() == "submenu") {
349 FbTk::Menu *submenu = MenuCreator::createMenu(pitem.label(), menu.screenNumber()); 363 FbTk::Menu *submenu = MenuCreator::createMenu(pitem.label(), menu.screenNumber());
350 parseWindowMenu(parse, *submenu, labelconvertor); 364 parseWindowMenu(parse, *submenu, labelconvertor, reloader);
351 submenu->updateMenu(); 365 submenu->updateMenu();
352 menu.insert(pitem.label(), submenu); 366 menu.insert(pitem.label(), submenu);
353 367
354 } else { // try non window menu specific stuff 368 } else { // try non window menu specific stuff
355 translateMenuItem(parse, pitem, labelconvertor); 369 translateMenuItem(parse, pitem, labelconvertor, reloader);
356 } 370 }
357 } 371 }
358} 372}
@@ -376,12 +390,12 @@ bool getStart(FbMenuParser &parser, string &label, FbTk::StringConvertor &labelc
376 390
377}; // end of anonymous namespace 391}; // end of anonymous namespace
378 392
379FbTk::Menu *MenuCreator::createMenu(const string &label, int screen_number) { 393FbMenu *MenuCreator::createMenu(const string &label, int screen_number) {
380 BScreen *screen = Fluxbox::instance()->findScreen(screen_number); 394 BScreen *screen = Fluxbox::instance()->findScreen(screen_number);
381 if (screen == 0) 395 if (screen == 0)
382 return 0; 396 return 0;
383 397
384 FbTk::Menu *menu = new FbMenu(screen->menuTheme(), 398 FbMenu *menu = new FbMenu(screen->menuTheme(),
385 screen->imageControl(), 399 screen->imageControl(),
386 *screen->layerManager().getLayer(Layer::MENU)); 400 *screen->layerManager().getLayer(Layer::MENU));
387 if (!label.empty()) 401 if (!label.empty())
@@ -391,7 +405,8 @@ FbTk::Menu *MenuCreator::createMenu(const string &label, int screen_number) {
391} 405}
392 406
393bool MenuCreator::createFromFile(const string &filename, 407bool MenuCreator::createFromFile(const string &filename,
394 FbTk::Menu &inject_into, bool begin) { 408 FbTk::Menu &inject_into,
409 AutoReloadHelper *reloader, bool begin) {
395 string real_filename = FbTk::StringUtil::expandFilename(filename); 410 string real_filename = FbTk::StringUtil::expandFilename(filename);
396 411
397 FbMenuParser parser(real_filename); 412 FbMenuParser parser(real_filename);
@@ -409,73 +424,49 @@ bool MenuCreator::createFromFile(const string &filename,
409 } 424 }
410 425
411 // save menu filename, so we can check if it changes 426 // save menu filename, so we can check if it changes
412 Fluxbox::instance()->saveMenuFilename(real_filename.c_str()); 427 if (reloader)
428 reloader->addFile(real_filename);
413 429
414 parseMenu(parser, inject_into, m_stringconvertor); 430 parseMenu(parser, inject_into, m_stringconvertor, reloader);
415 endFile(); 431 endFile();
416 432
417 return true; 433 return true;
418} 434}
419 435
420 436
421bool MenuCreator::createWindowMenuFromFile(const string &filename, 437void MenuCreator::createWindowMenuFromFile(const string &filename,
422 FbTk::Menu &inject_into) { 438 FbTk::Menu &inject_into,
439 AutoReloadHelper *reloader) {
423 string real_filename = FbTk::StringUtil::expandFilename(filename); 440 string real_filename = FbTk::StringUtil::expandFilename(filename);
424 FbMenuParser parser(real_filename); 441 FbMenuParser parser(real_filename);
425 if (!parser.isLoaded()) 442 if (!parser.isLoaded())
426 return false; 443 return;
427 444
428 string label; 445 string label;
429 446
430 startFile(); 447 startFile();
431 if (!getStart(parser, label, m_stringconvertor)) { 448 if (!getStart(parser, label, m_stringconvertor)) {
432 endFile(); 449 endFile();
433 return false; 450 return;
434 } 451 }
435 452
436 parseWindowMenu(parser, inject_into, m_stringconvertor); 453 if (reloader)
437 endFile(); 454 reloader->addFile(real_filename);
438 455
439 return true; 456 parseWindowMenu(parser, inject_into, m_stringconvertor, reloader);
457 endFile();
440} 458}
441 459
442 460
443FbTk::Menu *MenuCreator::createMenuType(const string &type, int screen_num) { 461FbMenu *MenuCreator::createMenuType(const string &type, int screen_num) {
444 BScreen *screen = Fluxbox::instance()->findScreen(screen_num); 462 BScreen *screen = Fluxbox::instance()->findScreen(screen_num);
445 if (screen == 0) 463 if (screen == 0)
446 return 0; 464 return 0;
447 if (type == "iconmenu") { 465 if (type == "iconmenu")
448 return new ClientMenu(*screen, screen->iconList(), 466 return new ClientMenu(*screen, screen->iconList(),
449 &screen->iconListSig()); 467 &screen->iconListSig());
450 } else if (type == "workspacemenu") { 468 else if (type == "workspacemenu")
451 return new WorkspaceMenu(*screen); 469 return new WorkspaceMenu(*screen);
452 } else if (type == "windowmenu") {
453 FbTk::Menu *menu = createMenu("", screen_num);
454
455 menu->disableTitle(); // not titlebar
456 if (screen->windowMenuFilename().empty() ||
457 ! createWindowMenuFromFile(screen->windowMenuFilename(), *menu)) {
458 const char *default_menu[] = {
459 "shade",
460 "stick",
461 "maximize",
462 "iconify",
463 "raise",
464 "lower",
465 "sendto",
466 "layer",
467 "alpha",
468 "extramenus",
469 "separator",
470 "close",
471 0
472 };
473 for (unsigned int i=0; default_menu[i]; ++i)
474 createWindowMenuItem(default_menu[i], "", *menu);
475 }
476 menu->reconfigure(); // update graphics
477 return menu;
478 }
479 470
480 return 0; 471 return 0;
481} 472}