diff options
Diffstat (limited to 'src/MenuCreator.cc')
-rw-r--r-- | src/MenuCreator.cc | 150 |
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; | |||
59 | using std::vector; | 59 | using std::vector; |
60 | using std::list; | 60 | using std::list; |
61 | using std::less; | 61 | using std::less; |
62 | using FbTk::AutoReloadHelper; | ||
62 | 63 | ||
63 | list<string> MenuCreator::encoding_stack; | 64 | list<string> MenuCreator::encoding_stack; |
64 | list<size_t> MenuCreator::stacksize_stack; | 65 | list<size_t> MenuCreator::stacksize_stack; |
@@ -68,13 +69,16 @@ FbTk::StringConvertor MenuCreator::m_stringconvertor(FbTk::StringConvertor::ToFb | |||
68 | namespace { | 69 | namespace { |
69 | 70 | ||
70 | void createStyleMenu(FbTk::Menu &parent, const string &label, | 71 | void 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 | ||
106 | void createRootCmdMenu(FbTk::Menu &parent, const string &label, | 109 | void 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 | ||
175 | void translateMenuItem(FbTk::Parser &parse, ParseItem &item, FbTk::StringConvertor &labelconvertor); | 181 | void translateMenuItem(FbTk::Parser &parse, ParseItem &item, |
182 | FbTk::StringConvertor &labelconvertor, | ||
183 | AutoReloadHelper *reloader); | ||
176 | 184 | ||
177 | 185 | ||
178 | void parseMenu(FbTk::Parser &pars, FbTk::Menu &menu, FbTk::StringConvertor &label_convertor) { | 186 | void 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 | ||
188 | void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConvertor &labelconvertor) { | 198 | void 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 | ||
342 | void parseWindowMenu(FbTk::Parser &parse, FbTk::Menu &menu, FbTk::StringConvertor &labelconvertor) { | 350 | void 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 | ||
383 | FbTk::Menu *MenuCreator::createMenu(const string &label, int screen_number) { | 393 | FbMenu *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 | ||
397 | FbTk::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 | |||
422 | bool MenuCreator::createFromFile(const string &filename, | 407 | bool 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 | ||
442 | bool MenuCreator::createWindowMenuFromFile(const string &filename, | 437 | void 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 | ||
464 | FbTk::Menu *MenuCreator::createMenuType(const string &type, int screen_num) { | 461 | FbMenu *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 | } |