Skip to content

Commit f27d120

Browse files
authored
Merge pull request #70 from klaussilveira/fix/user-scripts
User scripts
2 parents 8b60a26 + 4e3f670 commit f27d120

8 files changed

Lines changed: 106 additions & 26 deletions

File tree

include/ui/ieventmanager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ class IEventManager :
202202
/* greebo: Retrieves the string representation of the given event
203203
*/
204204
virtual std::string getEventStr(wxKeyEvent& ev) = 0;
205+
206+
virtual void connectDeferredAccelerators() = 0;
205207
};
206208

207209
// Global accessor for the event manager

plugins/script/PythonModule.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ ScriptCommand::Ptr PythonModule::createScriptCommand(const std::string& scriptBa
309309
}
310310

311311
// Successfully retrieved the command
312-
return std::make_shared<ScriptCommand>(cmdName, cmdDisplayName, relativeScriptPath);
312+
return std::make_shared<ScriptCommand>(cmdName, cmdDisplayName, relativeScriptPath, scriptBasePath);
313313
}
314314

315315
rError() << "Script file " << relativeScriptPath << " does not export a __commandName__ value" << std::endl;

plugins/script/ScriptCommand.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ namespace script
77

88
ScriptCommand::ScriptCommand(const std::string& name,
99
const std::string& displayName,
10-
const std::string& scriptFilename) :
10+
const std::string& scriptFilename,
11+
const std::string& basePath) :
1112
_name(name),
1213
_displayName(displayName),
13-
_scriptFilename(scriptFilename)
14+
_scriptFilename(scriptFilename),
15+
_basePath(basePath)
1416
{
1517
// Register this with the command system
1618
GlobalCommandSystem().addStatement(_name, "RunScriptCommand '" + _name + "'", false);

plugins/script/ScriptCommand.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ class ScriptCommand :
2323
// The script file name to execute (relative to scripts/ folder)
2424
std::string _scriptFilename;
2525

26+
std::string _basePath;
27+
2628
public:
2729
using Ptr = std::shared_ptr<ScriptCommand>;
2830

2931
ScriptCommand(const std::string& name,
3032
const std::string& displayName,
31-
const std::string& scriptFilename);
33+
const std::string& scriptFilename,
34+
const std::string& basePath);
3235

3336
~ScriptCommand() override;
3437

@@ -46,6 +49,11 @@ class ScriptCommand :
4649
{
4750
return _displayName;
4851
}
52+
53+
const std::string& getBasePath() const
54+
{
55+
return _basePath;
56+
}
4957
};
5058

5159
} // namespace script

plugins/script/ScriptingSystem.cpp

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131

3232
#include "PythonModule.h"
3333
#include "SceneNodeBuffer.h"
34+
#include "ui/ieventmanager.h"
3435

3536
#include "os/path.h"
3637
#include <functional>
3738
#include "string/case_conv.h"
39+
#include "settings/SettingsManager.h"
3840

3941
namespace script
4042
{
@@ -95,6 +97,8 @@ void ScriptingSystem::initialise()
9597

9698
// Search script folder for commands
9799
reloadScripts();
100+
101+
GlobalEventManager().connectDeferredAccelerators();
98102
}
99103

100104
void ScriptingSystem::runScriptFile(const cmd::ArgumentList& args)
@@ -138,12 +142,12 @@ void ScriptingSystem::executeCommand(const std::string& name)
138142
UndoableCommand cmd("runScriptCommand " + name);
139143

140144
// Execute the script file behind this command
141-
executeScriptFile(found->second->getFilename(), true);
145+
_pythonModule->executeScriptFile(found->second->getBasePath(), found->second->getFilename(), true);
142146
}
143147

