diff options
Diffstat (limited to 'src/FbCommandFactory.cc')
-rw-r--r-- | src/FbCommandFactory.cc | 192 |
1 files changed, 166 insertions, 26 deletions
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc index ce024eb..92099f2 100644 --- a/src/FbCommandFactory.cc +++ b/src/FbCommandFactory.cc | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "Screen.hh" | 34 | #include "Screen.hh" |
35 | 35 | ||
36 | #include "FbTk/StringUtil.hh" | 36 | #include "FbTk/StringUtil.hh" |
37 | #include "FbTk/LogicCommands.hh" | ||
37 | #include "FbTk/MacroCommand.hh" | 38 | #include "FbTk/MacroCommand.hh" |
38 | #include "FbTk/stringstream.hh" | 39 | #include "FbTk/stringstream.hh" |
39 | 40 | ||
@@ -50,6 +51,10 @@ using std::vector; | |||
50 | using std::cerr; | 51 | using std::cerr; |
51 | using std::endl; | 52 | using std::endl; |
52 | 53 | ||
54 | using namespace FbTk; | ||
55 | using FbTk::StringUtil::removeFirstWhitespace; | ||
56 | using FbTk::StringUtil::toLower; | ||
57 | |||
53 | // autoregister this module to command parser | 58 | // autoregister this module to command parser |
54 | FbCommandFactory FbCommandFactory::s_autoreg; | 59 | FbCommandFactory FbCommandFactory::s_autoreg; |
55 | 60 | ||
@@ -60,6 +65,109 @@ static int getint(const char *str, int defaultvalue) { | |||
60 | return defaultvalue; | 65 | return defaultvalue; |
61 | } | 66 | } |
62 | 67 | ||
68 | BoolCommand *parseBoolCommand(string &line, bool trusted) { | ||
69 | // parse arguments and command | ||
70 | string command = line; | ||
71 | string arguments; | ||
72 | string::size_type first_pos = removeFirstWhitespace(command); | ||
73 | FbTk::StringUtil::removeTrailingWhitespace(command); | ||
74 | string::size_type second_pos = command.find_first_of(" \t", first_pos); | ||
75 | if (second_pos != string::npos) { | ||
76 | // ok we have arguments, parsing them here | ||
77 | arguments = command.substr(second_pos); | ||
78 | removeFirstWhitespace(arguments); | ||
79 | command.erase(second_pos); // remove argument from command | ||
80 | } | ||
81 | |||
82 | // now we have parsed command and arguments | ||
83 | command = toLower(command); | ||
84 | |||
85 | if (command == "matches") { | ||
86 | return new MatchCmd(arguments); | ||
87 | } else if (command == "some") { | ||
88 | BoolCommand *boolcmd = parseBoolCommand(arguments, trusted); | ||
89 | if (!boolcmd) | ||
90 | return 0; | ||
91 | return new SomeCmd(RefCount<BoolCommand>(boolcmd)); | ||
92 | } else if (command == "every") { | ||
93 | BoolCommand *boolcmd = parseBoolCommand(arguments, trusted); | ||
94 | if (!boolcmd) | ||
95 | return 0; | ||
96 | return new EveryCmd(RefCount<BoolCommand>(boolcmd)); | ||
97 | } else if (command == "not") { | ||
98 | BoolCommand *boolcmd = parseBoolCommand(arguments, trusted); | ||
99 | if (!boolcmd) | ||
100 | return 0; | ||
101 | RefCount<BoolCommand> ref(boolcmd); | ||
102 | return new NotCommand(ref); | ||
103 | } else if (command == "and") { | ||
104 | int pos = 0, err = 0; | ||
105 | AndCommand *andcmd = new AndCommand(); | ||
106 | string cmd; | ||
107 | |||
108 | while (true) { | ||
109 | RefCount<BoolCommand> tmp(0); | ||
110 | err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos, | ||
111 | '{', '}', " \t\n", true); | ||
112 | pos += err; | ||
113 | if (err == 0) | ||
114 | break; | ||
115 | |||
116 | tmp = parseBoolCommand(cmd, trusted); | ||
117 | if (*tmp) | ||
118 | andcmd->add(tmp); | ||
119 | } | ||
120 | |||
121 | if (andcmd->size() > 0) | ||
122 | return andcmd; | ||
123 | delete andcmd; | ||
124 | } else if (command == "or") { | ||
125 | int pos = 0, err = 0; | ||
126 | OrCommand *orcmd = new OrCommand(); | ||
127 | string cmd; | ||
128 | |||
129 | while (true) { | ||
130 | RefCount<BoolCommand> tmp(0); | ||
131 | err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos, | ||
132 | '{', '}', " \t\n", true); | ||
133 | pos += err; | ||
134 | if (err == 0) | ||
135 | break; | ||
136 | |||
137 | tmp = parseBoolCommand(cmd, trusted); | ||
138 | if (*tmp) | ||
139 | orcmd->add(tmp); | ||
140 | } | ||
141 | |||
142 | if (orcmd->size() > 0) | ||
143 | return orcmd; | ||
144 | delete orcmd; | ||
145 | } else if (command == "xor") { | ||
146 | int pos = 0, err = 0; | ||
147 | XorCommand *xorcmd = new XorCommand(); | ||
148 | string cmd; | ||
149 | |||
150 | while (true) { | ||
151 | RefCount<BoolCommand> tmp(0); | ||
152 | err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos, | ||
153 | '{', '}', " \t\n", true); | ||
154 | pos += err; | ||
155 | if (err == 0) | ||
156 | break; | ||
157 | |||
158 | tmp = parseBoolCommand(cmd, trusted); | ||
159 | if (*tmp) | ||
160 | xorcmd->add(tmp); | ||
161 | } | ||
162 | |||
163 | if (xorcmd->size() > 0) | ||
164 | return xorcmd; | ||
165 | delete xorcmd; | ||
166 | } | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
63 | }; // end anonymous namespace | 171 | }; // end anonymous namespace |
64 | 172 | ||
65 | FbCommandFactory::FbCommandFactory() { | 173 | FbCommandFactory::FbCommandFactory() { |
@@ -74,6 +182,7 @@ FbCommandFactory::FbCommandFactory() { | |||
74 | "close", | 182 | "close", |
75 | "closeallwindows", | 183 | "closeallwindows", |
76 | "commanddialog", | 184 | "commanddialog", |
185 | "cond", | ||
77 | "custommenu", | 186 | "custommenu", |
78 | "deiconify", | 187 | "deiconify", |
79 | "detachclient", | 188 | "detachclient", |
@@ -91,6 +200,7 @@ FbCommandFactory::FbCommandFactory() { | |||
91 | "gotowindow", | 200 | "gotowindow", |
92 | "hidemenus", | 201 | "hidemenus", |
93 | "iconify", | 202 | "iconify", |
203 | "if", | ||
94 | "keymode", | 204 | "keymode", |
95 | "kill", | 205 | "kill", |
96 | "killwindow", | 206 | "killwindow", |
@@ -246,15 +356,15 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
246 | // Current focused window commands | 356 | // Current focused window commands |
247 | // | 357 | // |
248 | else if (command == "fullscreen") | 358 | else if (command == "fullscreen") |
249 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new FullscreenCmd()), arguments); | 359 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new FullscreenCmd()), arguments); |
250 | else if (command == "minimizewindow" || command == "minimize" || command == "iconify") | 360 | else if (command == "minimizewindow" || command == "minimize" || command == "iconify") |
251 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments); | 361 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments); |
252 | else if (command == "maximizewindow" || command == "maximize") | 362 | else if (command == "maximizewindow" || command == "maximize") |
253 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments); | 363 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments); |
254 | else if (command == "maximizevertical") | 364 | else if (command == "maximizevertical") |
255 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments); | 365 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments); |
256 | else if (command == "maximizehorizontal") | 366 | else if (command == "maximizehorizontal") |
257 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments); | 367 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments); |
258 | else if (command == "setalpha") { | 368 | else if (command == "setalpha") { |
259 | typedef vector<string> StringTokens; | 369 | typedef vector<string> StringTokens; |
260 | StringTokens tokens; | 370 | StringTokens tokens; |
@@ -281,7 +391,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
281 | if (pos != string::npos && pos != arguments.size()) | 391 | if (pos != string::npos && pos != arguments.size()) |
282 | pat = arguments.c_str() + pos; | 392 | pat = arguments.c_str() + pos; |
283 | 393 | ||
284 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new SetAlphaCmd(focused, relative, unfocused, un_rel)), pat); | 394 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new SetAlphaCmd(focused, relative, unfocused, un_rel)), pat); |
285 | } else if (command == "startmoving") | 395 | } else if (command == "startmoving") |
286 | return new StartMovingCmd(); | 396 | return new StartMovingCmd(); |
287 | else if (command == "startresizing") { | 397 | else if (command == "startresizing") { |
@@ -331,7 +441,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
331 | if (pos != string::npos && pos != arguments.size()) | 441 | if (pos != string::npos && pos != arguments.size()) |
332 | pat = arguments.c_str() + pos; | 442 | pat = arguments.c_str() + pos; |
333 | 443 | ||
334 | FbTk::RefCount<WindowHelperCmd> cmd; | 444 | FbTk::RefCount<FbTk::Command> cmd; |
335 | if (command == "resizeto") | 445 | if (command == "resizeto") |
336 | cmd = new ResizeToCmd(dx, dy); | 446 | cmd = new ResizeToCmd(dx, dy); |
337 | else | 447 | else |
@@ -386,7 +496,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
386 | if (pos != string::npos && pos != arguments.size()) | 496 | if (pos != string::npos && pos != arguments.size()) |
387 | pat = arguments.c_str() + pos; | 497 | pat = arguments.c_str() + pos; |
388 | 498 | ||
389 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new MoveToCmd(dx, dy, refc)), pat); | 499 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveToCmd(dx, dy, refc)), pat); |
390 | } else if (command == "move" || command == "moveright" || | 500 | } else if (command == "move" || command == "moveright" || |
391 | command == "moveleft" || command == "moveup" || | 501 | command == "moveleft" || command == "moveup" || |
392 | command == "movedown") { | 502 | command == "movedown") { |
@@ -412,29 +522,29 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
412 | if (pos != string::npos && pos != arguments.size()) | 522 | if (pos != string::npos && pos != arguments.size()) |
413 | pat = arguments.c_str() + pos; | 523 | pat = arguments.c_str() + pos; |
414 | 524 | ||
415 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new MoveCmd(dx, dy)), pat); | 525 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveCmd(dx, dy)), pat); |
416 | } else if (command == "raise") | 526 | } else if (command == "raise") |
417 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments); | 527 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments); |
418 | else if (command == "raiselayer") | 528 | else if (command == "raiselayer") |
419 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments); | 529 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments); |
420 | else if (command == "lower") | 530 | else if (command == "lower") |
421 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments); | 531 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments); |
422 | else if (command == "lowerlayer") | 532 | else if (command == "lowerlayer") |
423 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments); | 533 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments); |
424 | else if (command == "activate" || command == "focus") | 534 | else if (command == "activate" || command == "focus") |
425 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus)), arguments); | 535 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus)), arguments); |
426 | else if (command == "close") | 536 | else if (command == "close") |
427 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::close)), arguments); | 537 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::close)), arguments); |
428 | else if (command == "closeallwindows") | 538 | else if (command == "closeallwindows") |
429 | return new CloseAllWindowsCmd(); | 539 | return new CloseAllWindowsCmd(); |
430 | else if (command == "killwindow" || command == "kill") | 540 | else if (command == "killwindow" || command == "kill") |
431 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); | 541 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); |
432 | else if (command == "shade" || command == "shadewindow") | 542 | else if (command == "shade" || command == "shadewindow") |
433 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); | 543 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); |
434 | else if (command == "stick" || command == "stickwindow") | 544 | else if (command == "stick" || command == "stickwindow") |
435 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); | 545 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); |
436 | else if (command == "toggledecor") | 546 | else if (command == "toggledecor") |
437 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments); | 547 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments); |
438 | else if (command == "sethead") { | 548 | else if (command == "sethead") { |
439 | int num = 0; | 549 | int num = 0; |
440 | string pat; | 550 | string pat; |
@@ -443,7 +553,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
443 | string::size_type pos = arguments.find('('); | 553 | string::size_type pos = arguments.find('('); |
444 | if (pos != string::npos && pos != arguments.size()) | 554 | if (pos != string::npos && pos != arguments.size()) |
445 | pat = arguments.c_str() + pos; | 555 | pat = arguments.c_str() + pos; |
446 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new SetHeadCmd(num)), pat); | 556 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new SetHeadCmd(num)), pat); |
447 | } else if (command == "tab" || command == "sendtonextworkspace" || | 557 | } else if (command == "tab" || command == "sendtonextworkspace" || |
448 | command == "sendtoprevworkspace" || | 558 | command == "sendtoprevworkspace" || |
449 | command == "taketonextworkspace" || | 559 | command == "taketonextworkspace" || |
@@ -457,7 +567,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
457 | string::size_type pos = arguments.find('('); | 567 | string::size_type pos = arguments.find('('); |
458 | if (pos != string::npos && pos != arguments.size()) | 568 | if (pos != string::npos && pos != arguments.size()) |
459 | pat = arguments.c_str() + pos; | 569 | pat = arguments.c_str() + pos; |
460 | FbTk::RefCount<WindowHelperCmd> cmd; | 570 | FbTk::RefCount<FbTk::Command> cmd; |
461 | 571 | ||
462 | if (command == "tab") | 572 | if (command == "tab") |
463 | cmd = new GoToTabCmd(num); | 573 | cmd = new GoToTabCmd(num); |
@@ -475,15 +585,15 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
475 | cmd = new TakeToWorkspaceCmd(num-1); | 585 | cmd = new TakeToWorkspaceCmd(num-1); |
476 | return new WindowListCmd(cmd, pat); | 586 | return new WindowListCmd(cmd, pat); |
477 | } else if (command == "nexttab") | 587 | } else if (command == "nexttab") |
478 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments); | 588 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments); |
479 | else if (command == "prevtab") | 589 | else if (command == "prevtab") |
480 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments); | 590 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments); |
481 | else if (command == "movetableft") | 591 | else if (command == "movetableft") |
482 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments); | 592 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments); |
483 | else if (command == "movetabright") | 593 | else if (command == "movetabright") |
484 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments); | 594 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments); |
485 | else if (command == "detachclient") | 595 | else if (command == "detachclient") |
486 | return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments); | 596 | return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments); |
487 | else if (command == "windowmenu") | 597 | else if (command == "windowmenu") |
488 | return new CurrentWindowCmd(&FluxboxWindow::popupMenu); | 598 | return new CurrentWindowCmd(&FluxboxWindow::popupMenu); |
489 | // | 599 | // |
@@ -683,6 +793,36 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, | |||
683 | return macro; | 793 | return macro; |
684 | 794 | ||
685 | delete macro; | 795 | delete macro; |
796 | } else if (command == "if" || command == "cond") { | ||
797 | string cmd; | ||
798 | int err = 0, pos = 0; | ||
799 | RefCount<BoolCommand> cond(0); | ||
800 | RefCount<Command> t(0), f(0); | ||
801 | |||
802 | err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str(), | ||
803 | '{', '}', " \t\n", true); | ||
804 | if (err > 0) | ||
805 | cond = parseBoolCommand(cmd, trusted); | ||
806 | if (err == 0 || *cond == 0) | ||
807 | return 0; | ||
808 | |||
809 | pos = err; | ||
810 | err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos, | ||
811 | '{', '}', " \t\n", true); | ||
812 | if (err > 0) | ||
813 | t = CommandParser::instance().parseLine(cmd, trusted); | ||
814 | if (err == 0 || *t == 0) | ||
815 | return 0; | ||
816 | |||
817 | pos += err; | ||
818 | err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos, | ||
819 | '{', '}', " \t\n", true); | ||
820 | if (err > 0) | ||
821 | f = CommandParser::instance().parseLine(cmd, trusted); | ||
822 | if (err == 0 || *f == 0) | ||
823 | return 0; | ||
824 | |||
825 | return new FbTk::IfCommand(cond, t, f); | ||
686 | } | 826 | } |
687 | return 0; | 827 | return 0; |
688 | } | 828 | } |