aboutsummaryrefslogtreecommitdiff
path: root/src/FbCommandFactory.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbCommandFactory.cc')
-rw-r--r--src/FbCommandFactory.cc192
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;
50using std::cerr; 51using std::cerr;
51using std::endl; 52using std::endl;
52 53
54using namespace FbTk;
55using FbTk::StringUtil::removeFirstWhitespace;
56using FbTk::StringUtil::toLower;
57
53// autoregister this module to command parser 58// autoregister this module to command parser
54FbCommandFactory FbCommandFactory::s_autoreg; 59FbCommandFactory 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
68BoolCommand *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
65FbCommandFactory::FbCommandFactory() { 173FbCommandFactory::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}