aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkt <markt>2007-12-13 05:48:00 (GMT)
committermarkt <markt>2007-12-13 05:48:00 (GMT)
commit8b7464046cea5e521ac46811591b0fce0c45aca1 (patch)
tree09df752f426a249ae15375a626a98436c8727593
parentdaca07edafc2e75eb9ee04d35fe80759308a8583 (diff)
downloadfluxbox-8b7464046cea5e521ac46811591b0fce0c45aca1.zip
fluxbox-8b7464046cea5e521ac46811591b0fce0c45aca1.tar.bz2
added FbTk::CommandRegistry, decentralized command parsing, and made them auto-register
-rw-r--r--ChangeLog5
-rw-r--r--src/ClockTool.cc6
-rw-r--r--src/CommandDialog.cc8
-rw-r--r--src/CommandParser.cc124
-rw-r--r--src/CommandParser.hh81
-rw-r--r--src/CurrentWindowCmd.cc291
-rw-r--r--src/CurrentWindowCmd.hh10
-rw-r--r--src/FbCommandFactory.cc833
-rw-r--r--src/FbCommandFactory.hh35
-rw-r--r--src/FbCommands.cc110
-rw-r--r--src/FbCommands.hh6
-rw-r--r--src/FbTk/CommandRegistry.cc92
-rw-r--r--src/FbTk/CommandRegistry.hh130
-rw-r--r--src/FbTk/LogicCommands.cc93
-rw-r--r--src/FbTk/LogicCommands.hh4
-rw-r--r--src/FbTk/MacroCommand.cc48
-rw-r--r--src/FbTk/Makefile.am1
-rw-r--r--src/FbTk/StringUtil.cc12
-rw-r--r--src/FbTk/StringUtil.hh3
-rw-r--r--src/IconbarTool.cc4
-rw-r--r--src/Keys.cc4
-rw-r--r--src/LayerMenu.hh2
-rw-r--r--src/Makefile.am4
-rw-r--r--src/MenuCreator.cc14
-rw-r--r--src/Screen.cc12
-rw-r--r--src/Slit.hh2
-rw-r--r--src/ToggleMenu.hh2
-rw-r--r--src/ToolFactory.cc6
-rw-r--r--src/Toolbar.cc4
-rw-r--r--src/Toolbar.hh2
-rw-r--r--src/WorkspaceCmd.cc120
-rw-r--r--src/WorkspaceCmd.hh8
-rw-r--r--src/WorkspaceMenu.cc4
33 files changed, 966 insertions, 1114 deletions
diff --git a/ChangeLog b/ChangeLog
index b95d844..c942584 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.0.1: 2Changes for 1.0.1:
3*07/12/13:
4 * Moved command parsing code all over the place -- expect any patches that
5 add new commands to be broken (Mark, Simon)
6 Added FbTk/CommandRegistry.cc/hh
7 Removed FbCommandFactory.cc/hh CommandParser.cc/hh
3*07/12/11: 8*07/12/11:
4 * Added new resize modes for key command StartResizing: NearestEdge, Left, 9 * Added new resize modes for key command StartResizing: NearestEdge, Left,
5 Right, Top, Bottom (Mark) 10 Right, Top, Bottom (Mark)
diff --git a/src/ClockTool.cc b/src/ClockTool.cc
index 0bfa136..55973fb 100644
--- a/src/ClockTool.cc
+++ b/src/ClockTool.cc
@@ -26,7 +26,7 @@
26 26
27#include "ToolTheme.hh" 27#include "ToolTheme.hh"
28#include "Screen.hh" 28#include "Screen.hh"
29#include "CommandParser.hh" 29#include "FbTk/CommandRegistry.hh"
30#include "CommandDialog.hh" 30#include "CommandDialog.hh"
31#include "fluxbox.hh" 31#include "fluxbox.hh"
32 32
@@ -128,7 +128,7 @@ public:
128 128
129 CommandDialog *dialog = new CommandDialog(*screen, "Edit Clock Format", 129 CommandDialog *dialog = new CommandDialog(*screen, "Edit Clock Format",
130 "SetResourceValue " + resourcename + " "); 130 "SetResourceValue " + resourcename + " ");
131 FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine("reconfigure")); 131 FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine("reconfigure"));
132 dialog->setPostCommand(cmd); 132 dialog->setPostCommand(cmd);
133 dialog->setText(screen->resourceManager().resourceValue(resourcename)); 133 dialog->setText(screen->resourceManager().resourceValue(resourcename));
134 dialog->show(); 134 dialog->show();
@@ -169,7 +169,7 @@ ClockTool::ClockTool(const FbTk::FbWindow &parent,
169 m_button.setGC(m_theme.textGC()); 169 m_button.setGC(m_theme.textGC());
170 170
171 // setup menu 171 // setup menu
172 FbTk::RefCount<FbTk::Command> saverc(CommandParser::instance().parseLine("saverc")); 172 FbTk::RefCount<FbTk::Command> saverc(FbTk::CommandRegistry::instance().parseLine("saverc"));
173 FbTk::MenuItem *item = new ClockMenuItem(*this); 173 FbTk::MenuItem *item = new ClockMenuItem(*this);
174 item->setCommand(saverc); 174 item->setCommand(saverc);
175 menu.insert(item); 175 menu.insert(item);
diff --git a/src/CommandDialog.cc b/src/CommandDialog.cc
index e19cd53..436a942 100644
--- a/src/CommandDialog.cc
+++ b/src/CommandDialog.cc
@@ -27,7 +27,7 @@
27#include "Screen.hh" 27#include "Screen.hh"
28#include "FbWinFrameTheme.hh" 28#include "FbWinFrameTheme.hh"
29#include "WinClient.hh" 29#include "WinClient.hh"
30#include "CommandParser.hh" 30#include "FbTk/CommandRegistry.hh"
31#include "FocusControl.hh" 31#include "FocusControl.hh"
32#include "fluxbox.hh" 32#include "fluxbox.hh"
33 33
@@ -139,7 +139,7 @@ void CommandDialog::keyPressEvent(XKeyEvent &event) {
139 if (ks == XK_Return) { 139 if (ks == XK_Return) {
140 hide(); // hide and return focus to a FluxboxWindow 140 hide(); // hide and return focus to a FluxboxWindow
141 // create command from line 141 // create command from line
142 auto_ptr<FbTk::Command> cmd(CommandParser::instance(). 142 auto_ptr<FbTk::Command> cmd(FbTk::CommandRegistry::instance().
143 parseLine(m_precommand + m_textbox.text())); 143 parseLine(m_precommand + m_textbox.text()));
144 if (cmd.get()) 144 if (cmd.get())
145 cmd->execute(); 145 cmd->execute();
@@ -170,8 +170,8 @@ void CommandDialog::tabComplete() {
170 return; 170 return;
171 } 171 }
172 172
173 CommandParser::CommandFactoryMap::const_iterator it = CommandParser::instance().factorys().begin(); 173 FbTk::CommandRegistry::CreatorMap::const_iterator it = FbTk::CommandRegistry::instance().commandMap().begin();
174 const CommandParser::CommandFactoryMap::const_iterator it_end = CommandParser::instance().factorys().end(); 174 const FbTk::CommandRegistry::CreatorMap::const_iterator it_end = FbTk::CommandRegistry::instance().commandMap().end();
175 vector<string> matches; 175 vector<string> matches;
176 for (; it != it_end; ++it) { 176 for (; it != it_end; ++it) {
177 if ((*it).first.find(prefix) == 0) { 177 if ((*it).first.find(prefix) == 0) {
diff --git a/src/CommandParser.cc b/src/CommandParser.cc
deleted file mode 100644
index a1e52e5..0000000
--- a/src/CommandParser.cc
+++ /dev/null
@@ -1,124 +0,0 @@
1// CommandParser.cc for Fluxbox - an X11 Window manager
2// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
3// and Simon Bowden (rathnor at users.sourceforge.net)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23// $Id$
24
25#include "CommandParser.hh"
26#include "FbTk/StringUtil.hh"
27
28#include <vector>
29
30using std::string;
31using std::vector;
32using FbTk::StringUtil::removeFirstWhitespace;
33using FbTk::StringUtil::toLower;
34
35
36CommandParser *CommandParser::s_singleton = 0;
37
38CommandFactory::CommandFactory() {
39
40}
41
42CommandFactory::~CommandFactory() {
43 // remove all associations with this factory
44 CommandParser::instance().removeAssociation(*this);
45
46}
47
48void CommandFactory::addCommand(const std::string &command_name) {
49 CommandParser::instance().associateCommand(command_name, *this);
50}
51
52// ensure it is singleton
53CommandParser::CommandParser() {
54 if (s_singleton != 0)
55 throw std::string("CommandParser currently meant ot be singleton");
56}
57
58CommandParser &CommandParser::instance() {
59 if (s_singleton == 0)
60 s_singleton = new CommandParser();
61
62 return *s_singleton;
63}
64
65FbTk::Command *CommandParser::parseLine(const std::string &line, bool trusted) {
66
67 // parse arguments and command
68 string command = line;
69 string arguments;
70 string::size_type first_pos = removeFirstWhitespace(command);
71 FbTk::StringUtil::removeTrailingWhitespace(command);
72 string::size_type second_pos = command.find_first_of(" \t", first_pos);
73 if (second_pos != string::npos) {
74 // ok we have arguments, parsing them here
75 arguments = command.substr(second_pos);
76 removeFirstWhitespace(arguments);
77 command.erase(second_pos); // remove argument from command
78 }
79
80 // now we have parsed command and arguments
81 command = toLower(command);
82
83 // we didn't find any matching command in default commands,
84 // so we search in the command creators modules for a
85 // matching command string
86 return toCommand(command, arguments, trusted);
87
88}
89
90FbTk::Command *CommandParser::toCommand(const std::string &command_str,
91 const std::string &arguments, bool trusted) {
92 if (m_commandfactorys[command_str] != 0)
93 return m_commandfactorys[command_str]->stringToCommand(command_str, arguments, trusted);
94
95 return 0;
96}
97
98void CommandParser::associateCommand(const std::string &command, CommandFactory &factory) {
99 // we shouldnt override other commands
100 if (m_commandfactorys[command] != 0)
101 return;
102
103 m_commandfactorys[command] = &factory;
104}
105
106void CommandParser::removeAssociation(CommandFactory &factory) {
107 // commands that are associated with the factory
108 vector<string> commands;
109 // find associations
110 CommandFactoryMap::iterator factory_it = m_commandfactorys.begin();
111 const CommandFactoryMap::iterator factory_it_end = m_commandfactorys.end();
112 for (; factory_it != factory_it_end; ++factory_it) {
113 if ((*factory_it).second == &factory)
114 commands.push_back((*factory_it).first);
115 }
116 // remove all associations
117 while (!commands.empty()) {
118 m_commandfactorys.erase(commands.back());
119 commands.pop_back();
120 }
121
122 if (m_commandfactorys.empty())
123 delete s_singleton;
124}
diff --git a/src/CommandParser.hh b/src/CommandParser.hh
deleted file mode 100644
index 1bc3094..0000000
--- a/src/CommandParser.hh
+++ /dev/null
@@ -1,81 +0,0 @@
1// CommandParser.hh for Fluxbox - an X11 Window manager
2// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
3// and Simon Bowden (rathnor at users.sourceforge.net)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23// $Id$
24
25#ifndef COMMANDPARSER_HH
26#define COMMANDPARSER_HH
27
28#include <string>
29#include <map>
30
31#include "RefCount.hh"
32
33namespace FbTk {
34class Command;
35};
36
37/// Creates commands from command and argument.
38/// Used for modules to add new commands in compile/run time
39class CommandFactory {
40public:
41 CommandFactory();
42 virtual ~CommandFactory();
43 virtual FbTk::Command *stringToCommand(const std::string &command,
44 const std::string &arguments,
45 bool trusted) = 0;
46protected:
47 void addCommand(const std::string &value);
48};
49
50/// Parses text into a command
51class CommandParser {
52public:
53 typedef std::map<std::string, CommandFactory *> CommandFactoryMap;
54
55 /// @return parses and returns a command matching the line
56 FbTk::Command *parseLine(const std::string &line, bool trusted = true);
57
58 CommandParser();
59
60 /// @return instance of command parser
61 static CommandParser &instance();
62 /// @return map of factorys
63 const CommandFactoryMap &factorys() const { return m_commandfactorys; }
64private:
65 // so CommandFactory can associate it's commands
66 friend class CommandFactory;
67 /// associate a command with a factory
68 void associateCommand(const std::string &name, CommandFactory &factory);
69 /// remove all associations with the factory
70 void removeAssociation(CommandFactory &factory);
71
72 /// search for a command in our command factory map
73 FbTk::Command *toCommand(const std::string &command,
74 const std::string &arguments, bool trusted);
75
76 CommandFactoryMap m_commandfactorys; ///< a string to factory map
77
78 static CommandParser *s_singleton;
79};
80
81#endif // COMMANDPARSER_HH
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc
index 78f3aa1..33d8e8a 100644
--- a/src/CurrentWindowCmd.cc
+++ b/src/CurrentWindowCmd.cc
@@ -31,6 +31,95 @@
31#include "WinClient.hh" 31#include "WinClient.hh"
32 32
33#include "FocusControl.hh" 33#include "FocusControl.hh"
34#include "FbTk/CommandRegistry.hh"
35#include "FbTk/stringstream.hh"
36#include "FbTk/StringUtil.hh"
37
38#include <string>
39#include <vector>
40
41namespace {
42
43FbTk::Command *createCurrentWindowCmd(const std::string &command,
44 const std::string &args, bool trusted) {
45 if (command == "minimizewindow" || command == "minimize" || command == "iconify")
46 return new CurrentWindowCmd(&FluxboxWindow::iconify);
47 else if (command == "maximizewindow" || command == "maximize")
48 return new CurrentWindowCmd(&FluxboxWindow::maximizeFull);
49 else if (command == "maximizevertical")
50 return new CurrentWindowCmd(&FluxboxWindow::maximizeVertical);
51 else if (command == "maximizehorizontal")
52 return new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal);
53 else if (command == "raise")
54 return new CurrentWindowCmd(&FluxboxWindow::raise);
55 else if (command == "raiselayer")
56 return new CurrentWindowCmd(&FluxboxWindow::raiseLayer);
57 else if (command == "lower")
58 return new CurrentWindowCmd(&FluxboxWindow::lower);
59 else if (command == "lowerlayer")
60 return new CurrentWindowCmd(&FluxboxWindow::lowerLayer);
61 else if (command == "activate" || command == "focus")
62 return new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus);
63 else if (command == "close")
64 return new CurrentWindowCmd(&FluxboxWindow::close);
65 else if (command == "killwindow" || command == "kill")
66 return new CurrentWindowCmd(&FluxboxWindow::kill);
67 else if (command == "shade" || command == "shadewindow")
68 return new CurrentWindowCmd(&FluxboxWindow::shade);
69 else if (command == "shadeon" )
70 return new CurrentWindowCmd(&FluxboxWindow::shadeOn);
71 else if (command == "shadeoff" )
72 return new CurrentWindowCmd(&FluxboxWindow::shadeOff);
73 else if (command == "stick" || command == "stickwindow")
74 return new CurrentWindowCmd(&FluxboxWindow::stick);
75 else if (command == "toggledecor")
76 return new CurrentWindowCmd(&FluxboxWindow::toggleDecoration);
77 else if (command == "nexttab")
78 return new CurrentWindowCmd(&FluxboxWindow::nextClient);
79 else if (command == "prevtab")
80 return new CurrentWindowCmd(&FluxboxWindow::prevClient);
81 else if (command == "movetableft")
82 return new CurrentWindowCmd(&FluxboxWindow::moveClientLeft);
83 else if (command == "movetabright")
84 return new CurrentWindowCmd(&FluxboxWindow::moveClientRight);
85 else if (command == "detachclient")
86 return new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient);
87 else if (command == "windowmenu")
88 return new CurrentWindowCmd(&FluxboxWindow::popupMenu);
89 return 0;
90}
91
92REGISTER_COMMAND_PARSER(minimizewindow, createCurrentWindowCmd);
93REGISTER_COMMAND_PARSER(minimize, createCurrentWindowCmd);
94REGISTER_COMMAND_PARSER(iconify, createCurrentWindowCmd);
95REGISTER_COMMAND_PARSER(maximizewindow, createCurrentWindowCmd);
96REGISTER_COMMAND_PARSER(maximize, createCurrentWindowCmd);
97REGISTER_COMMAND_PARSER(maximizevertical, createCurrentWindowCmd);
98REGISTER_COMMAND_PARSER(maximizehorizontal, createCurrentWindowCmd);
99REGISTER_COMMAND_PARSER(raise, createCurrentWindowCmd);
100REGISTER_COMMAND_PARSER(raiselayer, createCurrentWindowCmd);
101REGISTER_COMMAND_PARSER(lower, createCurrentWindowCmd);
102REGISTER_COMMAND_PARSER(lowerlayer, createCurrentWindowCmd);
103REGISTER_COMMAND_PARSER(activate, createCurrentWindowCmd);
104REGISTER_COMMAND_PARSER(focus, createCurrentWindowCmd);
105REGISTER_COMMAND_PARSER(close, createCurrentWindowCmd);
106REGISTER_COMMAND_PARSER(killwindow, createCurrentWindowCmd);
107REGISTER_COMMAND_PARSER(kill, createCurrentWindowCmd);
108REGISTER_COMMAND_PARSER(shade, createCurrentWindowCmd);
109REGISTER_COMMAND_PARSER(shadewindow, createCurrentWindowCmd);
110REGISTER_COMMAND_PARSER(shadeon, createCurrentWindowCmd);
111REGISTER_COMMAND_PARSER(shadeoff, createCurrentWindowCmd);
112REGISTER_COMMAND_PARSER(stick, createCurrentWindowCmd);
113REGISTER_COMMAND_PARSER(stickwindow, createCurrentWindowCmd);
114REGISTER_COMMAND_PARSER(toggledecor, createCurrentWindowCmd);
115REGISTER_COMMAND_PARSER(nexttab, createCurrentWindowCmd);
116REGISTER_COMMAND_PARSER(prevtab, createCurrentWindowCmd);
117REGISTER_COMMAND_PARSER(movetableft, createCurrentWindowCmd);
118REGISTER_COMMAND_PARSER(movetabright, createCurrentWindowCmd);
119REGISTER_COMMAND_PARSER(detachclient, createCurrentWindowCmd);
120REGISTER_COMMAND_PARSER(windowmenu, createCurrentWindowCmd);
121
122}; // end anonymous namespace
34 123
35void WindowHelperCmd::execute() { 124void WindowHelperCmd::execute() {
36 if (WindowCmd<void>::window() || FocusControl::focusedFbWindow()) 125 if (WindowCmd<void>::window() || FocusControl::focusedFbWindow())
@@ -68,6 +157,44 @@ void CurrentWindowCmd::real_execute() {
68 (fbwindow().*m_action)(); 157 (fbwindow().*m_action)();
69} 158}
70 159
160namespace {
161
162FbTk::Command *parseIntCmd(const string &command, const string &args,
163 bool trusted) {
164 int num = (command == "sethead" ? 0 : 1);
165 FbTk_istringstream iss(args.c_str());
166 iss >> num;
167 if (command == "sethead")
168 return new SetHeadCmd(num);
169 else if (command == "tab")
170 return new GoToTabCmd(num);
171 else if (command == "sendtonextworkspace")
172 return new SendToNextWorkspaceCmd(num);
173 else if (command == "sendtoprevworkspace")
174 return new SendToPrevWorkspaceCmd(num);
175 else if (command == "taketonextworkspace")
176 return new TakeToNextWorkspaceCmd(num);
177 else if (command == "taketoprevworkspace")
178 return new TakeToPrevWorkspaceCmd(num);
179 else if (command == "sendtoworkspace")
180 // workspaces appear 1-indexed to the user, hence the minus 1
181 return new SendToWorkspaceCmd(num-1);
182 else if (command == "taketoworkspace")
183 return new TakeToWorkspaceCmd(num-1);
184 return 0;
185}
186
187REGISTER_COMMAND_PARSER(sethead, parseIntCmd);
188REGISTER_COMMAND_PARSER(tab, parseIntCmd);
189REGISTER_COMMAND_PARSER(sendtonextworkspace, parseIntCmd);
190REGISTER_COMMAND_PARSER(sendtoprevworkspace, parseIntCmd);
191REGISTER_COMMAND_PARSER(taketonextworkspace, parseIntCmd);
192REGISTER_COMMAND_PARSER(taketoprevworkspace, parseIntCmd);
193REGISTER_COMMAND_PARSER(sendtoworkspace, parseIntCmd);
194REGISTER_COMMAND_PARSER(taketoworkspace, parseIntCmd);
195
196}; // end anonymous namespace
197
71void SetHeadCmd::real_execute() { 198void SetHeadCmd::real_execute() {
72 fbwindow().setOnHead(m_head); 199 fbwindow().setOnHead(m_head);
73} 200}
@@ -127,6 +254,8 @@ void GoToTabCmd::real_execute() {
127 (*it)->focus(); 254 (*it)->focus();
128} 255}
129 256
257REGISTER_COMMAND(startmoving, StartMovingCmd);
258
130void StartMovingCmd::real_execute() { 259void StartMovingCmd::real_execute() {
131 const XEvent &last = Fluxbox::instance()->lastEvent(); 260 const XEvent &last = Fluxbox::instance()->lastEvent();
132 if (last.type == ButtonPress) { 261 if (last.type == ButtonPress) {
@@ -135,6 +264,41 @@ void StartMovingCmd::real_execute() {
135 } 264 }
136} 265}
137 266
267FbTk::Command *StartResizingCmd::parse(const string &cmd, const string &args,
268 bool trusted) {
269 FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE;
270 std::vector<string> tokens;
271 FbTk::StringUtil::stringtok<std::vector<string> >(tokens, args);
272 if (!tokens.empty()) {
273 string arg = FbTk::StringUtil::toLower(tokens[0]);
274 if (arg == "nearestcorner")
275 mode = FluxboxWindow::QUADRANTRESIZE;
276 else if (arg == "nearestedge")
277 mode = FluxboxWindow::NEARESTEDGERESIZE;
278 else if (arg == "center")
279 mode = FluxboxWindow::CENTERRESIZE;
280 else if (arg == "topleft")
281 mode = FluxboxWindow::TOPLEFTRESIZE;
282 else if (arg == "top")
283 mode = FluxboxWindow::TOPRESIZE;
284 else if (arg == "topright")
285 mode = FluxboxWindow::TOPRIGHTRESIZE;
286 else if (arg == "left")
287 mode = FluxboxWindow::LEFTRESIZE;
288 else if (arg == "right")
289 mode = FluxboxWindow::RIGHTRESIZE;
290 else if (arg == "bottomleft")
291 mode = FluxboxWindow::BOTTOMLEFTRESIZE;
292 else if (arg == "bottom")
293 mode = FluxboxWindow::BOTTOMRESIZE;
294 else if (arg == "bottomright")
295 mode = FluxboxWindow::BOTTOMRIGHTRESIZE;
296 }
297 return new StartResizingCmd(mode);
298}
299
300REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse);
301
138void StartResizingCmd::real_execute() { 302void StartResizingCmd::real_execute() {
139 const XEvent &last = Fluxbox::instance()->lastEvent(); 303 const XEvent &last = Fluxbox::instance()->lastEvent();
140 if (last.type == ButtonPress) { 304 if (last.type == ButtonPress) {
@@ -147,6 +311,33 @@ void StartResizingCmd::real_execute() {
147 } 311 }
148} 312}
149 313
314FbTk::Command *MoveCmd::parse(const string &command, const string &args,
315 bool trusted) {
316 FbTk_istringstream is(args.c_str());
317 int dx = 0, dy = 0;
318 is >> dx >> dy;
319
320 if (command == "moveright")
321 dy = 0;
322 else if (command == "moveleft") {
323 dy = 0;
324 dx = -dx;
325 } else if (command == "movedown") {
326 dy = dx;
327 dx = 0;
328 } else if (command == "moveup") {
329 dy = -dx;
330 dx = 0;
331 }
332 return new MoveCmd(dx, dy);
333}
334
335REGISTER_COMMAND_PARSER(move, MoveCmd::parse);
336REGISTER_COMMAND_PARSER(moveright, MoveCmd::parse);
337REGISTER_COMMAND_PARSER(moveleft, MoveCmd::parse);
338REGISTER_COMMAND_PARSER(moveup, MoveCmd::parse);
339REGISTER_COMMAND_PARSER(movedown, MoveCmd::parse);
340
150MoveCmd::MoveCmd(const int step_size_x, const int step_size_y) : 341MoveCmd::MoveCmd(const int step_size_x, const int step_size_y) :
151 m_step_size_x(step_size_x), m_step_size_y(step_size_y) { } 342 m_step_size_x(step_size_x), m_step_size_y(step_size_y) { }
152 343
@@ -156,6 +347,28 @@ void MoveCmd::real_execute() {
156 fbwindow().y() + m_step_size_y); 347 fbwindow().y() + m_step_size_y);
157} 348}
158 349
350FbTk::Command *ResizeCmd::parse(const string &command, const string &args,
351 bool trusted) {
352 FbTk_istringstream is(args.c_str());
353 int dx = 0, dy = 0;
354 is >> dx >> dy;
355 if (command == "resizehorizontal")
356 dy = 0;
357 else if (command == "resizevertical") {
358 dy = dx;
359 dx = 0;
360 }
361
362 if (command == "resizeto")
363 return new ResizeToCmd(dx, dy);
364 return new ResizeCmd(dx, dy);
365}
366
367REGISTER_COMMAND_PARSER(resize, ResizeCmd::parse);
368REGISTER_COMMAND_PARSER(resizeto, ResizeCmd::parse);
369REGISTER_COMMAND_PARSER(resizehorizontal, ResizeCmd::parse);
370REGISTER_COMMAND_PARSER(resizevertical, ResizeCmd::parse);
371
159ResizeCmd::ResizeCmd(const int step_size_x, const int step_size_y) : 372ResizeCmd::ResizeCmd(const int step_size_x, const int step_size_y) :
160 m_step_size_x(step_size_x), m_step_size_y(step_size_y) { } 373 m_step_size_x(step_size_x), m_step_size_y(step_size_y) { }
161 374
@@ -170,6 +383,53 @@ void ResizeCmd::real_execute() {
170 fbwindow().resize(w, h); 383 fbwindow().resize(w, h);
171} 384}
172 385
386FbTk::Command *MoveToCmd::parse(const string &cmd, const string &args,
387 bool trusted) {
388 typedef std::vector<string> StringTokens;
389 StringTokens tokens;
390 FbTk::StringUtil::stringtok<StringTokens>(tokens, args);
391
392 if (tokens.size() < 2)
393 return 0;
394
395 unsigned int refc = MoveToCmd::UPPER|MoveToCmd::LEFT;
396 int dx = 0, dy = 0;
397
398 if (tokens[0][0] == '*')
399 refc |= MoveToCmd::IGNORE_X;
400 else
401 dx = atoi(tokens[0].c_str());
402
403 if (tokens[1][0] == '*' && ! (refc & MoveToCmd::IGNORE_X))
404 refc |= MoveToCmd::IGNORE_Y;
405 else
406 dy = atoi(tokens[1].c_str());
407
408 if (tokens.size() >= 3) {
409 tokens[2] = FbTk::StringUtil::toLower(tokens[2]);
410 if (tokens[2] == "left" || tokens[2] == "upperleft" || tokens[2] == "lowerleft") {
411 refc |= MoveToCmd::LEFT;
412 refc &= ~MoveToCmd::RIGHT;
413 } else if (tokens[2] == "right" || tokens[2] == "upperright" || tokens[2] == "lowerright") {
414 refc |= MoveToCmd::RIGHT;
415 refc &= ~MoveToCmd::LEFT;
416 }
417
418 if (tokens[2] == "upper" || tokens[2] == "upperleft" || tokens[2] == "upperright") {
419 refc |= MoveToCmd::UPPER;
420 refc &= ~MoveToCmd::LOWER;
421 } else if (tokens[2] == "lower" || tokens[2] == "lowerleft" || tokens[2] == "lowerright") {
422 refc |= MoveToCmd::LOWER;
423 refc &= ~MoveToCmd::UPPER;
424 }
425 }
426
427 return new MoveToCmd(dx, dy, refc);
428
429}
430
431REGISTER_COMMAND_PARSER(moveto, MoveToCmd::parse);
432
173MoveToCmd::MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc) : 433MoveToCmd::MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc) :
174 m_step_size_x(step_size_x), m_step_size_y(step_size_y), m_refc(refc) { } 434 m_step_size_x(step_size_x), m_step_size_y(step_size_y), m_refc(refc) { }
175 435
@@ -205,11 +465,40 @@ void ResizeToCmd::real_execute() {
205 fbwindow().resize(m_step_size_x, m_step_size_y); 465 fbwindow().resize(m_step_size_x, m_step_size_y);
206} 466}
207 467
468REGISTER_COMMAND(fullscreen, FullscreenCmd);
469
208FullscreenCmd::FullscreenCmd() { } 470FullscreenCmd::FullscreenCmd() { }
209void FullscreenCmd::real_execute() { 471void FullscreenCmd::real_execute() {
210 fbwindow().setFullscreen(!fbwindow().isFullscreen()); 472 fbwindow().setFullscreen(!fbwindow().isFullscreen());
211} 473}
212 474
475FbTk::Command *SetAlphaCmd::parse(const string &command, const string &args,
476 bool trusted) {
477 typedef std::vector<string> StringTokens;
478 StringTokens tokens;
479 FbTk::StringUtil::stringtok<StringTokens>(tokens, args);
480
481 int focused, unfocused;
482 bool relative, un_rel;
483
484 if (tokens.empty()) { // set default alpha
485 focused = unfocused = 256;
486 relative = un_rel = false;
487 } else {
488 relative = un_rel = (tokens[0][0] == '+' || tokens[0][0] == '-');
489 focused = unfocused = atoi(tokens[0].c_str());
490 }
491
492 if (tokens.size() > 1) { // set different unfocused alpha
493 un_rel = (tokens[1][0] == '+' || tokens[1][0] == '-');
494 unfocused = atoi(tokens[1].c_str());
495 }
496
497 return new SetAlphaCmd(focused, relative, unfocused, un_rel);
498}
499
500REGISTER_COMMAND_PARSER(setalpha, SetAlphaCmd::parse);
501
213SetAlphaCmd::SetAlphaCmd(int focused, bool relative, 502SetAlphaCmd::SetAlphaCmd(int focused, bool relative,
214 int unfocused, bool un_relative) : 503 int unfocused, bool un_relative) :
215 m_focus(focused), m_unfocus(unfocused), 504 m_focus(focused), m_unfocus(unfocused),
@@ -240,6 +529,8 @@ void SetAlphaCmd::real_execute() {
240 fbwindow().setUnfocusedAlpha(m_unfocus); 529 fbwindow().setUnfocusedAlpha(m_unfocus);
241} 530}
242 531
532REGISTER_BOOLCOMMAND_WITH_ARGS(matches, MatchCmd);
533
243bool MatchCmd::real_execute() { 534bool MatchCmd::real_execute() {
244 return m_pat.match(winclient()); 535 return m_pat.match(winclient());
245} 536}
diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh
index c8e6242..7ef1184 100644
--- a/src/CurrentWindowCmd.hh
+++ b/src/CurrentWindowCmd.hh
@@ -151,6 +151,8 @@ protected:
151class StartResizingCmd: public WindowHelperCmd { 151class StartResizingCmd: public WindowHelperCmd {
152public: 152public:
153 explicit StartResizingCmd(FluxboxWindow::ResizeModel mode):m_mode(mode) { } 153 explicit StartResizingCmd(FluxboxWindow::ResizeModel mode):m_mode(mode) { }
154 static FbTk::Command *parse(const std::string &command,
155 const std::string &args, bool trusted);
154protected: 156protected:
155 void real_execute(); 157 void real_execute();
156private: 158private:
@@ -161,6 +163,8 @@ private:
161class MoveCmd: public WindowHelperCmd { 163class MoveCmd: public WindowHelperCmd {
162public: 164public:
163 explicit MoveCmd(const int step_size_x, const int step_size_y); 165 explicit MoveCmd(const int step_size_x, const int step_size_y);
166 static FbTk::Command *parse(const std::string &command,
167 const std::string &args, bool trusted);
164protected: 168protected:
165 void real_execute(); 169 void real_execute();
166 170
@@ -173,6 +177,8 @@ private:
173class ResizeCmd: public WindowHelperCmd{ 177class ResizeCmd: public WindowHelperCmd{
174public: 178public:
175 explicit ResizeCmd(int step_size_x, int step_size_y); 179 explicit ResizeCmd(int step_size_x, int step_size_y);
180 static FbTk::Command *parse(const std::string &command,
181 const std::string &args, bool trusted);
176protected: 182protected:
177 void real_execute(); 183 void real_execute();
178 184
@@ -194,6 +200,8 @@ public:
194 IGNORE_Y = 1 << 9 200 IGNORE_Y = 1 << 9
195 }; 201 };
196 explicit MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc); 202 explicit MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc);
203 static FbTk::Command *parse(const std::string &command,
204 const std::string &args, bool trusted);
197protected: 205protected:
198 void real_execute(); 206 void real_execute();
199 207
@@ -224,6 +232,8 @@ protected:
224class SetAlphaCmd: public WindowHelperCmd { 232class SetAlphaCmd: public WindowHelperCmd {
225public: 233public:
226 SetAlphaCmd(int focus, bool rel, int unfocus, bool unrel); 234 SetAlphaCmd(int focus, bool rel, int unfocus, bool unrel);
235 static FbTk::Command *parse(const std::string &command,
236 const std::string &args, bool trusted);
227protected: 237protected:
228 void real_execute(); 238 void real_execute();
229private: 239private:
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc
deleted file mode 100644
index 902461c..0000000
--- a/src/FbCommandFactory.cc
+++ /dev/null
@@ -1,833 +0,0 @@
1// FbCommandFactory.cc for Fluxbox Window manager
2// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
3// and Simon Bowden (rathnor at users.sourceforge.net)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23// $Id$
24
25#include "FbCommandFactory.hh"
26
27#include "FocusableList.hh"
28#include "CurrentWindowCmd.hh"
29#include "FbCommands.hh"
30#include "Window.hh"
31#include "WorkspaceCmd.hh"
32#include "fluxbox.hh"
33#include "SimpleCommand.hh"
34#include "Screen.hh"
35
36#include "FbTk/StringUtil.hh"
37#include "FbTk/LogicCommands.hh"
38#include "FbTk/MacroCommand.hh"
39#include "FbTk/stringstream.hh"
40
41#include <string>
42
43#ifdef HAVE_CSTDIO
44 #include <cstdio>
45#else
46 #include <stdio.h>
47#endif
48
49using std::string;
50using std::vector;
51using std::cerr;
52using std::endl;
53
54using namespace FbTk;
55using FbTk::StringUtil::removeFirstWhitespace;
56using FbTk::StringUtil::toLower;
57
58// autoregister this module to command parser
59FbCommandFactory FbCommandFactory::s_autoreg;
60
61namespace {
62
63static int getint(const char *str, int defaultvalue) {
64 sscanf(str, "%d", &defaultvalue);
65 return defaultvalue;
66}
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
171}; // end anonymous namespace
172
173FbCommandFactory::FbCommandFactory() {
174 // setup commands that we can handle
175 const char* commands[] = {
176 "activate",
177 "addworkspace",
178 "arrangewindows",
179 "attach",
180 "bindkey",
181 "clientmenu",
182 "close",
183 "closeallwindows",
184 "commanddialog",
185 "cond",
186 "custommenu",
187 "deiconify",
188 "detachclient",
189 "export",
190 "exec",
191 "execcommand",
192 "execute",
193 "exit",
194 "focus",
195 "focusup",
196 "focusdown",
197 "focusleft",
198 "focusright",
199 "fullscreen",
200 "gotowindow",
201 "hidemenus",
202 "iconify",
203 "if",
204 "keymode",
205 "kill",
206 "killwindow",
207 "leftworkspace",
208 "lower",
209 "lowerlayer",
210 "macrocmd",
211 "maximize",
212 "maximizehorizontal",
213 "maximizevertical",
214 "maximizewindow",
215 "minimize",
216 "minimizewindow",
217 "moveto",
218 "move",
219 "movedown",
220 "moveleft",
221 "moveright",
222 "movetableft",
223 "movetabright",
224 "moveup",
225 "nextgroup",
226 "nexttab",
227 "nextwindow",
228 "nextworkspace",
229 "prevgroup",
230 "prevtab",
231 "prevwindow",
232 "prevworkspace",
233 "quit",
234 "raise",
235 "raiselayer",
236 "reconfig",
237 "reconfigure",
238 "reloadstyle",
239 "removelastworkspace",
240 "resizeto",
241 "resize",
242 "resizehorizontal",
243 "resizevertical",
244 "restart",
245 "rightworkspace",
246 "rootmenu",
247 "saverc",
248 "sendtoworkspace",
249 "sendtonextworkspace",
250 "sendtoprevworkspace",
251 "setalpha",
252 "setenv",
253 "sethead",
254 "setstyle",
255 "setworkspacename",
256 "setworkspacenamedialog",
257 "setresourcevalue",
258 "setresourcevaluedialog",
259 "shade",
260 "shadeon",
261 "shadeoff",
262 "shadewindow",
263 "showdesktop",
264 "startmoving",
265 "startresizing",
266 "stick",
267 "stickwindow",
268 "tab",
269 "taketoworkspace",
270 "taketonextworkspace",
271 "taketoprevworkspace",
272 "togglecmd",
273 "toggledecor",
274 "windowmenu",
275 "workspace",
276 /* NOTE: The following are DEPRECATED and subject to removal */
277 "workspace1",
278 "workspace2",
279 "workspace3",
280 "workspace4",
281 "workspace5",
282 "workspace6",
283 "workspace7",
284 "workspace8",
285 "workspace9",
286 "workspace10",
287 "workspace11",
288 "workspace12",
289 /* end note */
290 "workspacemenu",
291 0
292 };
293
294 for (int i=0; commands[i]; ++i)
295 addCommand(commands[i]);
296}
297
298FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
299 const std::string &arguments, bool trusted) {
300 using namespace FbCommands;
301 //
302 // WM commands
303 //
304 if (command == "restart" && trusted)
305 return new RestartFluxboxCmd(arguments);
306 else if (command == "reconfigure" || command == "reconfig")
307 return new ReconfigureFluxboxCmd();
308 else if (command == "setstyle")
309 return new SetStyleCmd(arguments);
310 else if (command == "reloadstyle")
311 return new ReloadStyleCmd();
312 else if (command == "keymode")
313 return new KeyModeCmd(arguments);
314 else if (command == "saverc")
315 return new SaveResources();
316 else if (command == "execcommand" || command == "execute" || command == "exec") {
317 if (!trusted) return 0;
318 return new ExecuteCmd(arguments); // execute command on key screen
319 } else if (command == "exit" || command == "quit")
320 return new ExitFluxboxCmd();
321 else if ((command == "setenv" || command == "export") && trusted) {
322
323 string name = arguments;
324 FbTk::StringUtil::removeFirstWhitespace(name);
325 FbTk::StringUtil::removeTrailingWhitespace(name);
326 size_t pos = name.find_first_of(command == "setenv" ? " \t" : "=");
327 if (pos == string::npos || pos == name.size())
328 return 0;
329
330 string value = name.substr(pos + 1);
331 name = name.substr(0, pos);
332 return new ExportCmd(name, value);
333 } else if (command == "commanddialog") // run specified fluxbox command
334 return new CommandDialogCmd();
335 else if (command == "bindkey" && trusted)
336 return new BindKeyCmd(arguments);
337 else if (command == "setresourcevalue" && trusted) {
338 // we need to parse arguments as:
339 // <remove whitespace here><resname><one whitespace><value>
340 string name = arguments;
341 FbTk::StringUtil::removeFirstWhitespace(name);
342 size_t pos = name.find_first_of(" \t");
343 // we need an argument to resource name
344 if (pos == std::string::npos || pos == name.size())
345 return 0;
346 // +1 so we only remove the first whitespace
347 // i.e so users can set space before workspace name and so on
348 string value = name.substr(pos + 1);
349 name = name.substr(0, pos);
350 return new SetResourceValueCmd(name, value);
351 } else if (command == "setresourcevaluedialog")
352 return new SetResourceValueDialogCmd();
353 else if (command == "addworkspace")
354 return new AddWorkspaceCmd();
355 else if (command == "removelastworkspace")
356 return new RemoveLastWorkspaceCmd();
357 //
358 // Current focused window commands
359 //
360 else if (command == "fullscreen")
361 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new FullscreenCmd()), arguments);
362 else if (command == "minimizewindow" || command == "minimize" || command == "iconify")
363 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments);
364 else if (command == "maximizewindow" || command == "maximize")
365 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments);
366 else if (command == "maximizevertical")
367 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments);
368 else if (command == "maximizehorizontal")
369 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments);
370 else if (command == "setalpha") {
371 typedef vector<string> StringTokens;
372 StringTokens tokens;
373 FbTk::StringUtil::stringtok<StringTokens>(tokens, arguments);
374
375 int focused, unfocused;
376 bool relative, un_rel;
377
378 if (tokens.empty()) { // set default alpha
379 focused = unfocused = 256;
380 relative = un_rel = false;
381 } else {
382 relative = un_rel = (tokens[0][0] == '+' || tokens[0][0] == '-');
383 focused = unfocused = atoi(tokens[0].c_str());
384 }
385
386 if (tokens.size() > 1) { // set different unfocused alpha
387 un_rel = (tokens[1][0] == '+' || tokens[1][0] == '-');
388 unfocused = atoi(tokens[1].c_str());
389 }
390
391 string pat;
392 string::size_type pos = arguments.find('(');
393 if (pos != string::npos && pos != arguments.size())
394 pat = arguments.c_str() + pos;
395
396 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new SetAlphaCmd(focused, relative, unfocused, un_rel)), pat);
397 } else if (command == "startmoving")
398 return new StartMovingCmd();
399 else if (command == "startresizing") {
400 FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE;
401 vector<string> tokens;
402 FbTk::StringUtil::stringtok<vector<string> >(tokens, arguments);
403 if (!tokens.empty()) {
404 string arg = FbTk::StringUtil::toLower(tokens[0]);
405 if (arg == "nearestcorner")
406 mode = FluxboxWindow::QUADRANTRESIZE;
407 else if (arg == "nearestedge")
408 mode = FluxboxWindow::NEARESTEDGERESIZE;
409 else if (arg == "center")
410 mode = FluxboxWindow::CENTERRESIZE;
411 else if (arg == "topleft")
412 mode = FluxboxWindow::TOPLEFTRESIZE;
413 else if (arg == "top")
414 mode = FluxboxWindow::TOPRESIZE;
415 else if (arg == "topright")
416 mode = FluxboxWindow::TOPRIGHTRESIZE;
417 else if (arg == "left")
418 mode = FluxboxWindow::LEFTRESIZE;
419 else if (arg == "right")
420 mode = FluxboxWindow::RIGHTRESIZE;
421 else if (arg == "bottomleft")
422 mode = FluxboxWindow::BOTTOMLEFTRESIZE;
423 else if (arg == "bottom")
424 mode = FluxboxWindow::BOTTOMRESIZE;
425 else if (arg == "bottomright")
426 mode = FluxboxWindow::BOTTOMRIGHTRESIZE;
427 }
428 return new StartResizingCmd(mode);
429 } else if (command == "resize" || command == "resizeto" ||
430 command == "resizehorizontal" || command == "resizevertical") {
431 FbTk_istringstream is(arguments.c_str());
432 int dx = 0, dy = 0;
433 is >> dx >> dy;
434 if (command == "resizehorizontal")
435 dy = 0;
436 else if (command == "resizevertical") {
437 dy = dx;
438 dx = 0;
439 }
440
441 string pat;
442 string::size_type pos = arguments.find('(');
443 if (pos != string::npos && pos != arguments.size())
444 pat = arguments.c_str() + pos;
445
446 FbTk::RefCount<FbTk::Command> cmd;
447 if (command == "resizeto")
448 cmd = new ResizeToCmd(dx, dy);
449 else
450 cmd = new ResizeCmd(dx, dy);
451
452 return new WindowListCmd(cmd, pat);
453 } else if (command == "moveto") {
454 typedef vector<string> StringTokens;
455 StringTokens tokens;
456 FbTk::StringUtil::stringtok<StringTokens>(tokens, arguments);
457
458 if (tokens.size() < 2) {
459 cerr<<"*** WARNING: missing arguments for MoveTo\n";
460 return NULL;
461 }
462
463 unsigned int refc = MoveToCmd::UPPER|MoveToCmd::LEFT;
464 int dx = 0;
465 int dy = 0;
466
467 if (tokens[0][0] == '*')
468 refc |= MoveToCmd::IGNORE_X;
469 else
470 dx = atoi(tokens[0].c_str());
471
472 if (tokens[1][0] == '*' && ! (refc & MoveToCmd::IGNORE_X))
473 refc |= MoveToCmd::IGNORE_Y;
474 else
475 dy = atoi(tokens[1].c_str());
476
477 if (tokens.size() >= 3) {
478 tokens[2] = FbTk::StringUtil::toLower(tokens[2]);
479 if (tokens[2] == "left" || tokens[2] == "upperleft" || tokens[2] == "lowerleft") {
480 refc |= MoveToCmd::LEFT;
481 refc &= ~MoveToCmd::RIGHT;
482 } else if (tokens[2] == "right" || tokens[2] == "upperright" || tokens[2] == "lowerright") {
483 refc |= MoveToCmd::RIGHT;
484 refc &= ~MoveToCmd::LEFT;
485 }
486
487 if (tokens[2] == "upper" || tokens[2] == "upperleft" || tokens[2] == "upperright") {
488 refc |= MoveToCmd::UPPER;
489 refc &= ~MoveToCmd::LOWER;
490 } else if (tokens[2] == "lower" || tokens[2] == "lowerleft" || tokens[2] == "lowerright") {
491 refc |= MoveToCmd::LOWER;
492 refc &= ~MoveToCmd::UPPER;
493 }
494 }
495
496 string pat;
497 string::size_type pos = arguments.find('(');
498 if (pos != string::npos && pos != arguments.size())
499 pat = arguments.c_str() + pos;
500
501 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveToCmd(dx, dy, refc)), pat);
502 } else if (command == "move" || command == "moveright" ||
503 command == "moveleft" || command == "moveup" ||
504 command == "movedown") {
505 FbTk_istringstream is(arguments.c_str());
506 int dx = 0, dy = 0;
507 is >> dx >> dy;
508
509 if (command == "moveright")
510 dy = 0;
511 else if (command == "moveleft") {
512 dy = 0;
513 dx = -dx;
514 } else if (command == "movedown") {
515 dy = dx;
516 dx = 0;
517 } else if (command == "moveup") {
518 dy = -dx;
519 dx = 0;
520 }
521
522 string pat;
523 string::size_type pos = arguments.find('(');
524 if (pos != string::npos && pos != arguments.size())
525 pat = arguments.c_str() + pos;
526
527 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveCmd(dx, dy)), pat);
528 } else if (command == "raise")
529 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments);
530 else if (command == "raiselayer")
531 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments);
532 else if (command == "lower")
533 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments);
534 else if (command == "lowerlayer")
535 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments);
536 else if (command == "activate" || command == "focus")
537 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus)), arguments);
538 else if (command == "close")
539 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::close)), arguments);
540 else if (command == "closeallwindows")
541 return new CloseAllWindowsCmd();
542 else if (command == "killwindow" || command == "kill")
543 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments);
544 else if (command == "shade" || command == "shadewindow")
545 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments);
546 else if (command == "shadeon" )
547 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shadeOn)), arguments);
548 else if (command == "shadeoff" )
549 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shadeOff)), arguments);
550 else if (command == "stick" || command == "stickwindow")
551 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments);
552 else if (command == "toggledecor")
553 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments);
554 else if (command == "sethead") {
555 int num = 0;
556 string pat;
557 FbTk_istringstream iss(arguments.c_str());
558 iss >> num;
559 string::size_type pos = arguments.find('(');
560 if (pos != string::npos && pos != arguments.size())
561 pat = arguments.c_str() + pos;
562 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new SetHeadCmd(num)), pat);
563 } else if (command == "tab" || command == "sendtonextworkspace" ||
564 command == "sendtoprevworkspace" ||
565 command == "taketonextworkspace" ||
566 command == "taketoprevworkspace" ||
567 command == "sendtoworkspace" || command == "taketoworkspace") {
568 // workspaces appear 1-indexed to the user, hence the minus 1
569 int num = 1;
570 string pat;
571 FbTk_istringstream iss(arguments.c_str());
572 iss >> num;
573 string::size_type pos = arguments.find('(');
574 if (pos != string::npos && pos != arguments.size())
575 pat = arguments.c_str() + pos;
576 FbTk::RefCount<FbTk::Command> cmd;
577
578 if (command == "tab")
579 cmd = new GoToTabCmd(num);
580 else if (command == "sendtonextworkspace")
581 cmd = new SendToNextWorkspaceCmd(num);
582 else if (command == "sendtoprevworkspace")
583 cmd = new SendToPrevWorkspaceCmd(num);
584 else if (command == "taketonextworkspace")
585 cmd = new TakeToNextWorkspaceCmd(num);
586 else if (command == "taketoprevworkspace")
587 cmd = new TakeToPrevWorkspaceCmd(num);
588 else if (command == "sendtoworkspace")
589 cmd = new SendToWorkspaceCmd(num-1);
590 else
591 cmd = new TakeToWorkspaceCmd(num-1);
592 return new WindowListCmd(cmd, pat);
593 } else if (command == "nexttab")
594 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments);
595 else if (command == "prevtab")
596 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments);
597 else if (command == "movetableft")
598 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments);
599 else if (command == "movetabright")
600 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments);
601 else if (command == "detachclient")
602 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments);
603 else if (command == "windowmenu")
604 return new CurrentWindowCmd(&FluxboxWindow::popupMenu);
605 //
606 // Workspace commands
607 //
608 else if (command == "nextworkspace")
609 return new NextWorkspaceCmd(getint(arguments.c_str(), 1));
610 else if (command == "prevworkspace")
611 return new PrevWorkspaceCmd(getint(arguments.c_str(), 1));
612 else if (command == "rightworkspace")
613 return new RightWorkspaceCmd(getint(arguments.c_str(), 1));
614 else if (command == "leftworkspace")
615 return new LeftWorkspaceCmd(getint(arguments.c_str(), 1));
616 else if (command == "workspace")
617 // workspaces appear 1-indexed to the user, hence the minus 1
618 return new JumpToWorkspaceCmd(getint(arguments.c_str(), 1) - 1);
619 else if (command.substr(0, 9) == "workspace" && command[9] >= '0' && command[9] <= '9') {
620 cerr<<"*** WARNING: 'Workspace<n>' actions are deprecated! Use 'Workspace <n>' instead"<<endl;
621 return new JumpToWorkspaceCmd(getint(command.substr(9).c_str(), 1) - 1);
622
623 } else if (command == "attach") {
624 int opts; // not used
625 string pat;
626 FocusableList::parseArgs(arguments, opts, pat);
627 return new AttachCmd(pat);
628 } else if (command == "nextwindow") {
629 int opts;
630 string pat;
631 FocusableList::parseArgs(arguments, opts, pat);
632 return new NextWindowCmd(opts, pat);
633 } else if (command == "nextgroup") {
634 int opts;
635 string pat;
636 FocusableList::parseArgs(arguments, opts, pat);
637 opts |= FocusableList::LIST_GROUPS;
638 return new NextWindowCmd(opts, pat);
639 } else if (command == "prevwindow") {
640 int opts;
641 string pat;
642 FocusableList::parseArgs(arguments, opts, pat);
643 return new PrevWindowCmd(opts, pat);
644 } else if (command == "prevgroup") {
645 int opts;
646 string pat;
647 FocusableList::parseArgs(arguments, opts, pat);
648 opts |= FocusableList::LIST_GROUPS;
649 return new PrevWindowCmd(opts, pat);
650 } else if (command == "gotowindow") {
651 int num, opts;
652 string args, pat;
653 FbTk_istringstream iss(arguments.c_str());
654 iss >> num;
655 string::size_type pos = arguments.find_first_of("({");
656 if (pos != string::npos && pos != arguments.size())
657 args = arguments.c_str() + pos;
658 FocusableList::parseArgs(args, opts, pat);
659 return new GoToWindowCmd(num, opts, pat);
660 } else if (command == "clientmenu") {
661 int opts;
662 string pat;
663 FocusableList::parseArgs(arguments, opts, pat);
664 return new ShowClientMenuCmd(opts, pat);
665 } else if (command == "focusup")
666 return new DirFocusCmd(FocusControl::FOCUSUP);
667 else if (command == "focusdown")
668 return new DirFocusCmd(FocusControl::FOCUSDOWN);
669 else if (command == "focusleft")
670 return new DirFocusCmd(FocusControl::FOCUSLEFT);
671 else if (command == "focusright")
672 return new DirFocusCmd(FocusControl::FOCUSRIGHT);
673 else if (command == "arrangewindows")
674 return new ArrangeWindowsCmd();
675 else if (command == "showdesktop")
676 return new ShowDesktopCmd();
677 else if (command == "hidemenus")
678 return new HideMenuCmd();
679 else if (command == "rootmenu")
680 return new ShowRootMenuCmd();
681 else if (command == "custommenu")
682 return new ShowCustomMenuCmd(arguments.c_str());
683 else if (command == "workspacemenu")
684 return new ShowWorkspaceMenuCmd();
685 else if (command == "setworkspacename") {
686 if (arguments.empty())
687 return new SetWorkspaceNameCmd("empty");
688 else
689 return new SetWorkspaceNameCmd(arguments);
690 }
691 else if (command == "setworkspacenamedialog")
692 return new WorkspaceNameDialogCmd();
693 //
694 // special commands
695 //
696 else if (command == "deiconify") {
697
698 FbTk_istringstream iss(arguments.c_str());
699 string mode;
700 string d;
701 DeiconifyCmd::Destination dest;
702
703 iss >> mode;
704 if (iss.fail())
705 mode="lastworkspace";
706 mode= FbTk::StringUtil::toLower(mode);
707
708 iss >> d;
709 if (iss.fail())
710 d="current";
711 d= FbTk::StringUtil::toLower(d);
712 if (d == "origin" )
713 dest= DeiconifyCmd::ORIGIN;
714 else if (d == "originquiet")
715 dest= DeiconifyCmd::ORIGINQUIET;
716 else
717 dest= DeiconifyCmd::CURRENT;
718
719 if ( mode == "all" )
720 return new DeiconifyCmd(DeiconifyCmd::ALL, dest);
721 else if ( mode == "allworkspace" )
722 return new DeiconifyCmd(DeiconifyCmd::ALLWORKSPACE, dest);
723 else if ( mode == "last" )
724 return new DeiconifyCmd(DeiconifyCmd::LAST, dest);
725 else // lastworkspace, default
726 return new DeiconifyCmd(DeiconifyCmd::LASTWORKSPACE, dest);
727
728 } else if (command == "macrocmd") {
729 string cmd;
730 int err= 0;
731 int parse_pos= 0;
732 FbTk::MacroCommand* macro= new FbTk::MacroCommand();
733
734 while (true) {
735 parse_pos+= err;
736 err= FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() +
737 parse_pos,
738 '{', '}', " \t\n", true);
739 if ( err > 0 ) {
740 string c, a;
741 string::size_type first_pos =
742 FbTk::StringUtil::removeFirstWhitespace(cmd);
743 string::size_type second_pos =
744 cmd.find_first_of(" \t", first_pos);
745 if (second_pos != string::npos) {
746 a= cmd.substr(second_pos);
747 FbTk::StringUtil::removeFirstWhitespace(a);
748 cmd.erase(second_pos);
749 }
750 c= FbTk::StringUtil::toLower(cmd);
751
752 FbTk::Command* fbcmd= stringToCommand(c,a,trusted);
753 if (fbcmd) {
754 FbTk::RefCount<FbTk::Command> rfbcmd(fbcmd);
755 macro->add(rfbcmd);
756 }
757 } else
758 break;
759 }
760
761 if ( macro->size() > 0 )
762 return macro;
763
764 delete macro;
765 } else if (command == "togglecmd") {
766 string cmd;
767 int err= 0;
768 int parse_pos= 0;
769 FbTk::ToggleCommand* macro= new FbTk::ToggleCommand();
770
771 while (true) {
772 parse_pos+= err;
773 err= FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() +
774 parse_pos,
775 '{', '}', " \t\n", true);
776 if ( err > 0 ) {
777 string c, a;
778 string::size_type first_pos =
779 FbTk::StringUtil::removeFirstWhitespace(cmd);
780 string::size_type second_pos=
781 cmd.find_first_of(" \t", first_pos);
782 if (second_pos != string::npos) {
783 a= cmd.substr(second_pos);
784 FbTk::StringUtil::removeFirstWhitespace(a);
785 cmd.erase(second_pos);
786 }
787 c= FbTk::StringUtil::toLower(cmd);
788
789 FbTk::Command* fbcmd= stringToCommand(c,a,trusted);
790 if (fbcmd) {
791 FbTk::RefCount<FbTk::Command> rfbcmd(fbcmd);
792 macro->add(rfbcmd);
793 }
794 } else
795 break;
796 }
797
798 if ( macro->size() > 0 )
799 return macro;
800
801 delete macro;
802 } else if (command == "if" || command == "cond") {
803 string cmd;
804 int err = 0, pos = 0;
805 RefCount<BoolCommand> cond(0);
806 RefCount<Command> t(0), f(0);
807
808 err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str(),
809 '{', '}', " \t\n", true);
810 if (err > 0)
811 cond = parseBoolCommand(cmd, trusted);
812 if (err == 0 || *cond == 0)
813 return 0;
814
815 pos = err;
816 err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos,
817 '{', '}', " \t\n", true);
818 if (err == 0)
819 return 0;
820 t = CommandParser::instance().parseLine(cmd, trusted);
821
822 pos += err;
823 err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos,
824 '{', '}', " \t\n", true);
825 if (err > 0)
826 f = CommandParser::instance().parseLine(cmd, trusted);
827 if (err == 0 || *t == 0 && *f == 0)
828 return 0;
829
830 return new FbTk::IfCommand(cond, t, f);
831 }
832 return 0;
833}
diff --git a/src/FbCommandFactory.hh b/src/FbCommandFactory.hh
deleted file mode 100644
index 4b68499..0000000
--- a/src/FbCommandFactory.hh
+++ /dev/null
@@ -1,35 +0,0 @@
1// FbCommandFactory.hh for Fluxbox Window manager
2// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
3// and Simon Bowden (rathnor at users.sourceforge.net)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23// $Id$
24
25#include "CommandParser.hh"
26
27class FbCommandFactory: public CommandFactory {
28public:
29 FbTk::Command *stringToCommand(const std::string &command,
30 const std::string &arguments, bool trusted);
31
32private:
33 FbCommandFactory();
34 static FbCommandFactory s_autoreg; ///< autoregister variable
35};
diff --git a/src/FbCommands.cc b/src/FbCommands.cc
index de14f73..0d4e0e3 100644
--- a/src/FbCommands.cc
+++ b/src/FbCommands.cc
@@ -33,6 +33,9 @@
33 33
34#include "FbTk/Theme.hh" 34#include "FbTk/Theme.hh"
35#include "FbTk/Menu.hh" 35#include "FbTk/Menu.hh"
36#include "FbTk/CommandRegistry.hh"
37#include "FbTk/StringUtil.hh"
38#include "FbTk/stringstream.hh"
36 39
37#include <sys/types.h> 40#include <sys/types.h>
38#include <unistd.h> 41#include <unistd.h>
@@ -120,6 +123,10 @@ void showMenu(const BScreen &screen, FbTk::Menu &menu) {
120 123
121namespace FbCommands { 124namespace FbCommands {
122 125
126REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(exec, FbCommands::ExecuteCmd);
127REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(execute, FbCommands::ExecuteCmd);
128REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(execcommand, FbCommands::ExecuteCmd);
129
123ExecuteCmd::ExecuteCmd(const string &cmd, int screen_num):m_cmd(cmd), m_screen_num(screen_num) { 130ExecuteCmd::ExecuteCmd(const string &cmd, int screen_num):m_cmd(cmd), m_screen_num(screen_num) {
124 131
125} 132}
@@ -169,6 +176,27 @@ int ExecuteCmd::run() {
169 return pid; // compiler happy -> we are happy ;) 176 return pid; // compiler happy -> we are happy ;)
170} 177}
171 178
179FbTk::Command *ExportCmd::parse(const string &command, const string &args,
180 bool trusted) {
181 string name = args;
182 FbTk::StringUtil::removeFirstWhitespace(name);
183 if (command != "setresourcevalue")
184 FbTk::StringUtil::removeTrailingWhitespace(name);
185 size_t pos = name.find_first_of(command == "export" ? "=" : " \t");
186 if (pos == string::npos || pos == name.size() || !trusted)
187 return 0;
188
189 string value = name.substr(pos + 1);
190 name = name.substr(0, pos);
191 if (command == "setresourcevalue")
192 return new SetResourceValueCmd(name, value);
193 return new ExportCmd(name, value);
194}
195
196REGISTER_COMMAND_PARSER(setenv, ExportCmd::parse);
197REGISTER_COMMAND_PARSER(export, ExportCmd::parse);
198REGISTER_COMMAND_PARSER(setresourcevalue, ExportCmd::parse);
199
172ExportCmd::ExportCmd(const string& name, const string& value) : 200ExportCmd::ExportCmd(const string& name, const string& value) :
173 m_name(name), m_value(value) { 201 m_name(name), m_value(value) {
174} 202}
@@ -205,15 +233,21 @@ void ExportCmd::execute() {
205 } 233 }
206} 234}
207 235
236REGISTER_COMMAND(exit, FbCommands::ExitFluxboxCmd);
237REGISTER_COMMAND(quit, FbCommands::ExitFluxboxCmd);
208 238
209void ExitFluxboxCmd::execute() { 239void ExitFluxboxCmd::execute() {
210 Fluxbox::instance()->shutdown(); 240 Fluxbox::instance()->shutdown();
211} 241}
212 242
243REGISTER_COMMAND(saverc, FbCommands::SaveResources);
244
213void SaveResources::execute() { 245void SaveResources::execute() {
214 Fluxbox::instance()->save_rc(); 246 Fluxbox::instance()->save_rc();
215} 247}
216 248
249REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(restart, FbCommands::RestartFluxboxCmd);
250
217RestartFluxboxCmd::RestartFluxboxCmd(const string &cmd):m_cmd(cmd){ 251RestartFluxboxCmd::RestartFluxboxCmd(const string &cmd):m_cmd(cmd){
218} 252}
219 253
@@ -224,16 +258,22 @@ void RestartFluxboxCmd::execute() {
224 Fluxbox::instance()->restart(m_cmd.c_str()); 258 Fluxbox::instance()->restart(m_cmd.c_str());
225} 259}
226 260
261REGISTER_COMMAND(reconfigure, FbCommands::ReconfigureFluxboxCmd);
262REGISTER_COMMAND(reconfig, FbCommands::ReconfigureFluxboxCmd);
263
227void ReconfigureFluxboxCmd::execute() { 264void ReconfigureFluxboxCmd::execute() {
228 Fluxbox::instance()->reconfigure(); 265 Fluxbox::instance()->reconfigure();
229} 266}
230 267
268REGISTER_COMMAND(reloadstyle, FbCommands::ReloadStyleCmd);
231 269
232void ReloadStyleCmd::execute() { 270void ReloadStyleCmd::execute() {
233 SetStyleCmd cmd(Fluxbox::instance()->getStyleFilename()); 271 SetStyleCmd cmd(Fluxbox::instance()->getStyleFilename());
234 cmd.execute(); 272 cmd.execute();
235} 273}
236 274
275REGISTER_COMMAND_WITH_ARGS(setstyle, FbCommands::SetStyleCmd);
276
237SetStyleCmd::SetStyleCmd(const string &filename):m_filename(filename) { 277SetStyleCmd::SetStyleCmd(const string &filename):m_filename(filename) {
238 278
239} 279}
@@ -245,6 +285,8 @@ void SetStyleCmd::execute() {
245 Fluxbox::instance()->getStyleOverlayFilename()); 285 Fluxbox::instance()->getStyleOverlayFilename());
246} 286}
247 287
288REGISTER_COMMAND_WITH_ARGS(keymode, FbCommands::KeyModeCmd);
289
248KeyModeCmd::KeyModeCmd(const string &arguments):m_keymode(arguments),m_end_args("None Escape") { 290KeyModeCmd::KeyModeCmd(const string &arguments):m_keymode(arguments),m_end_args("None Escape") {
249 string::size_type second_pos = m_keymode.find_first_of(" \t", 0); 291 string::size_type second_pos = m_keymode.find_first_of(" \t", 0);
250 if (second_pos != string::npos) { 292 if (second_pos != string::npos) {
@@ -260,10 +302,22 @@ void KeyModeCmd::execute() {
260 Fluxbox::instance()->keys()->keyMode(m_keymode); 302 Fluxbox::instance()->keys()->keyMode(m_keymode);
261} 303}
262 304
305REGISTER_COMMAND(hidemenus, FbCommands::HideMenuCmd);
306
263void HideMenuCmd::execute() { 307void HideMenuCmd::execute() {
264 FbTk::Menu::hideShownMenu(); 308 FbTk::Menu::hideShownMenu();
265} 309}
266 310
311FbTk::Command *ShowClientMenuCmd::parse(const string &command,
312 const string &args, bool trusted) {
313 int opts;
314 string pat;
315 FocusableList::parseArgs(args, opts, pat);
316 return new ShowClientMenuCmd(opts, pat);
317}
318
319REGISTER_COMMAND_PARSER(clientmenu, ShowClientMenuCmd::parse);
320
267void ShowClientMenuCmd::execute() { 321void ShowClientMenuCmd::execute() {
268 BScreen *screen = Fluxbox::instance()->mouseScreen(); 322 BScreen *screen = Fluxbox::instance()->mouseScreen();
269 if (screen == 0) 323 if (screen == 0)
@@ -285,6 +339,8 @@ void ShowClientMenuCmd::execute() {
285 ::showMenu(*screen, **m_menu); 339 ::showMenu(*screen, **m_menu);
286} 340}
287 341
342REGISTER_COMMAND_WITH_ARGS(custommenu, FbCommands::ShowCustomMenuCmd);
343
288ShowCustomMenuCmd::ShowCustomMenuCmd(const string &arguments) : custom_menu_file(arguments) {} 344ShowCustomMenuCmd::ShowCustomMenuCmd(const string &arguments) : custom_menu_file(arguments) {}
289 345
290void ShowCustomMenuCmd::execute() { 346void ShowCustomMenuCmd::execute() {
@@ -298,6 +354,8 @@ void ShowCustomMenuCmd::execute() {
298 ::showMenu(*screen, **m_menu); 354 ::showMenu(*screen, **m_menu);
299} 355}
300 356
357REGISTER_COMMAND(rootmenu, FbCommands::ShowRootMenuCmd);
358
301void ShowRootMenuCmd::execute() { 359void ShowRootMenuCmd::execute() {
302 BScreen *screen = Fluxbox::instance()->mouseScreen(); 360 BScreen *screen = Fluxbox::instance()->mouseScreen();
303 if (screen == 0) 361 if (screen == 0)
@@ -306,6 +364,8 @@ void ShowRootMenuCmd::execute() {
306 ::showMenu(*screen, screen->rootMenu()); 364 ::showMenu(*screen, screen->rootMenu());
307} 365}
308 366
367REGISTER_COMMAND(workspacemenu, FbCommands::ShowWorkspaceMenuCmd);
368
309void ShowWorkspaceMenuCmd::execute() { 369void ShowWorkspaceMenuCmd::execute() {
310 BScreen *screen = Fluxbox::instance()->mouseScreen(); 370 BScreen *screen = Fluxbox::instance()->mouseScreen();
311 if (screen == 0) 371 if (screen == 0)
@@ -314,10 +374,13 @@ void ShowWorkspaceMenuCmd::execute() {
314 ::showMenu(*screen, screen->workspaceMenu()); 374 ::showMenu(*screen, screen->workspaceMenu());
315} 375}
316 376
317 377REGISTER_COMMAND_WITH_ARGS(setworkspacename, FbCommands::SetWorkspaceNameCmd);
318 378
319SetWorkspaceNameCmd::SetWorkspaceNameCmd(const string &name, int spaceid): 379SetWorkspaceNameCmd::SetWorkspaceNameCmd(const string &name, int spaceid):
320 m_name(name), m_workspace(spaceid) { } 380 m_name(name), m_workspace(spaceid) {
381 if (name.empty())
382 m_name = "empty";
383}
321 384
322void SetWorkspaceNameCmd::execute() { 385void SetWorkspaceNameCmd::execute() {
323 BScreen *screen = Fluxbox::instance()->mouseScreen(); 386 BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -340,6 +403,8 @@ void SetWorkspaceNameCmd::execute() {
340 Fluxbox::instance()->save_rc(); 403 Fluxbox::instance()->save_rc();
341} 404}
342 405
406REGISTER_COMMAND(setworkspacenamedialog, FbCommands::WorkspaceNameDialogCmd);
407
343void WorkspaceNameDialogCmd::execute() { 408void WorkspaceNameDialogCmd::execute() {
344 409
345 BScreen *screen = Fluxbox::instance()->mouseScreen(); 410 BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -351,6 +416,8 @@ void WorkspaceNameDialogCmd::execute() {
351 win->show(); 416 win->show();
352} 417}
353 418
419REGISTER_COMMAND(commanddialog, FbCommands::CommandDialogCmd);
420
354void CommandDialogCmd::execute() { 421void CommandDialogCmd::execute() {
355 BScreen *screen = Fluxbox::instance()->mouseScreen(); 422 BScreen *screen = Fluxbox::instance()->mouseScreen();
356 if (screen == 0) 423 if (screen == 0)
@@ -376,6 +443,8 @@ void SetResourceValueCmd::execute() {
376 Fluxbox::instance()->save_rc(); 443 Fluxbox::instance()->save_rc();
377} 444}
378 445
446REGISTER_COMMAND(setresourcevaluedialog, FbCommands::SetResourceValueDialogCmd);
447
379void SetResourceValueDialogCmd::execute() { 448void SetResourceValueDialogCmd::execute() {
380 BScreen *screen = Fluxbox::instance()->mouseScreen(); 449 BScreen *screen = Fluxbox::instance()->mouseScreen();
381 if (screen == 0) 450 if (screen == 0)
@@ -385,6 +454,8 @@ void SetResourceValueDialogCmd::execute() {
385 win->show(); 454 win->show();
386}; 455};
387 456
457REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(bindkey, FbCommands::BindKeyCmd);
458
388BindKeyCmd::BindKeyCmd(const string &keybind):m_keybind(keybind) { } 459BindKeyCmd::BindKeyCmd(const string &keybind):m_keybind(keybind) { }
389 460
390void BindKeyCmd::execute() { 461void BindKeyCmd::execute() {
@@ -398,6 +469,41 @@ void BindKeyCmd::execute() {
398 } 469 }
399} 470}
400 471
472FbTk::Command *DeiconifyCmd::parse(const string &command, const string &args,
473 bool trusted) {
474 FbTk_istringstream iss(args.c_str());
475 string mode;
476 string d;
477 Destination dest;
478
479 iss >> mode;
480 if (iss.fail())
481 mode="lastworkspace";
482 mode= FbTk::StringUtil::toLower(mode);
483
484 iss >> d;
485 if (iss.fail())
486 d="current";
487 d = FbTk::StringUtil::toLower(d);
488 if (d == "origin" )
489 dest = ORIGIN;
490 else if (d == "originquiet")
491 dest = ORIGINQUIET;
492 else
493 dest = CURRENT;
494
495 if (mode == "all")
496 return new DeiconifyCmd(DeiconifyCmd::ALL, dest);
497 else if (mode == "allworkspace")
498 return new DeiconifyCmd(DeiconifyCmd::ALLWORKSPACE, dest);
499 else if (mode == "last")
500 return new DeiconifyCmd(DeiconifyCmd::LAST, dest);
501 // lastworkspace, default
502 return new DeiconifyCmd(DeiconifyCmd::LASTWORKSPACE, dest);
503}
504
505REGISTER_COMMAND_PARSER(deiconify, DeiconifyCmd::parse);
506
401DeiconifyCmd::DeiconifyCmd(Mode mode, 507DeiconifyCmd::DeiconifyCmd(Mode mode,
402 Destination dest) : m_mode(mode), m_dest(dest) { } 508 Destination dest) : m_mode(mode), m_dest(dest) { }
403 509
diff --git a/src/FbCommands.hh b/src/FbCommands.hh
index c130050..566b17a 100644
--- a/src/FbCommands.hh
+++ b/src/FbCommands.hh
@@ -57,6 +57,8 @@ class ExportCmd : public FbTk::Command {
57public: 57public:
58 ExportCmd(const std::string& name, const std::string& value); 58 ExportCmd(const std::string& name, const std::string& value);
59 void execute(); 59 void execute();
60 static FbTk::Command *parse(const std::string &command,
61 const std::string &args, bool trusted);
60private: 62private:
61 std::string m_name; 63 std::string m_name;
62 std::string m_value; 64 std::string m_value;
@@ -121,6 +123,8 @@ public:
121 ShowClientMenuCmd(int option, std::string &pat): 123 ShowClientMenuCmd(int option, std::string &pat):
122 m_option(option|FocusableList::LIST_GROUPS), m_pat(pat.c_str()) { } 124 m_option(option|FocusableList::LIST_GROUPS), m_pat(pat.c_str()) { }
123 void execute(); 125 void execute();
126 static FbTk::Command *parse(const std::string &command,
127 const std::string &args, bool trusted);
124private: 128private:
125 const int m_option; 129 const int m_option;
126 const ClientPattern m_pat; 130 const ClientPattern m_pat;
@@ -208,6 +212,8 @@ public:
208 DeiconifyCmd(Mode mode= LASTWORKSPACE, 212 DeiconifyCmd(Mode mode= LASTWORKSPACE,
209 Destination dest= CURRENT); 213 Destination dest= CURRENT);
210 void execute(); 214 void execute();
215 static FbTk::Command *parse(const std::string &command,
216 const std::string &args, bool trusted);
211private: 217private:
212 Mode m_mode; 218 Mode m_mode;
213 Destination m_dest; 219 Destination m_dest;
diff --git a/src/FbTk/CommandRegistry.cc b/src/FbTk/CommandRegistry.cc
new file mode 100644
index 0000000..1d16c75
--- /dev/null
+++ b/src/FbTk/CommandRegistry.cc
@@ -0,0 +1,92 @@
1// CommandRegistry.cc for FbTk
2// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: $
23
24#include "CommandRegistry.hh"
25#include "Command.hh"
26#include "StringUtil.hh"
27
28#include <iostream>
29
30namespace FbTk {
31
32CommandRegistry &CommandRegistry::instance() {
33 static CommandRegistry s_instance;
34 return s_instance;
35}
36
37
38bool CommandRegistry::registerCommand(string name,
39 CreateFunction createFunction) {
40 name = StringUtil::toLower(name);
41 m_commandCreators[name] = createFunction;
42 return true;
43}
44
45bool CommandRegistry::registerBoolCommand(string name,
46 BoolCreateFunction createFunction) {
47 name = StringUtil::toLower(name);
48 m_boolcommandCreators[name] = createFunction;
49 return true;
50}
51
52Command *CommandRegistry::parseLine(const string &line, bool trusted) const {
53 // parse args and command
54 string command, args;
55 StringUtil::getFirstWord(line, command, args);
56
57 // now we have parsed command and args
58 command = StringUtil::toLower(command);
59 return getCommand(command, args, trusted);
60}
61
62BoolCommand *CommandRegistry::parseBoolLine(const string &line, bool trusted) const {
63 // parse args and command
64 string command, args;
65 StringUtil::getFirstWord(line, command, args);
66
67 // now we have parsed command and args
68 command = StringUtil::toLower(command);
69 return getBoolCommand(command, args, trusted);
70}
71
72Command *CommandRegistry::getCommand(const string &name, const string &args,
73 bool trusted) const {
74 string lc = StringUtil::toLower(name);
75 CreatorMap::const_iterator it = m_commandCreators.find(lc.c_str());
76 if (it == m_commandCreators.end())
77 return 0;
78 else
79 return it->second(name, args, trusted);
80}
81
82BoolCommand *CommandRegistry::getBoolCommand(const string &name,
83 const string &args, bool trusted) const {
84 string lc = StringUtil::toLower(name);
85 BoolCreatorMap::const_iterator it = m_boolcommandCreators.find(lc.c_str());
86 if (it == m_boolcommandCreators.end())
87 return 0;
88 else
89 return it->second(name, args, trusted);
90}
91
92}; // end namespace FbTk
diff --git a/src/FbTk/CommandRegistry.hh b/src/FbTk/CommandRegistry.hh
new file mode 100644
index 0000000..f3b6880
--- /dev/null
+++ b/src/FbTk/CommandRegistry.hh
@@ -0,0 +1,130 @@
1// CommandRegistry.hh for FbTk
2// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: $
23
24#ifndef COMMANDREGISTRY_HH
25#define COMMANDREGISTRY_HH
26
27#include <string>
28#include <map>
29
30using std::string;
31
32namespace FbTk {
33class Command;
34class BoolCommand;
35
36#define REGISTER_COMMAND_PARSER(name, parser) \
37 namespace { \
38 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, parser); \
39 }
40
41#define REGISTER_BOOLCOMMAND_PARSER(name, parser) \
42 namespace { \
43 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerBoolCommand(#name, parser); \
44 }
45
46/* Include some basic command creators */
47template <typename Cmd, typename Ret>
48Ret *CommandCreator(const string &name, const string &args, bool trusted) {
49 return new Cmd();
50}
51
52#define REGISTER_COMMAND(name, classname) \
53 namespace { \
54 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::CommandCreator<classname, FbTk::Command>); \
55 }
56
57template <typename Cmd, typename Ret>
58Ret *CommandCreatorWithArgs(const string &name, const string &args,
59 bool trusted) {
60 return new Cmd(args);
61}
62
63#define REGISTER_COMMAND_WITH_ARGS(name, classname) \
64 namespace { \
65 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::CommandCreatorWithArgs<classname, FbTk::Command>); \
66 }
67
68#define REGISTER_BOOLCOMMAND_WITH_ARGS(name, classname) \
69 namespace { \
70 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerBoolCommand(#name, FbTk::CommandCreatorWithArgs<classname, FbTk::BoolCommand>); \
71 }
72
73template <typename Cmd, typename Ret>
74Ret *UntrustedCommandCreator(const string &name, const string &args,
75 bool trusted) {
76 if (!trusted) return 0;
77 return new Cmd();
78}
79
80#define REGISTER_UNTRUSTED_COMMAND(name, classname) \
81 namespace { \
82 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::UntrustedCommandCreator<classname, FbTk::Command>); \
83 }
84
85template <typename Cmd, typename Ret>
86Ret * UntrustedCommandCreatorWithArgs(const string &name, const string &args,
87 bool trusted) {
88 if (!trusted) return 0;
89 return new Cmd(args);
90}
91
92#define REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(name, classname) \
93 namespace { \
94 static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::UntrustedCommandCreatorWithArgs<classname, FbTk::Command>); \
95 }
96
97/* Not built to be virtual at the moment */
98class CommandRegistry {
99public:
100 typedef Command * CreateFunction(const string &name, const string &args, bool trusted);
101 typedef BoolCommand * BoolCreateFunction(const string &name,
102 const string &args, bool trusted);
103 typedef std::map<string, CreateFunction *> CreatorMap;
104 typedef std::map<string, BoolCreateFunction *> BoolCreatorMap;
105
106 static CommandRegistry &instance();
107
108 Command *parseLine(const string &line, bool trusted = true) const;
109 BoolCommand *parseBoolLine(const string &line, bool trusted = true) const;
110 Command *getCommand(const string &name, const string &args, bool trusted) const;
111 BoolCommand *getBoolCommand(const string &name, const string &args,
112 bool trusted) const;
113
114 /* Note: the ownership of this object passes to this class */
115 bool registerCommand(string name, CreateFunction createFunction);
116 bool registerBoolCommand(string name, BoolCreateFunction bcf);
117
118 const CreatorMap commandMap() const { return m_commandCreators; }
119
120private:
121 CommandRegistry() {}
122 ~CommandRegistry() {}
123
124 CreatorMap m_commandCreators;
125 BoolCreatorMap m_boolcommandCreators;
126};
127
128}; // end namespace FbTk
129
130#endif // COMMANDREGISTRY_HH
diff --git a/src/FbTk/LogicCommands.cc b/src/FbTk/LogicCommands.cc
index 99b5b53..1c6f238 100644
--- a/src/FbTk/LogicCommands.cc
+++ b/src/FbTk/LogicCommands.cc
@@ -23,8 +23,101 @@
23 23
24#include "LogicCommands.hh" 24#include "LogicCommands.hh"
25 25
26#include "CommandRegistry.hh"
27#include "StringUtil.hh"
28
29using FbTk::StringUtil::removeFirstWhitespace;
30using FbTk::StringUtil::toLower;
31using std::string;
32
26namespace FbTk { 33namespace FbTk {
27 34
35namespace {
36
37template <typename M>
38M *addCommands(M *macro, const string &args, bool trusted) {
39 int pos = 0, err = 0;
40 string cmd;
41
42 while (true) {
43 RefCount<BoolCommand> tmp(0);
44 err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
45 '{', '}', " \t\n", true);
46 pos += err;
47 if (err == 0)
48 break;
49
50 tmp = CommandRegistry::instance().parseBoolLine(cmd, trusted);
51 if (*tmp)
52 macro->add(tmp);
53 }
54
55 if (macro->size() > 0)
56 return macro;
57 delete macro;
58 return 0;
59}
60
61BoolCommand *parseLogicCommand(const string &command, const string &args,
62 bool trusted) {
63 if (command == "not") {
64 BoolCommand *boolcmd =
65 CommandRegistry::instance().parseBoolLine(args, trusted);
66 if (!boolcmd)
67 return 0;
68 RefCount<BoolCommand> ref(boolcmd);
69 return new NotCommand(ref);
70 } else if (command == "and")
71 return addCommands<AndCommand>(new AndCommand(), args, trusted);
72 else if (command == "or")
73 return addCommands<OrCommand>(new OrCommand(), args, trusted);
74 else if (command == "xor")
75 return addCommands<XorCommand>(new XorCommand(), args, trusted);
76 return 0;
77}
78
79REGISTER_BOOLCOMMAND_PARSER(not, parseLogicCommand);
80REGISTER_BOOLCOMMAND_PARSER(and, parseLogicCommand);
81REGISTER_BOOLCOMMAND_PARSER(or, parseLogicCommand);
82REGISTER_BOOLCOMMAND_PARSER(xor, parseLogicCommand);
83
84}; // end anonymous namespace
85
86Command *IfCommand::parse(const std::string &command, const std::string &args,
87 bool trusted) {
88 std::string cmd;
89 int err = 0, pos = 0;
90 RefCount<BoolCommand> cond(0);
91 RefCount<Command> t(0), f(0);
92
93 err = StringUtil::getStringBetween(cmd, args.c_str(),
94 '{', '}', " \t\n", true);
95 if (err > 0)
96 cond = CommandRegistry::instance().parseBoolLine(cmd, trusted);
97 if (err == 0 || *cond == 0)
98 return 0;
99
100 pos = err;
101 err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
102 '{', '}', " \t\n", true);
103 if (err == 0)
104 return 0;
105 t = CommandRegistry::instance().parseLine(cmd, trusted);
106
107 pos += err;
108 err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
109 '{', '}', " \t\n", true);
110 if (err > 0)
111 f = CommandRegistry::instance().parseLine(cmd, trusted);
112 if (err == 0 || *t == 0 && *f == 0)
113 return 0;
114
115 return new IfCommand(cond, t, f);
116}
117
118REGISTER_COMMAND_PARSER(if, IfCommand::parse);
119REGISTER_COMMAND_PARSER(cond, IfCommand::parse);
120
28void OrCommand::add(RefCount<BoolCommand> &com) { 121void OrCommand::add(RefCount<BoolCommand> &com) {
29 m_commandlist.push_back(com); 122 m_commandlist.push_back(com);
30} 123}
diff --git a/src/FbTk/LogicCommands.hh b/src/FbTk/LogicCommands.hh
index 4f20864..3eb3e8c 100644
--- a/src/FbTk/LogicCommands.hh
+++ b/src/FbTk/LogicCommands.hh
@@ -27,6 +27,7 @@
27#include "Command.hh" 27#include "Command.hh"
28#include "RefCount.hh" 28#include "RefCount.hh"
29 29
30#include <string>
30#include <vector> 31#include <vector>
31 32
32namespace FbTk { 33namespace FbTk {
@@ -43,7 +44,8 @@ public:
43 } else 44 } else
44 if (*m_f) m_f->execute(); 45 if (*m_f) m_f->execute();
45 } 46 }
46 47 static Command *parse(const std::string &cmd, const std::string &args,
48 bool trusted);
47private: 49private:
48 RefCount<BoolCommand> m_cond; 50 RefCount<BoolCommand> m_cond;
49 RefCount<Command> m_t, m_f; 51 RefCount<Command> m_t, m_f;
diff --git a/src/FbTk/MacroCommand.cc b/src/FbTk/MacroCommand.cc
index 491b01e..20e91e4 100644
--- a/src/FbTk/MacroCommand.cc
+++ b/src/FbTk/MacroCommand.cc
@@ -23,8 +23,56 @@
23 23
24#include "MacroCommand.hh" 24#include "MacroCommand.hh"
25 25
26#include "CommandRegistry.hh"
27#include "StringUtil.hh"
28
29#include <string>
30
26namespace FbTk { 31namespace FbTk {
27 32
33namespace {
34
35template <typename M>
36M *addCommands(M *macro, const std::string &args, bool trusted) {
37
38 std::string cmd;
39 int err = 0;
40 int pos = 0;
41
42 while (true) {
43 RefCount<Command> next(0);
44 pos += err;
45 err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
46 '{', '}', " \t\n", true);
47 if (err == 0)
48 break;
49 if (err > 0)
50 next = CommandRegistry::instance().parseLine(cmd, trusted);
51 if (*next != 0)
52 macro->add(next);
53 }
54
55 if (macro->size() > 0)
56 return macro;
57
58 delete macro;
59 return 0;
60}
61
62Command *parseMacroCmd(const std::string &command, const std::string &args,
63 bool trusted) {
64 if (command == "macrocmd")
65 return addCommands<MacroCommand>(new MacroCommand, args, trusted);
66 else if (command == "togglecmd")
67 return addCommands<ToggleCommand>(new ToggleCommand, args, trusted);
68 return 0;
69}
70
71REGISTER_COMMAND_PARSER(macrocmd, parseMacroCmd);
72REGISTER_COMMAND_PARSER(togglecmd, parseMacroCmd);
73
74}; // end anonymous namespace
75
28void MacroCommand::add(RefCount<Command> &com) { 76void MacroCommand::add(RefCount<Command> &com) {
29 m_commandlist.push_back(com); 77 m_commandlist.push_back(com);
30} 78}
diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am
index 2bf9da7..f3e928d 100644
--- a/src/FbTk/Makefile.am
+++ b/src/FbTk/Makefile.am
@@ -16,6 +16,7 @@ imlib2_SOURCE= ImageImlib2.hh ImageImlib2.cc
16endif 16endif
17 17
18libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \ 18libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
19 CommandRegistry.hh CommandRegistry.cc \
19 FileUtil.hh FileUtil.cc \ 20 FileUtil.hh FileUtil.cc \
20 EventHandler.hh EventManager.hh EventManager.cc \ 21 EventHandler.hh EventManager.hh EventManager.cc \
21 FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \ 22 FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \
diff --git a/src/FbTk/StringUtil.cc b/src/FbTk/StringUtil.cc
index 869a3b5..9b4928b 100644
--- a/src/FbTk/StringUtil.cc
+++ b/src/FbTk/StringUtil.cc
@@ -233,6 +233,18 @@ string::size_type removeTrailingWhitespace(string &str) {
233 return first_pos; 233 return first_pos;
234} 234}
235 235
236void getFirstWord(const std::string &in, std::string &word, std::string &rest) {
237 word = in;
238 string::size_type first_pos = StringUtil::removeFirstWhitespace(word);
239 string::size_type second_pos = word.find_first_of(" \t", first_pos);
240 if (second_pos != string::npos) {
241 rest = word.substr(second_pos);
242 word.erase(second_pos);
243 removeFirstWhitespace(rest);
244 removeTrailingWhitespace(rest);
245 }
246}
247
236}; // end namespace StringUtil 248}; // end namespace StringUtil
237 249
238}; // end namespace FbTk 250}; // end namespace FbTk
diff --git a/src/FbTk/StringUtil.hh b/src/FbTk/StringUtil.hh
index b45d6a2..7f0cf54 100644
--- a/src/FbTk/StringUtil.hh
+++ b/src/FbTk/StringUtil.hh
@@ -64,6 +64,9 @@ std::string basename(const std::string &basename);
64std::string::size_type removeFirstWhitespace(std::string &str); 64std::string::size_type removeFirstWhitespace(std::string &str);
65std::string::size_type removeTrailingWhitespace(std::string &str); 65std::string::size_type removeTrailingWhitespace(std::string &str);
66 66
67/// removes the first part of a string and returns the two pieces
68void getFirstWord(const std::string &in, std::string &first, std::string &rest);
69
67/// Breaks a string into tokens 70/// Breaks a string into tokens
68template <typename Container> 71template <typename Container>
69static void 72static void
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc
index 2574762..f0179d1 100644
--- a/src/IconbarTool.cc
+++ b/src/IconbarTool.cc
@@ -33,7 +33,7 @@
33#include "Workspace.hh" 33#include "Workspace.hh"
34#include "FbMenu.hh" 34#include "FbMenu.hh"
35#include "BoolMenuItem.hh" 35#include "BoolMenuItem.hh"
36#include "CommandParser.hh" 36#include "FbTk/CommandRegistry.hh"
37#include "WinClient.hh" 37#include "WinClient.hh"
38#include "FocusControl.hh" 38#include "FocusControl.hh"
39#include "FbCommands.hh" 39#include "FbCommands.hh"
@@ -282,7 +282,7 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme,
282 // setup use pixmap item to reconfig iconbar and save resource on click 282 // setup use pixmap item to reconfig iconbar and save resource on click
283 MacroCommand *save_and_reconfig = new MacroCommand(); 283 MacroCommand *save_and_reconfig = new MacroCommand();
284 RefCount<Command> reconfig(new SimpleCommand<IconbarTool>(*this, &IconbarTool::renderTheme)); 284 RefCount<Command> reconfig(new SimpleCommand<IconbarTool>(*this, &IconbarTool::renderTheme));
285 RefCount<Command> save(CommandParser::instance().parseLine("saverc")); 285 RefCount<Command> save(FbTk::CommandRegistry::instance().parseLine("saverc"));
286 save_and_reconfig->add(reconfig); 286 save_and_reconfig->add(reconfig);
287 save_and_reconfig->add(save); 287 save_and_reconfig->add(save);
288 RefCount<Command> s_and_reconfig(save_and_reconfig); 288 RefCount<Command> s_and_reconfig(save_and_reconfig);
diff --git a/src/Keys.cc b/src/Keys.cc
index 06a0d48..e102029 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -32,7 +32,7 @@
32#include "FbTk/App.hh" 32#include "FbTk/App.hh"
33#include "FbTk/Command.hh" 33#include "FbTk/Command.hh"
34 34
35#include "CommandParser.hh" 35#include "FbTk/CommandRegistry.hh"
36#include "FbTk/I18n.hh" 36#include "FbTk/I18n.hh"
37 37
38#ifdef HAVE_CONFIG_H 38#ifdef HAVE_CONFIG_H
@@ -395,7 +395,7 @@ bool Keys::addBinding(const string &linebuffer) {
395 const char *str = FbTk::StringUtil::strcasestr(linebuffer.c_str(), 395 const char *str = FbTk::StringUtil::strcasestr(linebuffer.c_str(),
396 val[argc].c_str() + 1); // +1 to skip ':' 396 val[argc].c_str() + 1); // +1 to skip ':'
397 if (str) 397 if (str)
398 current_key->m_command = CommandParser::instance().parseLine(str); 398 current_key->m_command = FbTk::CommandRegistry::instance().parseLine(str);
399 399
400 if (!str || *current_key->m_command == 0 || mod) { 400 if (!str || *current_key->m_command == 0 || mod) {
401 delete first_new_key; 401 delete first_new_key;
diff --git a/src/LayerMenu.hh b/src/LayerMenu.hh
index fcc4edb..4f4a0a9 100644
--- a/src/LayerMenu.hh
+++ b/src/LayerMenu.hh
@@ -64,7 +64,7 @@ private:
64/// Create a layer menu inside from the given menu 64/// Create a layer menu inside from the given menu
65class LayerMenu : public ToggleMenu { 65class LayerMenu : public ToggleMenu {
66public: 66public:
67 LayerMenu(MenuTheme &tm, FbTk::ImageControl &imgctrl, 67 LayerMenu(class MenuTheme &tm, FbTk::ImageControl &imgctrl,
68 FbTk::XLayer &layer, LayerObject *item, bool save_rc); 68 FbTk::XLayer &layer, LayerObject *item, bool save_rc);
69 void show(); 69 void show();
70}; 70};
diff --git a/src/Makefile.am b/src/Makefile.am
index 3ecc610..e718092 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -118,8 +118,6 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
118 Xutil.hh Xutil.cc \ 118 Xutil.hh Xutil.cc \
119 CurrentWindowCmd.hh CurrentWindowCmd.cc \ 119 CurrentWindowCmd.hh CurrentWindowCmd.cc \
120 WorkspaceCmd.hh WorkspaceCmd.cc \ 120 WorkspaceCmd.hh WorkspaceCmd.cc \
121 CommandParser.hh CommandParser.cc \
122 FbCommandFactory.hh FbCommandFactory.cc \
123 Shape.hh Shape.cc \ 121 Shape.hh Shape.cc \
124 MenuTheme.hh MenuTheme.cc \ 122 MenuTheme.hh MenuTheme.cc \
125 Container.hh Container.cc \ 123 Container.hh Container.cc \
@@ -156,4 +154,4 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
156 ${REMEMBER_SOURCE} ${TOOLBAR_SOURCE} 154 ${REMEMBER_SOURCE} ${TOOLBAR_SOURCE}
157 155
158 156
159LDADD=FbTk/libFbTk.a defaults.$(OBJEXT) 157LDADD=FbTk/libFbTk.a FbTk/LogicCommands.o defaults.$(OBJEXT)
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc
index 8cc483a..b98287b 100644
--- a/src/MenuCreator.cc
+++ b/src/MenuCreator.cc
@@ -26,7 +26,7 @@
26 26
27#include "defaults.hh" 27#include "defaults.hh"
28#include "Screen.hh" 28#include "Screen.hh"
29#include "CommandParser.hh" 29#include "FbTk/CommandRegistry.hh"
30#include "fluxbox.hh" 30#include "fluxbox.hh"
31#include "Window.hh" 31#include "Window.hh"
32#include "WindowCmd.hh" 32#include "WindowCmd.hh"
@@ -247,7 +247,7 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
247 else 247 else
248 menu.insert(str_label, submenu); 248 menu.insert(str_label, submenu);
249 } else if (str_key == "exit") { // exit 249 } else if (str_key == "exit") { // exit
250 FbTk::RefCount<FbTk::Command> exit_cmd(CommandParser::instance().parseLine("exit")); 250 FbTk::RefCount<FbTk::Command> exit_cmd(FbTk::CommandRegistry::instance().parseLine("exit"));
251 if (str_label.empty()) 251 if (str_label.empty())
252 menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd); 252 menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd);
253 else 253 else
@@ -255,8 +255,8 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
255 } else if (str_key == "exec") { 255 } else if (str_key == "exec") {
256 // execute and hide menu 256 // execute and hide menu
257 using namespace FbTk; 257 using namespace FbTk;
258 RefCount<Command> exec_cmd(CommandParser::instance().parseLine("exec " + str_cmd)); 258 RefCount<Command> exec_cmd(FbTk::CommandRegistry::instance().parseLine("exec " + str_cmd));
259 RefCount<Command> hide_menu(CommandParser::instance().parseLine("hidemenus")); 259 RefCount<Command> hide_menu(FbTk::CommandRegistry::instance().parseLine("hidemenus"));
260 MacroCommand *exec_and_hide = new FbTk::MacroCommand(); 260 MacroCommand *exec_and_hide = new FbTk::MacroCommand();
261 exec_and_hide->add(hide_menu); 261 exec_and_hide->add(hide_menu);
262 exec_and_hide->add(exec_cmd); 262 exec_and_hide->add(exec_cmd);
@@ -264,8 +264,8 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
264 menu.insert(str_label, exec_and_hide_cmd); 264 menu.insert(str_label, exec_and_hide_cmd);
265 } else if (str_key == "macrocmd") { 265 } else if (str_key == "macrocmd") {
266 using namespace FbTk; 266 using namespace FbTk;
267 RefCount<Command> macro_cmd(CommandParser::instance().parseLine("macrocmd " + str_cmd)); 267 RefCount<Command> macro_cmd(FbTk::CommandRegistry::instance().parseLine("macrocmd " + str_cmd));
268 RefCount<Command> hide_menu(CommandParser::instance().parseLine("hidemenus")); 268 RefCount<Command> hide_menu(FbTk::CommandRegistry::instance().parseLine("hidemenus"));
269 MacroCommand *exec_and_hide = new FbTk::MacroCommand(); 269 MacroCommand *exec_and_hide = new FbTk::MacroCommand();
270 exec_and_hide->add(hide_menu); 270 exec_and_hide->add(hide_menu);
271 exec_and_hide->add(macro_cmd); 271 exec_and_hide->add(macro_cmd);
@@ -364,7 +364,7 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
364 else { // ok, if we didn't find any special menu item we try with command parser 364 else { // ok, if we didn't find any special menu item we try with command parser
365 // we need to attach command with arguments so command parser can parse it 365 // we need to attach command with arguments so command parser can parse it
366 string line = str_key + " " + str_cmd; 366 string line = str_key + " " + str_cmd;
367 FbTk::RefCount<FbTk::Command> command(CommandParser::instance().parseLine(line)); 367 FbTk::RefCount<FbTk::Command> command(FbTk::CommandRegistry::instance().parseLine(line));
368 if (*command != 0) { 368 if (*command != 0) {
369 // special NLS default labels 369 // special NLS default labels
370 if (str_label.empty()) { 370 if (str_label.empty()) {
diff --git a/src/Screen.cc b/src/Screen.cc
index 79a75ef..1651824 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -60,7 +60,7 @@
60#include "WinClient.hh" 60#include "WinClient.hh"
61#include "FbWinFrame.hh" 61#include "FbWinFrame.hh"
62#include "Strut.hh" 62#include "Strut.hh"
63#include "CommandParser.hh" 63#include "FbTk/CommandRegistry.hh"
64#include "AtomHandler.hh" 64#include "AtomHandler.hh"
65#include "HeadArea.hh" 65#include "HeadArea.hh"
66#include "FbCommands.hh" 66#include "FbCommands.hh"
@@ -815,7 +815,7 @@ void BScreen::propertyNotify(Atom atom) {
815 &ret_bytes_after, (unsigned char **)&str); 815 &ret_bytes_after, (unsigned char **)&str);
816 } 816 }
817 817
818 FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine(str, false)); 818 FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(str, false));
819 if (cmd.get()) 819 if (cmd.get())
820 cmd->execute(); 820 cmd->execute();
821 XFree(str); 821 XFree(str);
@@ -1531,9 +1531,9 @@ void BScreen::initMenu() {
1531 if (m_rootmenu.get() == 0) { 1531 if (m_rootmenu.get() == 0) {
1532 _FB_USES_NLS; 1532 _FB_USES_NLS;
1533 m_rootmenu.reset(createMenu(_FB_XTEXT(Menu, DefaultRootMenu, "Fluxbox default menu", "Title of fallback root menu"))); 1533 m_rootmenu.reset(createMenu(_FB_XTEXT(Menu, DefaultRootMenu, "Fluxbox default menu", "Title of fallback root menu")));
1534 FbTk::RefCount<FbTk::Command> restart_fb(CommandParser::instance().parseLine("restart")); 1534 FbTk::RefCount<FbTk::Command> restart_fb(FbTk::CommandRegistry::instance().parseLine("restart"));
1535 FbTk::RefCount<FbTk::Command> exit_fb(CommandParser::instance().parseLine("exit")); 1535 FbTk::RefCount<FbTk::Command> exit_fb(FbTk::CommandRegistry::instance().parseLine("exit"));
1536 FbTk::RefCount<FbTk::Command> execute_xterm(CommandParser::instance().parseLine("exec xterm")); 1536 FbTk::RefCount<FbTk::Command> execute_xterm(FbTk::CommandRegistry::instance().parseLine("exec xterm"));
1537 m_rootmenu->setInternalMenu(); 1537 m_rootmenu->setInternalMenu();
1538 m_rootmenu->insert("xterm", execute_xterm); 1538 m_rootmenu->insert("xterm", execute_xterm);
1539 m_rootmenu->insert(_FB_XTEXT(Menu, Restart, "Restart", "Restart command"), 1539 m_rootmenu->insert(_FB_XTEXT(Menu, Restart, "Restart", "Restart command"),
@@ -1578,7 +1578,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1578 FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>( 1578 FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
1579 *Fluxbox::instance(), 1579 *Fluxbox::instance(),
1580 &Fluxbox::save_rc)); 1580 &Fluxbox::save_rc));
1581 FbTk::RefCount<FbTk::Command> reconf_cmd(CommandParser::instance().parseLine("reconfigure")); 1581 FbTk::RefCount<FbTk::Command> reconf_cmd(FbTk::CommandRegistry::instance().parseLine("reconfigure"));
1582 1582
1583 FbTk::RefCount<FbTk::Command> reconftabs_cmd(new FbTk::SimpleCommand<BScreen>( 1583 FbTk::RefCount<FbTk::Command> reconftabs_cmd(new FbTk::SimpleCommand<BScreen>(
1584 *this, 1584 *this,
diff --git a/src/Slit.hh b/src/Slit.hh
index 06a8a25..aa88a5d 100644
--- a/src/Slit.hh
+++ b/src/Slit.hh
@@ -177,7 +177,7 @@ private:
177 FbTk::Resource<Slit::Placement> m_rc_placement; 177 FbTk::Resource<Slit::Placement> m_rc_placement;
178 FbTk::Resource<Slit::Direction> m_rc_direction; 178 FbTk::Resource<Slit::Direction> m_rc_direction;
179 FbTk::Resource<int> m_rc_alpha, m_rc_on_head; 179 FbTk::Resource<int> m_rc_alpha, m_rc_on_head;
180 FbTk::Resource<Layer> m_rc_layernum; 180 FbTk::Resource<class Layer> m_rc_layernum;
181}; 181};
182 182
183 183
diff --git a/src/ToggleMenu.hh b/src/ToggleMenu.hh
index 10c8594..66f33c4 100644
--- a/src/ToggleMenu.hh
+++ b/src/ToggleMenu.hh
@@ -32,7 +32,7 @@
32 */ 32 */
33class ToggleMenu: public FbMenu { 33class ToggleMenu: public FbMenu {
34public: 34public:
35 ToggleMenu(MenuTheme &tm, FbTk::ImageControl &imgctrl, 35 ToggleMenu(class MenuTheme &tm, FbTk::ImageControl &imgctrl,
36 FbTk::XLayer &layer):FbMenu(tm, imgctrl, layer) 36 FbTk::XLayer &layer):FbMenu(tm, imgctrl, layer)
37 {} 37 {}
38 virtual ~ToggleMenu() {} 38 virtual ~ToggleMenu() {}
diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc
index 3fa8714..c54dd19 100644
--- a/src/ToolFactory.cc
+++ b/src/ToolFactory.cc
@@ -36,7 +36,7 @@
36#include "WorkspaceNameTheme.hh" 36#include "WorkspaceNameTheme.hh"
37#include "ButtonTheme.hh" 37#include "ButtonTheme.hh"
38 38
39#include "CommandParser.hh" 39#include "FbTk/CommandRegistry.hh"
40#include "Screen.hh" 40#include "Screen.hh"
41#include "Toolbar.hh" 41#include "Toolbar.hh"
42#include "fluxbox.hh" 42#include "fluxbox.hh"
@@ -107,7 +107,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
107 } else if (name == "nextworkspace" || 107 } else if (name == "nextworkspace" ||
108 name == "prevworkspace") { 108 name == "prevworkspace") {
109 109
110 FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine(name)); 110 FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(name));
111 if (*cmd == 0) // we need a command 111 if (*cmd == 0) // we need a command
112 return 0; 112 return 0;
113 113
@@ -127,7 +127,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
127 } else if (name == "nextwindow" || 127 } else if (name == "nextwindow" ||
128 name == "prevwindow") { 128 name == "prevwindow") {
129 129
130 FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine(name)); 130 FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(name));
131 if (*cmd == 0) // we need a command 131 if (*cmd == 0) // we need a command
132 return 0; 132 return 0;
133 133
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index 55ae1d3..3e446d8 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -44,7 +44,7 @@
44#endif // XINERAMA 44#endif // XINERAMA
45 45
46#include "Strut.hh" 46#include "Strut.hh"
47#include "CommandParser.hh" 47#include "FbTk/CommandRegistry.hh"
48#include "Layer.hh" 48#include "Layer.hh"
49 49
50#include "FbTk/I18n.hh" 50#include "FbTk/I18n.hh"
@@ -823,7 +823,7 @@ void Toolbar::setupMenus(bool skip_new_placement) {
823 "Toolbar", "Title of Toolbar menu")); 823 "Toolbar", "Title of Toolbar menu"));
824 824
825 RefCommand reconfig_toolbar(new ToolbarCommand(*this, &Toolbar::reconfigure)); 825 RefCommand reconfig_toolbar(new ToolbarCommand(*this, &Toolbar::reconfigure));
826 RefCommand save_resources(CommandParser::instance().parseLine("saverc")); 826 RefCommand save_resources(FbTk::CommandRegistry::instance().parseLine("saverc"));
827 MacroCommand *toolbar_menuitem_macro = new MacroCommand(); 827 MacroCommand *toolbar_menuitem_macro = new MacroCommand();
828 toolbar_menuitem_macro->add(reconfig_toolbar); 828 toolbar_menuitem_macro->add(reconfig_toolbar);
829 toolbar_menuitem_macro->add(save_resources); 829 toolbar_menuitem_macro->add(save_resources);
diff --git a/src/Toolbar.hh b/src/Toolbar.hh
index 243ce52..4062f83 100644
--- a/src/Toolbar.hh
+++ b/src/Toolbar.hh
@@ -178,7 +178,7 @@ private:
178 FbTk::Resource<bool> m_rc_auto_hide, m_rc_maximize_over, m_rc_visible; 178 FbTk::Resource<bool> m_rc_auto_hide, m_rc_maximize_over, m_rc_visible;
179 FbTk::Resource<int> m_rc_width_percent; 179 FbTk::Resource<int> m_rc_width_percent;
180 FbTk::Resource<int> m_rc_alpha; 180 FbTk::Resource<int> m_rc_alpha;
181 FbTk::Resource<Layer> m_rc_layernum; 181 FbTk::Resource<class Layer> m_rc_layernum;
182 FbTk::Resource<int> m_rc_on_head; 182 FbTk::Resource<int> m_rc_on_head;
183 FbTk::Resource<Placement> m_rc_placement; 183 FbTk::Resource<Placement> m_rc_placement;
184 FbTk::Resource<int> m_rc_height; 184 FbTk::Resource<int> m_rc_height;
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc
index 536019c..5498b38 100644
--- a/src/WorkspaceCmd.cc
+++ b/src/WorkspaceCmd.cc
@@ -33,6 +33,8 @@
33#include "WindowCmd.hh" 33#include "WindowCmd.hh"
34 34
35#include "FbTk/KeyUtil.hh" 35#include "FbTk/KeyUtil.hh"
36#include "FbTk/CommandRegistry.hh"
37#include "FbTk/stringstream.hh"
36 38
37#ifdef HAVE_CMATH 39#ifdef HAVE_CMATH
38 #include <cmath> 40 #include <cmath>
@@ -42,6 +44,8 @@
42#include <algorithm> 44#include <algorithm>
43#include <functional> 45#include <functional>
44 46
47using std::string;
48
45void WindowListCmd::execute() { 49void WindowListCmd::execute() {
46 if (m_pat.error()) { 50 if (m_pat.error()) {
47 m_cmd->execute(); 51 m_cmd->execute();
@@ -66,6 +70,20 @@ void WindowListCmd::execute() {
66 } 70 }
67} 71}
68 72
73FbTk::BoolCommand *SomeCmd::parse(const string &command, const string &args,
74 bool trusted) {
75 BoolCommand *boolcmd =
76 FbTk::CommandRegistry::instance().parseBoolLine(args, trusted);
77 if (!boolcmd)
78 return 0;
79 if (command == "some")
80 return new SomeCmd(FbTk::RefCount<FbTk::BoolCommand>(boolcmd));
81 return new EveryCmd(FbTk::RefCount<FbTk::BoolCommand>(boolcmd));
82}
83
84REGISTER_BOOLCOMMAND_PARSER(some, SomeCmd::parse);
85REGISTER_BOOLCOMMAND_PARSER(every, SomeCmd::parse);
86
69bool SomeCmd::bool_execute() { 87bool SomeCmd::bool_execute() {
70 BScreen *screen = Fluxbox::instance()->keyScreen(); 88 BScreen *screen = Fluxbox::instance()->keyScreen();
71 if (screen != 0) { 89 if (screen != 0) {
@@ -108,6 +126,37 @@ bool EveryCmd::bool_execute() {
108 return true; 126 return true;
109} 127}
110 128
129namespace {
130
131FbTk::Command *parseWindowList(const string &command,
132 const string &args, bool trusted) {
133 int opts;
134 string pat;
135 FocusableList::parseArgs(args, opts, pat);
136 if (command == "attach")
137 return new AttachCmd(pat);
138 else if (command == "nextwindow")
139 return new NextWindowCmd(opts, pat);
140 else if (command == "nextgroup") {
141 opts |= FocusableList::LIST_GROUPS;
142 return new NextWindowCmd(opts, pat);
143 } else if (command == "prevwindow")
144 return new PrevWindowCmd(opts, pat);
145 else if (command == "prevgroup") {
146 opts |= FocusableList::LIST_GROUPS;
147 return new PrevWindowCmd(opts, pat);
148 }
149 return 0;
150}
151
152REGISTER_COMMAND_PARSER(attach, parseWindowList);
153REGISTER_COMMAND_PARSER(nextwindow, parseWindowList);
154REGISTER_COMMAND_PARSER(nextgroup, parseWindowList);
155REGISTER_COMMAND_PARSER(prevwindow, parseWindowList);
156REGISTER_COMMAND_PARSER(prevgroup, parseWindowList);
157
158}; // end anonymous namespace
159
111void AttachCmd::execute() { 160void AttachCmd::execute() {
112 BScreen *screen = Fluxbox::instance()->keyScreen(); 161 BScreen *screen = Fluxbox::instance()->keyScreen();
113 if (screen != 0) { 162 if (screen != 0) {
@@ -140,6 +189,21 @@ void PrevWindowCmd::execute() {
140 screen->cycleFocus(m_option, &m_pat, true); 189 screen->cycleFocus(m_option, &m_pat, true);
141} 190}
142 191
192FbTk::Command *GoToWindowCmd::parse(const string &command,
193 const string &arguments, bool trusted) {
194 int num, opts;
195 string args, pat;
196 FbTk_istringstream iss(arguments.c_str());
197 iss >> num;
198 string::size_type pos = arguments.find_first_of("({");
199 if (pos != string::npos && pos != arguments.size())
200 args = arguments.c_str() + pos;
201 FocusableList::parseArgs(args, opts, pat);
202 return new GoToWindowCmd(num, opts, pat);
203}
204
205REGISTER_COMMAND_PARSER(gotowindow, GoToWindowCmd::parse);
206
143void GoToWindowCmd::execute() { 207void GoToWindowCmd::execute() {
144 BScreen *screen = Fluxbox::instance()->keyScreen(); 208 BScreen *screen = Fluxbox::instance()->keyScreen();
145 if (screen != 0) { 209 if (screen != 0) {
@@ -149,6 +213,24 @@ void GoToWindowCmd::execute() {
149 } 213 }
150} 214}
151 215
216FbTk::Command *DirFocusCmd::parse(const string &command,
217 const string &args, bool trusted) {
218 if (command == "focusup")
219 return new DirFocusCmd(FocusControl::FOCUSUP);
220 else if (command == "focusdown")
221 return new DirFocusCmd(FocusControl::FOCUSDOWN);
222 else if (command == "focusleft")
223 return new DirFocusCmd(FocusControl::FOCUSLEFT);
224 else if (command == "focusright")
225 return new DirFocusCmd(FocusControl::FOCUSRIGHT);
226 return 0;
227}
228
229REGISTER_COMMAND_PARSER(focusup, DirFocusCmd::parse);
230REGISTER_COMMAND_PARSER(focusdown, DirFocusCmd::parse);
231REGISTER_COMMAND_PARSER(focusleft, DirFocusCmd::parse);
232REGISTER_COMMAND_PARSER(focusright, DirFocusCmd::parse);
233
152void DirFocusCmd::execute() { 234void DirFocusCmd::execute() {
153 BScreen *screen = Fluxbox::instance()->keyScreen(); 235 BScreen *screen = Fluxbox::instance()->keyScreen();
154 if (screen == 0) 236 if (screen == 0)
@@ -159,18 +241,51 @@ void DirFocusCmd::execute() {
159 screen->focusControl().dirFocus(*win, m_dir); 241 screen->focusControl().dirFocus(*win, m_dir);
160} 242}
161 243
244REGISTER_COMMAND(addworkspace, AddWorkspaceCmd);
245
162void AddWorkspaceCmd::execute() { 246void AddWorkspaceCmd::execute() {
163 BScreen *screen = Fluxbox::instance()->mouseScreen(); 247 BScreen *screen = Fluxbox::instance()->mouseScreen();
164 if (screen != 0) 248 if (screen != 0)
165 screen->addWorkspace(); 249 screen->addWorkspace();
166} 250}
167 251
252REGISTER_COMMAND(removelastworkspace, RemoveLastWorkspaceCmd);
253
168void RemoveLastWorkspaceCmd::execute() { 254void RemoveLastWorkspaceCmd::execute() {
169 BScreen *screen = Fluxbox::instance()->mouseScreen(); 255 BScreen *screen = Fluxbox::instance()->mouseScreen();
170 if (screen != 0) 256 if (screen != 0)
171 screen->removeLastWorkspace(); 257 screen->removeLastWorkspace();
172} 258}
173 259
260namespace {
261
262FbTk::Command *parseIntCmd(const string &command, const string &args,
263 bool trusted) {
264 int num = 1;
265 FbTk_istringstream iss(args.c_str());
266 iss >> num;
267 if (command == "nextworkspace")
268 return new NextWorkspaceCmd(num);
269 else if (command == "prevworkspace")
270 return new PrevWorkspaceCmd(num);
271 else if (command == "rightworkspace")
272 return new RightWorkspaceCmd(num);
273 else if (command == "leftworkspace")
274 return new LeftWorkspaceCmd(num);
275 else if (command == "workspace")
276 // workspaces appear 1-indexed to the user, hence the minus 1
277 return new JumpToWorkspaceCmd(num - 1);
278 return 0;
279}
280
281REGISTER_COMMAND_PARSER(nextworkspace, parseIntCmd);
282REGISTER_COMMAND_PARSER(prevworkspace, parseIntCmd);
283REGISTER_COMMAND_PARSER(rightworkspace, parseIntCmd);
284REGISTER_COMMAND_PARSER(leftworkspace, parseIntCmd);
285REGISTER_COMMAND_PARSER(workspace, parseIntCmd);
286
287}; // end anonymous namespace
288
174void NextWorkspaceCmd::execute() { 289void NextWorkspaceCmd::execute() {
175 BScreen *screen = Fluxbox::instance()->mouseScreen(); 290 BScreen *screen = Fluxbox::instance()->mouseScreen();
176 if (screen != 0) 291 if (screen != 0)
@@ -210,6 +325,7 @@ void JumpToWorkspaceCmd::execute() {
210 } 325 }
211} 326}
212 327
328REGISTER_COMMAND(arrangewindows, ArrangeWindowsCmd);
213 329
214/** 330/**
215 try to arrange the windows on the current workspace in a 'clever' way. 331 try to arrange the windows on the current workspace in a 'clever' way.
@@ -335,6 +451,8 @@ void ArrangeWindowsCmd::execute() {
335 } 451 }
336} 452}
337 453
454REGISTER_COMMAND(showdesktop, ShowDesktopCmd);
455
338void ShowDesktopCmd::execute() { 456void ShowDesktopCmd::execute() {
339 BScreen *screen = Fluxbox::instance()->mouseScreen(); 457 BScreen *screen = Fluxbox::instance()->mouseScreen();
340 if (screen == 0) 458 if (screen == 0)
@@ -349,6 +467,8 @@ void ShowDesktopCmd::execute() {
349 } 467 }
350} 468}
351 469
470REGISTER_COMMAND(closeallwindows, CloseAllWindowsCmd);
471
352void CloseAllWindowsCmd::execute() { 472void CloseAllWindowsCmd::execute() {
353 BScreen *screen = Fluxbox::instance()->mouseScreen(); 473 BScreen *screen = Fluxbox::instance()->mouseScreen();
354 if (screen == 0) 474 if (screen == 0)
diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh
index eeacc16..fa8cb58 100644
--- a/src/WorkspaceCmd.hh
+++ b/src/WorkspaceCmd.hh
@@ -32,6 +32,8 @@
32 32
33#include "FbTk/RefCount.hh" 33#include "FbTk/RefCount.hh"
34 34
35#include <string>
36
35class WindowListCmd: public FbTk::Command { 37class WindowListCmd: public FbTk::Command {
36public: 38public:
37 WindowListCmd(FbTk::RefCount<FbTk::Command> cmd, const std::string &pat): 39 WindowListCmd(FbTk::RefCount<FbTk::Command> cmd, const std::string &pat):
@@ -49,6 +51,8 @@ public:
49 SomeCmd(FbTk::RefCount<FbTk::BoolCommand> cmd): m_cmd(cmd) { } 51 SomeCmd(FbTk::RefCount<FbTk::BoolCommand> cmd): m_cmd(cmd) { }
50 52
51 bool bool_execute(); 53 bool bool_execute();
54 static FbTk::BoolCommand *parse(const std::string &command,
55 const std::string &args, bool trusted);
52 56
53private: 57private:
54 FbTk::RefCount<FbTk::BoolCommand> m_cmd; 58 FbTk::RefCount<FbTk::BoolCommand> m_cmd;
@@ -97,6 +101,8 @@ public:
97 GoToWindowCmd(int num, int option, std::string &pat): 101 GoToWindowCmd(int num, int option, std::string &pat):
98 m_num(num), m_option(option), m_pat(pat.c_str()) { } 102 m_num(num), m_option(option), m_pat(pat.c_str()) { }
99 void execute(); 103 void execute();
104 static FbTk::Command *parse(const std::string &command,
105 const std::string &args, bool trusted);
100private: 106private:
101 const int m_num; 107 const int m_num;
102 const int m_option; 108 const int m_option;
@@ -107,6 +113,8 @@ class DirFocusCmd: public FbTk::Command {
107public: 113public:
108 explicit DirFocusCmd(const FocusControl::FocusDir dir): m_dir(dir) { } 114 explicit DirFocusCmd(const FocusControl::FocusDir dir): m_dir(dir) { }
109 void execute(); 115 void execute();
116 static FbTk::Command *parse(const std::string &command,
117 const std::string &args, bool trusted);
110private: 118private:
111 const FocusControl::FocusDir m_dir; 119 const FocusControl::FocusDir m_dir;
112}; 120};
diff --git a/src/WorkspaceMenu.cc b/src/WorkspaceMenu.cc
index 43cd3a3..23d4007 100644
--- a/src/WorkspaceMenu.cc
+++ b/src/WorkspaceMenu.cc
@@ -27,7 +27,7 @@
27#include "Workspace.hh" 27#include "Workspace.hh"
28#include "WorkspaceCmd.hh" 28#include "WorkspaceCmd.hh"
29#include "MenuCreator.hh" 29#include "MenuCreator.hh"
30#include "CommandParser.hh" 30#include "FbTk/CommandRegistry.hh"
31#include "FbCommands.hh" 31#include "FbCommands.hh"
32#include "Layer.hh" 32#include "Layer.hh"
33 33
@@ -147,7 +147,7 @@ void WorkspaceMenu::init(BScreen &screen) {
147 remove_workspace_macro->add(saverc_cmd); 147 remove_workspace_macro->add(saverc_cmd);
148 RefCount<Command> remove_last_cmd(remove_workspace_macro); 148 RefCount<Command> remove_last_cmd(remove_workspace_macro);
149 149
150 RefCount<Command> start_edit(CommandParser::instance().parseLine("setworkspacenamedialog")); 150 RefCount<Command> start_edit(FbTk::CommandRegistry::instance().parseLine("setworkspacenamedialog"));
151 151
152 insert(new FbTk::MenuSeparator()); 152 insert(new FbTk::MenuSeparator());
153 insert(_FB_XTEXT(Workspace, NewWorkspace, "New Workspace", "Add a new workspace"), 153 insert(_FB_XTEXT(Workspace, NewWorkspace, "New Workspace", "Add a new workspace"),