144-
void ScriptingSystem::loadCommandScript(const std::string& scriptFilename)
148+
void ScriptingSystem::loadCommandScript(const std::string& basePath, const std::string& scriptFilename)
145149
{
146-
auto command = _pythonModule->createScriptCommand(_scriptPath, scriptFilename);
150+
auto command = _pythonModule->createScriptCommand(basePath, scriptFilename);
147151

148152
if (!command)
149153
{
@@ -173,29 +177,37 @@ void ScriptingSystem::reloadScripts()
173177
_commands.clear();
174178

175179
// Initialise the search's starting point
176-
fs::path start = fs::path(_scriptPath) / COMMAND_PATH;
177-
178-
if (!fs::exists(start))
180+
auto scanDirectory = [&](const std::string& basePath)
179181
{
180-
rWarning() << "Couldn't find scripts folder: " << start.string() << std::endl;
181-
return;
182-
}
182+
fs::path start = fs::path(basePath) / COMMAND_PATH;
183183

184-
for (fs::recursive_directory_iterator it(start);
185-
it != fs::recursive_directory_iterator(); ++it)
186-
{
187-
// Get the candidate
188-
const fs::path& candidate = *it;
184+
if (!fs::exists(start))
185+
{
186+
return;
187+
}
189188

190-
if (fs::is_directory(candidate)) continue;
189+
for (fs::recursive_directory_iterator it(start);
190+
it != fs::recursive_directory_iterator(); ++it)
191+
{
192+
const fs::path& candidate = *it;
191193

192-
std::string extension = os::getExtension(candidate.string());
193-
string::to_lower(extension);
194+
if (fs::is_directory(candidate)) continue;
194195

195-
if (extension != PYTHON_FILE_EXTENSION) continue;
196+
std::string extension = os::getExtension(candidate.string());
197+
string::to_lower(extension);
196198

197-
// Script file found, construct a new command
198-
loadCommandScript(os::getRelativePath(candidate.generic_string(), _scriptPath));
199+
if (extension != PYTHON_FILE_EXTENSION) continue;
200+
201+
// Script file found, construct a new command
202+
loadCommandScript(basePath, os::getRelativePath(candidate.generic_string(), basePath));
203+
}
204+
};
205+
206+
scanDirectory(_scriptPath);
207+
208+
if (!_userScriptPath.empty())
209+
{
210+
scanDirectory(_userScriptPath);
199211
}
200212

201213
rMessage() << "ScriptModule: Found " << _commands.size() << " commands." << std::endl;
@@ -208,6 +220,9 @@ void ScriptingSystem::initialiseModule(const IApplicationContext& ctx)
208220
// Construct the script path
209221
_scriptPath = ctx.getRuntimeDataPath() + SCRIPT_PATH;
210222

223+
settings::SettingsManager manager(ctx);
224+
_userScriptPath = manager.getCurrentVersionSettingsFolder() + SCRIPT_PATH;
225+
211226
// Set up the python interpreter
212227
_pythonModule.reset(new PythonModule);
213228

@@ -274,6 +289,7 @@ void ScriptingSystem::shutdownModule()
274289

275290
_commands.clear();
276291
_scriptPath.clear();
292+
_userScriptPath.clear();
277293
_pythonModule.reset();
278294
}
279295

plugins/script/ScriptingSystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class ScriptingSystem: public IScriptingSystem
2222

2323
// The path where the script files are hosted
2424
std::string _scriptPath;
25+
std::string _userScriptPath;
2526

2627
// All named script commands (pointing to .py files)
2728
std::map<std::string, ScriptCommand::Ptr> _commands;
@@ -74,7 +75,7 @@ class ScriptingSystem: public IScriptingSystem
7475
private:
7576
void executeScriptFile(const std::string& filename, bool setExecuteCommandAttr);
7677
void reloadScripts();
77-
void loadCommandScript(const std::string& scriptFilename);
78+
void loadCommandScript(const std::string& basePath, const std::string& scriptFilename);
7879
};
7980
typedef std::shared_ptr<ScriptingSystem> ScriptingSystemPtr;
8081

radiant/eventmanager/EventManager.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void EventManager::shutdownModule()
8383
saveEventListToRegistry();
8484

8585
_accelerators.clear();
86+
_deferredAccelerators.clear();
8687
_events.clear();
8788
}
8889

@@ -107,6 +108,7 @@ void EventManager::resetAcceleratorBindings()
107108
}
108109

109110
_accelerators.clear();
111+
_deferredAccelerators.clear();
110112

111113
for (const auto& pair : _menuItems)
112114
{
@@ -406,7 +408,9 @@ Accelerator& EventManager::connectAccelerator(int keyCode, unsigned int modifier
406408
}
407409
else
408410
{
409-
return _emptyAccelerator;
411+
rMessage() << "EventManager: Deferring shortcut for not-yet-registered command: " << command << std::endl;
412+
_deferredAccelerators.emplace(command, accelerator);
413+
return *accelerator;
410414
}
411415

412416
auto result = _accelerators.emplace(command, accelerator);
@@ -635,6 +639,50 @@ void EventManager::saveEventListToRegistry()
635639

636640
shortcutSaver.visit(pair.first, *pair.second);
637641
}
642+
643+
for (const auto& pair : _deferredAccelerators)
644+
{
645+
if (pair.second->isEmpty()) continue;
646+
647+
shortcutSaver.visit(pair.first, *pair.second);
648+
}
649+
}
650+
651+
void EventManager::connectDeferredAccelerators()
652+
{
653+
auto it = _deferredAccelerators.begin();
654+
655+
while (it != _deferredAccelerators.end())
656+
{
657+
const auto& command = it->first;
658+
auto& accelerator = it->second;
659+
660+
auto event = findEvent(command);
661+
662+
if (!event->empty())
663+
{
664+
accelerator->setEvent(event);
665+
}
666+
else if (GlobalCommandSystem().commandExists(command))
667+
{
668+
accelerator->setStatement(command);
669+
}
670+
else
671+
{
672+
++it;
673+
continue;
674+
}
675+
676+
rMessage() << "EventManager: Resolved deferred shortcut for " << command << std::endl;
677+
678+
_accelerators.emplace(command, accelerator);
679+
680+
std::string acceleratorStr = accelerator->getString(true);
681+
setMenuItemAccelerator(command, acceleratorStr);
682+
setToolItemAccelerator(command, acceleratorStr);
683+
684+
it = _deferredAccelerators.erase(it);
685+
}
638686
}
639687

640688
Accelerator& EventManager::findAccelerator(const std::string& key, const std::string& modifierStr)

radiant/eventmanager/EventManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class EventManager :
3232
// The command-to-accelerator map containing all registered shortcuts
3333
typedef std::map<std::string, Accelerator::Ptr> AcceleratorMap;
3434
AcceleratorMap _accelerators;
35+
AcceleratorMap _deferredAccelerators;
3536

3637
// The map of all registered events
3738
EventMap _events;
@@ -92,6 +93,8 @@ class EventManager :
9293

9394
void foreachEvent(IEventVisitor& eventVisitor) override;
9495

96+
void connectDeferredAccelerators() override;
97+
9598
// Tries to locate an accelerator, that is connected to the given command
9699
Accelerator& findAccelerator(wxKeyEvent& ev);
97100
bool handleKeyEvent(wxKeyEvent& keyEvent);

0 commit comments

Comments
 (0)