|
Scripting_Working_With_QtScript
QtScript - An Implementation Of ECMAScriptAs QtScript is an implementation of ECMAScript like JavaScript is, anyone with familiarity of the latter can begin to program with it and EiskaltDC++ immediately. You can view the official documentation here, and a basic overview of ECMAScript functionality as implemented in QtScript here. Script ConsoleAvailable under the Tools menu, allows you to execute QtScript code directly. Paste/type script in the code text box and then press the Start button - the output text box displays the results. Note that if your code encounters an error, it stalls at the relevant line and the Stop button is needed to stop the ScriptEngine, which then outputs very basic error information - for example: <anonymous>()@:18 Indicates that your 'anonymous function' script encountered an error on line 18. For basic investigation and debugging, the built in print() and printErr() functions are useful, for example: print('This is a test message!');
printErr('This is a test error!');Standalone QtScripts In EiskaltDC++EiskaltDC++ gives you the ability to 'register' QtScript that has been saved into a file, and if you enable the script it will be automatically executed whenever Eiskalt starts up (and when you enable it after it has been disabled). Scripts recognised by EiskaltDC++ are listed in Tools -> Scripts Manager. In order to have your script recognised, you must house it in a dedicated folder in either the global script installation directory: TODO: Currently this is '/usr/share/eiskaltdcpp/qt/qtscripts/'? {CMAKE_INSTALL_PREFIX}/share/eiskaltdcpp/scripts Or the user script installation directory: ~/.config/eiskaltdc++/scripts/ Within your script folder, you must place the following files:
'script.desc' contains the following structure: auth=<author> name=<script name> desc=<script description> icon=<icon file to use, optional - leave blank if not needed> For example: auth=Omega Weapon name=Status Script desc=Integrates with the main notification system icon= Aside from these, any number of other files can also be present in the directory. For reference, you can include extra script files inside 'main.js' with the Include function, so having one fixed file executed by Eiskalt does not limit any capability. Once this is in place, start/restart Eiskalt and enable the relevant script in Scripts Manager. Scripting With External Editors And Reloading ScriptsTo seriously script with Eiskalt, you need to develop in an external editor. Most competent editors support JavaScript syntax highlighting, which is essentially what QtScript is. Whenever you make a change to a 'main.js' or 'script.desc' file, Eiskalt detects this and offers to reload - when you accept this, the relevant file is re-evaluated/executed. Eiskalt Startup And ScriptsAs part of the Eiskalt startup process, all enabled scripts are automatically executed. The ScriptEngineEach of your QtScripts are evaluated in a separate ScriptEngine - therefore there is no immediate way to share data between them, put in a different way this means that the individual script environments are protected from other scripts. Connecting To SignalsQt objects can expose events ('signals') that other code can slot into. These will typically be 'emitted' on useful events like a user posting in hubchat, sending a PM, etc. In QtScript you can slot into these by connecting a script function to the definition of the signal function, on the relevant object. For example: var hubManager = HubManager();
// Hooking a very simple print statement into the hub window creation event
hubManager["hubRegistered(QObject*)"].connect(
function(hubObject)
{
print('Hub object: ' + hubObject);
}The following will be printed to stdout when you open a new hub ('hubObject' is implicitly turned into a string representation of itself): Hub object: HubFrame(name = "UIHubFrame") Note that you do have to pass the signal definition verbatim - if you miss out '*' for example, it will not work. If you find the signal does not provide enough information when it is emitted (in the above case it just sends the relevant hub frame), then you may be able to get what you want by using a fancy ability of QtScript - closures. If you have a useful object already instantiated in the code around the statement to hook into the signal, you can add the object into the function that fires on the signal by simply including it in somehow: var hubManager = HubManager();
var hubList = hubManager.getHubs();
// Hooking a very simple print statement into the hub window creation event, and then an example of a closure
hubManager["hubRegistered(QObject*)"].connect(
function(hubObject)
{
print('Hub object: ' + hubObject);
print('This was instantiated in the outer function, but is magically available here: ' + hubList);
}The closure maintains a reference to the original object in this way. |