Developer Documentation
scripting.cc
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39* *
40\*===========================================================================*/
41
42
43
44
45
46//=============================================================================
47//
48// CLASS Core - IMPLEMENTATION
49//
50//=============================================================================
51
52
53//== INCLUDES =================================================================
54
55// -------------------- mview
56#include "Core.hh"
57#include <QUiLoader>
58
59#ifdef PYTHON_ENABLED
60 #include <PythonInterpreter/PythonInterpreter.hh>
61#endif
62
63//== IMPLEMENTATION ==========================================================
64
65#if QT_VERSION_MAJOR < 6
66
67void Core::slotScriptInfo( const QString& _pluginName , const QString& _functionName ) {
68 emit scriptInfo( _pluginName , _functionName );
69}
70
71void Core::slotExecuteScript( const QString& _script ) {
72 emit executeScript( _script );
73}
74
75
76void Core::slotGetScriptingEngine( QScriptEngine*& _engine ) {
77 _engine = &scriptEngine_;
78}
79
80#endif
81
82
83void Core::slotExecuteFileScript( const QString& _filename ) {
84
85 if ( _filename.endsWith("ofs",Qt::CaseInsensitive) ) {
86 emit executeFileScript(_filename);
87 }
88
89
90 if ( _filename.endsWith("ofp",Qt::CaseInsensitive) ) {
91 #ifdef PYTHON_ENABLED
92 executePythonScriptFile(_filename);
93
94 if ( !OpenFlipper::Options::nogui() ) {
95 if ( coreWidget_->pythonWidget_ == nullptr) {
97 }
98
99 coreWidget_->pythonWidget_->loadScriptFromFile(_filename);
100 }
101 #else
102 std::cerr << "No Python Script support. Unable to execute: " + _filename.toStdString() ;
103 #endif
104 }
105}
106
107void Core::slotShowScriptInEditor(const QString &_filename ) {
108 if ( _filename.endsWith("ofp",Qt::CaseInsensitive) ) {
109 #ifdef PYTHON_ENABLED
110
111 if ( !OpenFlipper::Options::nogui() ) {
112 if ( coreWidget_->pythonWidget_ == nullptr) {
114 }
115
116 coreWidget_->pythonWidget_->loadScriptFromFile(_filename);
117 }
118
119 #else
120 std::cerr << "No Python Script support. Unable to execute: " + _filename.toStdString() ;
121 #endif
122 }
123}
124
125
126void Core::slotGetAllAvailableFunctions( QStringList& _functions ) {
127 _functions = scriptingFunctions_;
128}
129
130void Core::scriptLogFunction( const QString& _output) {
131 emit scriptLog(_output);
132}
133
134void Core::createWidget(const QString& _objectName, const QString& _uiFilename, bool _show) {
135 if ( OpenFlipper::Options::gui()) {
136 QUiLoader loader;
137
138 QFile uiFile(_uiFilename);
139
140 if ( !uiFile.exists() ) {
141 emit log(LOGERR,tr("File does not exist : ") + _uiFilename );
142 return;
143 }
144
145 uiFile.open(QIODevice::ReadOnly);
146 QWidget *ui = loader.load(&uiFile, coreWidget_);
147 uiFile.close();
148
149 if ( ui == 0 ) {
150 emit log(LOGERR,tr("Unable to create QWidget from ui file for ") + _objectName );
151 return;
152 }
153
154#if QT_VERSION_MAJOR < 6
155
156 QScriptValue scriptUi = scriptEngine_.newQObject(ui, QScriptEngine::ScriptOwnership);
157
158 if ( !scriptUi.isValid() ) {
159 emit log(LOGERR,tr("Unable to generate script interface for ") + _objectName );
160 return;
161 }
162
163 scriptEngine_.globalObject().setProperty(_objectName, scriptUi);
164
165#endif
166
167 if(_show) ui->show();
168 } else {
169 emit log(LOGERR,tr("Error! Script tried to create Widget in ui less batc mode! Creation Aborted!"));
170 }
171
172}
173
174//-----------------------------------------------------------------------------
175
176int Core::getObjectId( const QString _name ) {
177
178 return PluginFunctions::getObjectId(_name);
179}
180
181//-----------------------------------------------------------------------------
182
183void Core::setViewMode(QString _viewMode){
184
185 if ( OpenFlipper::Options::gui() )
186 coreWidget_->setViewMode( _viewMode );
187}
188
189//-----------------------------------------------------------------------------
190
192 return OpenFlipper::Options::currentViewMode();
193}
194
195//-----------------------------------------------------------------------------
196
197void Core::setViewModeIcon(QString _mode, QString _iconName){
198
199 if ( OpenFlipper::Options::gui() ){
200
201 QFile file(_iconName);
202 QFileInfo fileInfo(file);
203
204 if ( ! file.exists() ){
205 emit log(LOGERR, tr("Icon not found (%1)").arg(_iconName) );
206 return;
207 }
208
209 file.copy(OpenFlipper::Options::configDirStr() + QDir::separator() + "Icons" + QDir::separator() + "viewMode_" + fileInfo.fileName() );
210
211 coreWidget_->slotSetViewModeIcon( _mode, "viewMode_" + fileInfo.fileName() );
212 }
213}
214
215//-----------------------------------------------------------------------------
216
217void Core::moveToolBoxToTop(QString _name) {
218
219 if(OpenFlipper::Options::gui()) {
221 }
222}
223
224//-----------------------------------------------------------------------------
225
226void Core::moveToolBoxToBottom(QString _name) {
227
228 if(OpenFlipper::Options::gui()) {
230 }
231}
232
233//-----------------------------------------------------------------------------
234
235void Core::addViewModeToolboxes(QString _modeName, QString _toolboxList) {
236
237 QStringList list = _toolboxList.split(";");
238 coreWidget_->slotAddViewModeToolboxes(_modeName,list);
239}
240
241//-----------------------------------------------------------------------------
242
243void Core::addViewModeToolbars(QString _modeName, QString _toolbarList) {
244
245 QStringList list = _toolbarList.split(";");
246 coreWidget_->slotAddViewModeToolbars(_modeName,list);
247}
248
249//-----------------------------------------------------------------------------
250
251void Core::addViewModeContextMenus(QString _modeName, QString _contextMenuList) {
252
253 QStringList list = _contextMenuList.split(";");
255}
256
257void Core::addViewModeIcon(QString _modeName, QString _iconName) {
258 coreWidget_->slotSetViewModeIcon(_modeName,true,_iconName);
259}
260
261//-----------------------------------------------------------------------------
262
263void Core::setToolBoxSide(QString _side) {
264
265 if(_side.toLower() == "left") {
267 } else if(_side.toLower() == "right") {
269 } else {
270 emit log(LOGERR, QString("Could not display toolboxes on side '%1'. Use either 'left' or 'right' as string!").arg(_side));
271 }
272}
273
274//-----------------------------------------------------------------------------
275
276QWidget *Core::getToolbox(const QString& _pluginName, const QString& _toolboxName) {
277 std::vector<PluginInfo>::const_iterator pluginIt = plugins().end();
278 for (std::vector<PluginInfo>::const_iterator it = plugins().begin(), it_end = plugins().end(); it != it_end; ++it) {
279 if (it->name == _pluginName) {
280 pluginIt = it;
281 }
282 }
283 if (pluginIt == plugins().end()) return 0;
284
285 for (std::vector<std::pair<QString , QWidget*> >::const_iterator it = pluginIt->toolboxWidgets.begin(), it_end = pluginIt->toolboxWidgets.end();
286 it != it_end; ++it) {
287 if (it->first == _toolboxName)
288 return it->second;
289 }
290
291 return 0;
292}
293
294void Core::activateToolbox(QString _pluginName, QString _toolboxName, bool activate) {
295 QWidget *toolbox = Core::getToolbox(_pluginName, _toolboxName);
296 coreWidget_->expandToolBoxWidget(toolbox, activate);
297}
298
299void Core::addToolbox(const QString& _name ,QWidget* _widget) {
300 addToolbox(_name, _widget, new QIcon(), 0);
301}
302
303void Core::addToolbox(const QString& _name ,QWidget* _widget, QIcon* _icon) {
304 addToolbox(_name, _widget, _icon, 0);
305}
306
307void Core::addToolbox(QString _name ,QWidget* _widget, QIcon* _icon,
308 QWidget *_headerAreaWidget) {
309 int id = -1;
310
311 // Find the plugin which added this Toolbox
312 for ( uint i = 0 ; i < plugins().size(); ++i ) {
313 if ( plugins()[i].plugin == sender() ) {
314 id = i;
315 break;
316 }
317 }
318
319 // Find the scripting plugin because we assign this toolBox to it as we did not find the original sender
320 if ( id == -1 ) {
321 for ( uint i = 0 ; i < plugins().size(); ++i ) {
322 if ( plugins()[i].name == "Scripting" ) {
323 id = i;
324 break;
325 }
326 }
327
328
329 if ( id == -1 ) {
330 std::cerr << "Unknown sender plugin when adding Toolbox!" << std::endl;
331 return;
332 }
333 }
334
335 spinBoxEventFilter_.hookUpToWidgetTree(_widget);
336 plugins()[id].toolboxWidgets.push_back( std::pair< QString,QWidget* >( _name , _widget) );
337 plugins()[id].toolboxIcons.push_back( _icon );
338 plugins()[id].headerAreaWidgets.push_back( std::pair< QString,QWidget* >( _name , _headerAreaWidget) );
339
340 // add widget name to viewMode 'all'
341 if ( !viewModes_[0]->visibleToolboxes.contains(_name) ){
342 viewModes_[0]->visibleToolboxes << _name;
343 viewModes_[0]->visibleToolboxes.sort();
344
345 viewModes_[0]->toolboxIconMap.insert(_name, *_icon);
346 }
347
348
349 setViewMode( OpenFlipper::Options::currentViewMode() );
350}
351
352void Core::setToolBoxActive(QString _toolBoxName, bool _active)
353{
354 if ( OpenFlipper::Options::gui() ){
355 coreWidget_->toolBox_->setElementActive(_toolBoxName,_active);
356 }
357}
358
361 OpenFlipper::Options::blockSceneGraphUpdates();
362}
363
366 OpenFlipper::Options::unblockSceneGraphUpdates();
367}
368
369void Core::setView(QString view) {
371}
372
375}
376
377//=============================================================================
378//== Script Special Functions =================================================
379//=============================================================================
380
381#if QT_VERSION_MAJOR < 6
382
383void Core::slotScriptError(const QScriptValue &error) {
384 emit log(LOGERR, tr("Script error: ") + error.toString());
385}
386
387QScriptValue myPrintFunction(QScriptContext *context, QScriptEngine *engine)
388{
389 QString result;
390 for (int i = 0; i < context->argumentCount(); ++i) {
391 if (i > 0)
392 result.append(" ");
393 result.append(context->argument(i).toString());
394 }
395
396 // Get the textedit for Output ( Set in Core.cc )
397 QScriptValue calleeData = context->callee().property("textedit");
398 Core *widget = qobject_cast<Core*>(calleeData.toQObject());
399
400 widget->scriptLogFunction(result);
401
402 return engine->undefinedValue();
403}
404
405QScriptValue printToFileFunction(QScriptContext *context, QScriptEngine *engine)
406{
407 if ( context->argumentCount() < 2 ) {
408 context->throwError( QScriptContext::SyntaxError, "Error! printToFileFunction needs at least two arguments, filename and what should be printed" );
409 return engine->undefinedValue();
410 }
411
412 QString result;
413 for (int i = 1; i < context->argumentCount(); ++i) {
414 if (i > 1)
415 result.append(" ");
416 result.append(context->argument(i).toString());
417 }
418
419 QFile file(context->argument(0).toString());
420
421 file.open(QIODevice::Append);
422 QTextStream stream(&file);
423
424 stream << result << "\n";
425
426 file.close();
427
428 return engine->undefinedValue();
429}
430
431QScriptValue helpFunction(QScriptContext *context, QScriptEngine *engine)
432{
433 if ( context->argumentCount() != 1 ) {
434 context->throwError( QScriptContext::SyntaxError, "Error! helpFunction needs one argument" );
435 return engine->undefinedValue();
436 }
437
438 QString helpString = context->argument(0).toString();
439
440 // Get the corewidget poiter ( Set in Core.cc )
441 QScriptValue calleeData = context->callee().property("core");
442 Core *core = qobject_cast<Core*>(calleeData.toQObject());
443
444 const std::vector<PluginInfo> plugins = core->plugins();
445
446 for (unsigned int i=0; i < plugins.size(); i++) {
447 if (plugins[i].rpcName == helpString) {
448 core->scriptLogFunction( "=======================================================\n" );
449 core->scriptLogFunction( "Found Plugin \"" + plugins[i].name + "\" \n" );
450 core->scriptLogFunction( "Description: " + plugins[i].description + " \n");
451 core->scriptLogFunction( "=======================================================\n" );
452 core->scriptLogFunction( "Scripting functions: \n");
453
454 for ( int j = 0 ; j < plugins[i].rpcFunctions.size() ; ++j ) {
455 core->scriptLogFunction( plugins[i].rpcFunctions[j]+"\n");
456 }
457
458 core->scriptLogFunction( "\n\n");
459 }
460 }
461
462
463
464 return engine->undefinedValue();
465}
466
467#endif
468
469void Core::executePythonScriptFile(QString _filename){
470 QFile file(_filename);
471
472 if (!file.exists()) {
473 emit scriptLog("Unable to load file " + _filename + " as python script. File not found!");
474
475 // Fail when in batch mode
476 if (OpenFlipper::Options::nogui())
477 exit(1);
478
479 return;
480 }
481
482 file.open(QIODevice::ReadOnly| QFile::Text);
483
484 QTextStream in(&file);
485
486 QString script = in.readAll();
487
488 executePythonScript(script);
489
490}
491
492
493void Core::executePythonScript(const QString& _script) {
494#ifdef PYTHON_ENABLED
496 interpreter->runScript(_script);
497#else
498 emit scriptLog("Python scripting Error! No build in python support. Unable to execute script. Build OpenFlipper with Python support to enable Python based scripting.");
499#endif
500}
501
502void Core::slotExecutePythonScript(const QString& _script) {
503 executePythonScript(_script);
504}
505
506void Core::slotOpenPythonScriptInEditor(QString _script) {
507 emit scriptLog("Open python editor");
508 emit scriptLog(_script);
510 coreWidget_->pythonWidget_->showScript(_script);
511}
QScriptValue printToFileFunction(QScriptContext *context, QScriptEngine *engine)
Special print function for sending output to a file.
Definition: scripting.cc:405
QScriptValue helpFunction(QScriptContext *context, QScriptEngine *engine)
Function to print help about scripting functions.
Definition: scripting.cc:431
QScriptValue myPrintFunction(QScriptContext *context, QScriptEngine *engine)
Special print function for core logger.
Definition: scripting.cc:387
@ LOGERR
void showPythonScriptInterpreter()
Pointer to the OptionsWidget.
Definition: Python.cc:3
void slotAddViewModeContextMenus(const QString &_mode, const QStringList &_usedToolbars)
Add or change Toolbars for a ViewMode (non-userdefined viewMode)
Definition: viewMode.cc:198
void expandToolBoxWidget(QWidget *widget, bool expand)
Definition: picking.cc:492
SideArea * toolBox_
Toolbox.
Definition: CoreWidget.hh:741
void moveToolBoxToBottom(QString _name)
Move a specific toolbox widget to the bottom of the side area.
Definition: viewMode.cc:492
void slotSetView(QString view)
Set the supplied serialized view.
void slotSetViewModeIcon(const QString &_mode, const QString &_iconName)
Sets the Icon for a given View Mode (non-userdefined viewMode)
Definition: viewMode.cc:245
void slotAddViewModeToolboxes(const QString &_mode, const QStringList &_usedWidgets)
Add or change Toolboxes for a ViewMode (non-userdefined viewMode)
Definition: viewMode.cc:93
void setToolBoxOrientationOnTheRight(bool _toolBoxRight)
Set orientation of tool box (either on the right or the left side of the screen)
Definition: CoreWidget.cc:838
void slotSetViewAndWindowGeometry(QString view)
Set the supplied serialized view.
void moveToolBoxToTop(QString _name)
Move a specific toolbox widget to the top of the side area.
Definition: viewMode.cc:487
PythonWidget * pythonWidget_
Pointer to the about widget.
Definition: CoreWidget.hh:1248
void setViewMode(const QString &_mode, bool _expandAll=false)
Set the view Mode to the given Mode.
Definition: viewMode.cc:318
void slotAddViewModeToolbars(const QString &_mode, const QStringList &_usedToolbars)
Add or change Toolbars for a ViewMode (non-userdefined viewMode)
Definition: viewMode.cc:141
Definition: Core.hh:133
void slotGetAllAvailableFunctions(QStringList &_functions)
Core scripting engine.
Definition: scripting.cc:126
void executeFileScript(QString _filename)
Core scripting engine.
void addViewModeToolbars(QString _modeName, QString _toolbarList)
Scripting function to set toolbars in a view mode.
Definition: scripting.cc:243
void addViewModeToolboxes(QString _modeName, QString _toolboxList)
Scripting function to set toolboxes in a view mode.
Definition: scripting.cc:235
QWidget * getToolbox(const QString &_pluginName, const QString &_toolboxName)
Definition: scripting.cc:276
void setToolBoxSide(QString _side)
Scripting function to set the side of the main window on which the toolbox should be displayed.
Definition: scripting.cc:263
void addViewModeContextMenus(QString _modeName, QString _contextMenuList)
Scripting function to set context menus in a view mode.
Definition: scripting.cc:251
void setViewAndWindowGeometry(QString view)
Called when a plugin requests an update in the viewer.
Definition: scripting.cc:373
void slotScriptError(const QScriptValue &error)
Core scripting engine.
Definition: scripting.cc:383
void blockSceneGraphUpdates()
Block the scenegraph updates.
Definition: scripting.cc:360
void addViewModeIcon(QString _modeName, QString _iconName)
Scripting function to set an icon for a view mode.
Definition: scripting.cc:257
void slotExecuteScript(const QString &_script)
Definition: scripting.cc:71
void scriptLog(QString _message)
Logging signal for ScriptEngine.
void scriptInfo(QString _pluginName, QString _functionName)
Core scripting engine.
QStringList scriptingFunctions_
List of all registered scripting functions.
Definition: Core.hh:1352
void moveToolBoxToBottom(QString _name)
Move selected toolbox to bottom of side area.
Definition: scripting.cc:226
void executeScript(QString _script)
Core scripting engine.
void addToolbox(const QString &_name, QWidget *_widget)
Add a Toolbox from a plugin or from scripting.
Definition: scripting.cc:299
QVector< ViewMode * > viewModes_
List of available draw modes.
Definition: Core.hh:1661
void setToolBoxActive(QString _toolBoxName, bool _active)
Scripting function to activate or deactivate a toolbox.
Definition: scripting.cc:352
void slotShowScriptInEditor(const QString &_filename)
Definition: scripting.cc:107
void unblockSceneGraphUpdates()
Unblock the scenegraph updates.
Definition: scripting.cc:365
void setViewModeIcon(QString _mode, QString _iconName)
Set the icon of a viewMode.
Definition: scripting.cc:197
void moveToolBoxToTop(QString _name)
Move selected toolbox to top of side area.
Definition: scripting.cc:217
void executePythonScriptFile(QString _filename)
Open the given file and execute its contents as a python script.
Definition: scripting.cc:469
std::vector< PluginInfo > & plugins()
Index of Plugins toolbox widget.
Definition: Core.cc:770
QScriptEngine scriptEngine_
Core scripting engine.
Definition: Core.hh:1344
void slotScriptInfo(const QString &_pluginName, const QString &_functionName)
Core scripting engine.
Definition: scripting.cc:67
void createWidget(const QString &_objectName, const QString &_uiFilename, bool _show=true)
Create an script object from a ui file.
Definition: scripting.cc:134
void slotExecuteFileScript(const QString &_filename)
Definition: scripting.cc:83
void setView(QString view)
Called when a plugin requests an update in the viewer.
Definition: scripting.cc:369
void log(Logtype _type, QString _message)
Logg with OUT,WARN or ERR as type.
int getObjectId(QString _filename)
Get object id from filename.
Definition: scripting.cc:176
void setViewMode(QString _viewMode)
Set the active ViewMode.
Definition: scripting.cc:183
void activateToolbox(QString _pluginName, QString _toolboxName, bool activate)
expand or collapse a toolbox
Definition: scripting.cc:294
void executePythonScript(const QString &_script)
execute the given string as a python script
Definition: scripting.cc:493
void scriptLogFunction(const QString &_output)
stream for logging to file
Definition: scripting.cc:130
QString getCurrentViewMode()
Get current view mode.
Definition: scripting.cc:191
void slotGetScriptingEngine(QScriptEngine *&_engine)
Core scripting engine.
Definition: scripting.cc:76
CoreWidget * coreWidget_
The main applications widget ( only created in gui mode )
Definition: Core.hh:1652
This class provides OpenFlippers Python interpreter.
bool runScript(const QString &_script)
Run a script. Output is passed to the standard logging facilities of OpenFlipper.
static PythonInterpreter * getInstance()
Creates or returns an instance of the interpreter.
void setElementActive(const QString &_name, bool _active)
set the active state of given element
Definition: SideArea.cc:212
int getObjectId(const QString &_name)