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 
66 
67 void Core::slotScriptInfo( QString _pluginName , QString _functionName ) {
68  emit scriptInfo( _pluginName , _functionName );
69 }
70 
71 void Core::slotExecuteScript( QString _script ) {
72  emit executeScript( _script );
73 }
74 
75 void Core::slotExecuteFileScript( QString _filename ) {
76  emit executeFileScript( _filename );
77 }
78 
79 void Core::slotGetScriptingEngine( QScriptEngine*& _engine ) {
80  _engine = &scriptEngine_;
81 }
82 
83 void Core::slotGetAllAvailableFunctions( QStringList& _functions ) {
84  _functions = scriptingFunctions_;
85 }
86 
87 void Core::scriptLogFunction( QString _output) {
88  emit scriptLog(_output);
89 }
90 
91 void Core::createWidget(QString _objectName, QString _uiFilename, bool _show) {
92  if ( OpenFlipper::Options::gui()) {
93  QUiLoader loader;
94 
95  QFile uiFile(_uiFilename);
96 
97  if ( !uiFile.exists() ) {
98  emit log(LOGERR,tr("File does not exist : ") + _uiFilename );
99  return;
100  }
101 
102  uiFile.open(QIODevice::ReadOnly);
103  QWidget *ui = loader.load(&uiFile, coreWidget_);
104  uiFile.close();
105 
106  if ( ui == 0 ) {
107  emit log(LOGERR,tr("Unable to create QWidget from ui file for ") + _objectName );
108  return;
109  }
110 
111  QScriptValue scriptUi = scriptEngine_.newQObject(ui, QScriptEngine::ScriptOwnership);
112 
113  if ( !scriptUi.isValid() ) {
114  emit log(LOGERR,tr("Unable to generate script interface for ") + _objectName );
115  return;
116  }
117 
118  scriptEngine_.globalObject().setProperty(_objectName, scriptUi);
119 
120 
121  if(_show) ui->show();
122  } else {
123  emit log(LOGERR,tr("Error! Script tried to create Widget in ui less batc mode! Creation Aborted!"));
124  }
125 
126 }
127 
128 //-----------------------------------------------------------------------------
129 
130 int Core::getObjectId( const QString _name ) {
131 
132  return PluginFunctions::getObjectId(_name);
133 }
134 
135 //-----------------------------------------------------------------------------
136 
137 void Core::setViewMode(QString _viewMode){
138 
139  if ( OpenFlipper::Options::gui() )
140  coreWidget_->setViewMode( _viewMode );
141 }
142 
143 //-----------------------------------------------------------------------------
144 
146  return OpenFlipper::Options::currentViewMode();
147 }
148 
149 //-----------------------------------------------------------------------------
150 
151 void Core::setViewModeIcon(QString _mode, QString _iconName){
152 
153  if ( OpenFlipper::Options::gui() ){
154 
155  QFile file(_iconName);
156  QFileInfo fileInfo(file);
157 
158  if ( ! file.exists() ){
159  emit log(LOGERR, tr("Icon not found (%1)").arg(_iconName) );
160  return;
161  }
162 
163  file.copy(OpenFlipper::Options::configDirStr() + QDir::separator() + "Icons" + QDir::separator() + "viewMode_" + fileInfo.fileName() );
164 
165  coreWidget_->slotSetViewModeIcon( _mode, "viewMode_" + fileInfo.fileName() );
166  }
167 }
168 
169 //-----------------------------------------------------------------------------
170 
171 void Core::moveToolBoxToTop(QString _name) {
172 
173  if(OpenFlipper::Options::gui()) {
175  }
176 }
177 
178 //-----------------------------------------------------------------------------
179 
180 void Core::moveToolBoxToBottom(QString _name) {
181 
182  if(OpenFlipper::Options::gui()) {
184  }
185 }
186 
187 //-----------------------------------------------------------------------------
188 
189 void Core::addViewModeToolboxes(QString _modeName, QString _toolboxList) {
190 
191  QStringList list = _toolboxList.split(";");
192  coreWidget_->slotAddViewModeToolboxes(_modeName,list);
193 }
194 
195 //-----------------------------------------------------------------------------
196 
197 void Core::addViewModeToolbars(QString _modeName, QString _toolbarList) {
198 
199  QStringList list = _toolbarList.split(";");
200  coreWidget_->slotAddViewModeToolbars(_modeName,list);
201 }
202 
203 //-----------------------------------------------------------------------------
204 
205 void Core::addViewModeContextMenus(QString _modeName, QString _contextMenuList) {
206 
207  QStringList list = _contextMenuList.split(";");
208  coreWidget_->slotAddViewModeContextMenus(_modeName,list);
209 }
210 
211 void Core::addViewModeIcon(QString _modeName, QString _iconName) {
212  coreWidget_->slotSetViewModeIcon(_modeName,true,_iconName);
213 }
214 
215 //-----------------------------------------------------------------------------
216 
217 void Core::setToolBoxSide(QString _side) {
218 
219  if(_side.toLower() == "left") {
221  } else if(_side.toLower() == "right") {
223  } else {
224  emit log(LOGERR, QString("Could not display toolboxes on side '%1'. Use either 'left' or 'right' as string!").arg(_side));
225  }
226 }
227 
228 //-----------------------------------------------------------------------------
229 
230 QWidget *Core::getToolbox(QString _pluginName, QString _toolboxName) {
231  std::vector<PluginInfo>::const_iterator pluginIt = plugins().end();
232  for (std::vector<PluginInfo>::const_iterator it = plugins().begin(), it_end = plugins().end(); it != it_end; ++it) {
233  if (it->name == _pluginName) {
234  pluginIt = it;
235  }
236  }
237  if (pluginIt == plugins().end()) return 0;
238 
239  for (std::vector<std::pair<QString , QWidget*> >::const_iterator it = pluginIt->toolboxWidgets.begin(), it_end = pluginIt->toolboxWidgets.end();
240  it != it_end; ++it) {
241  if (it->first == _toolboxName)
242  return it->second;
243  }
244 
245  return 0;
246 }
247 
248 void Core::activateToolbox(QString _pluginName, QString _toolboxName, bool activate) {
249  QWidget *toolbox = Core::getToolbox(_pluginName, _toolboxName);
250  coreWidget_->expandToolBoxWidget(toolbox, activate);
251 }
252 
253 void Core::addToolbox(QString _name ,QWidget* _widget) {
254  addToolbox(_name, _widget, 0, 0);
255 }
256 
257 void Core::addToolbox(QString _name ,QWidget* _widget, QIcon* _icon) {
258  addToolbox(_name, _widget, _icon, 0);
259 }
260 
261 void Core::addToolbox(QString _name ,QWidget* _widget, QIcon* _icon,
262  QWidget *_headerAreaWidget) {
263  int id = -1;
264 
265  // Find the plugin which added this Toolbox
266  for ( uint i = 0 ; i < plugins().size(); ++i ) {
267  if ( plugins()[i].plugin == sender() ) {
268  id = i;
269  break;
270  }
271  }
272 
273  // Find the scripting plugin because we assign this toolBox to it as we did not find the original sender
274  if ( id == -1 ) {
275  for ( uint i = 0 ; i < plugins().size(); ++i ) {
276  if ( plugins()[i].name == "Scripting" ) {
277  id = i;
278  break;
279  }
280  }
281 
282 
283  if ( id == -1 ) {
284  std::cerr << "Unknown sender plugin when adding Toolbox!" << std::endl;
285  return;
286  }
287  }
288 
289  spinBoxEventFilter_.hookUpToWidgetTree(_widget);
290  plugins()[id].toolboxWidgets.push_back( std::pair< QString,QWidget* >( _name , _widget) );
291  plugins()[id].toolboxIcons.push_back( _icon );
292  plugins()[id].headerAreaWidgets.push_back( std::pair< QString,QWidget* >( _name , _headerAreaWidget) );
293 
294  // add widget name to viewMode 'all'
295  if ( !viewModes_[0]->visibleToolboxes.contains(_name) ){
296  viewModes_[0]->visibleToolboxes << _name;
297  viewModes_[0]->visibleToolboxes.sort();
298  }
299 
300  setViewMode( OpenFlipper::Options::currentViewMode() );
301 }
302 
303 void Core::setToolBoxActive(QString _toolBoxName, bool _active)
304 {
305  if ( OpenFlipper::Options::gui() ){
306  coreWidget_->toolBox_->setElementActive(_toolBoxName,_active);
307  }
308 }
309 
312  OpenFlipper::Options::blockSceneGraphUpdates();
313 }
314 
317  OpenFlipper::Options::unblockSceneGraphUpdates();
318 }
319 
320 void Core::setView(QString view) {
321  coreWidget_->slotSetView(view);
322 }
323 
324 void Core::setViewAndWindowGeometry(QString view) {
326 }
327 
328 //=============================================================================
329 //== Script Special Functions =================================================
330 //=============================================================================
331 
332 void Core::slotScriptError(const QScriptValue &error) {
333  emit log(LOGERR, tr("Script error: ") + error.toString());
334 }
335 
336 QScriptValue myPrintFunction(QScriptContext *context, QScriptEngine *engine)
337 {
338  QString result;
339  for (int i = 0; i < context->argumentCount(); ++i) {
340  if (i > 0)
341  result.append(" ");
342  result.append(context->argument(i).toString());
343  }
344 
345  // Get the textedit for Output ( Set in Core.cc )
346  QScriptValue calleeData = context->callee().property("textedit");
347  Core *widget = qobject_cast<Core*>(calleeData.toQObject());
348 
349  widget->scriptLogFunction(result);
350 
351  return engine->undefinedValue();
352 }
353 
354 QScriptValue printToFileFunction(QScriptContext *context, QScriptEngine *engine)
355 {
356  if ( context->argumentCount() < 2 ) {
357  context->throwError( QScriptContext::SyntaxError, "Error! printToFileFunction needs at least two arguments, filename and what should be printed" );
358  return engine->undefinedValue();
359  }
360 
361  QString result;
362  for (int i = 1; i < context->argumentCount(); ++i) {
363  if (i > 1)
364  result.append(" ");
365  result.append(context->argument(i).toString());
366  }
367 
368  QFile file(context->argument(0).toString());
369 
370  file.open(QIODevice::Append);
371  QTextStream stream(&file);
372 
373  stream << result << "\n";
374 
375  file.close();
376 
377  return engine->undefinedValue();
378 }
379 
380 QScriptValue helpFunction(QScriptContext *context, QScriptEngine *engine)
381 {
382  if ( context->argumentCount() != 1 ) {
383  context->throwError( QScriptContext::SyntaxError, "Error! helpFunction needs one argument" );
384  return engine->undefinedValue();
385  }
386 
387  QString helpString = context->argument(0).toString();
388 
389  // Get the corewidget poiter ( Set in Core.cc )
390  QScriptValue calleeData = context->callee().property("core");
391  Core *core = qobject_cast<Core*>(calleeData.toQObject());
392 
393  const std::vector<PluginInfo> plugins = core->plugins();
394 
395  for (unsigned int i=0; i < plugins.size(); i++) {
396  if (plugins[i].rpcName == helpString) {
397  core->scriptLogFunction( "=======================================================\n" );
398  core->scriptLogFunction( "Found Plugin \"" + plugins[i].name + "\" \n" );
399  core->scriptLogFunction( "Description: " + plugins[i].description + " \n");
400  core->scriptLogFunction( "=======================================================\n" );
401  core->scriptLogFunction( "Scripting functions: \n");
402 
403  for ( int j = 0 ; j < plugins[i].rpcFunctions.size() ; ++j ) {
404  core->scriptLogFunction( plugins[i].rpcFunctions[j]+"\n");
405  }
406 
407  core->scriptLogFunction( "\n\n");
408  }
409  }
410 
411 
412 
413  return engine->undefinedValue();
414 }
415 
416 
417 void Core::executePythonScriptFile(QString _filename){
418  QFile file(_filename);
419 
420  if (!file.exists()) {
421  emit scriptLog("Unable to load file " + _filename + " as python script. File not found!");
422 
423  // Fail when in batch mode
424  if (OpenFlipper::Options::nogui())
425  exit(1);
426 
427  return;
428  }
429 
430  file.open(QIODevice::ReadOnly| QFile::Text);
431 
432  QTextStream in(&file);
433 
434  QString script = in.readAll();
435 
436  executePythonScript(script);
437 
438 }
439 
440 
441 void Core::executePythonScript(QString _script) {
442 #ifdef PYTHON_ENABLED
444  interpreter->runScript(_script);
445 #else
446  emit scriptLog("Python scripting Error! No build in python support. Unable to execute script. Build OpenFlipper with Python support to enable Python based scripting.");
447 #endif
448 }
449 
void createWidget(QString _objectName, QString _uiFilename, bool _show=true)
Create an script object from a ui file.
Definition: scripting.cc:91
QWidget * getToolbox(QString _pluginName, QString _toolboxName)
Definition: scripting.cc:230
void setToolBoxActive(QString _toolBoxName, bool _active)
Scripting function to activate or deactivate a toolbox.
Definition: scripting.cc:303
void setElementActive(QString _name, bool _active)
set the active state of given element
Definition: SideArea.cc:212
void slotExecuteScript(QString _script)
Definition: scripting.cc:71
void moveToolBoxToBottom(QString _name)
Move a specific toolbox widget to the bottom of the side area.
Definition: viewMode.cc:457
void addViewModeToolbars(QString _modeName, QString _toolbarList)
Scripting function to set toolbars in a view mode.
Definition: scripting.cc:197
bool runScript(QString _script)
Run a script. Output is passed to the standard logging facilities of OpenFlipper. ...
void scriptLogFunction(QString _output)
stream for logging to file
Definition: scripting.cc:87
static PythonInterpreter * getInstance()
Creates or returns an instance of the interpreter.
Definition: Core.hh:132
void setView(QString view)
Called when a plugin requests an update in the viewer.
Definition: scripting.cc:320
int getObjectId(const QString &_name)
void executeFileScript(QString _filename)
Core scripting engine.
void slotAddViewModeContextMenus(QString _mode, QStringList _usedToolbars)
Add or change Toolbars for a ViewMode (non-userdefined viewMode)
Definition: viewMode.cc:196
QScriptValue helpFunction(QScriptContext *context, QScriptEngine *engine)
Function to print help about scripting functions.
Definition: scripting.cc:380
void addViewModeContextMenus(QString _modeName, QString _contextMenuList)
Scripting function to set context menus in a view mode.
Definition: scripting.cc:205
QScriptValue printToFileFunction(QScriptContext *context, QScriptEngine *engine)
Special print function for sending output to a file.
Definition: scripting.cc:354
SideArea * toolBox_
Toolbox.
Definition: CoreWidget.hh:734
void log(Logtype _type, QString _message)
Logg with OUT,WARN or ERR as type.
void executePythonScriptFile(QString _filename)
Open the given file and execute its contents as a python script.
Definition: scripting.cc:417
void slotSetViewModeIcon(QString _mode, QString _iconName)
Sets the Icon for a given View Mode (non-userdefined viewMode)
Definition: viewMode.cc:243
void setViewMode(QString _mode, bool _expandAll=false)
Set the view Mode to the given Mode.
Definition: viewMode.cc:316
void executeScript(QString _script)
Core scripting engine.
void expandToolBoxWidget(QWidget *widget, bool expand)
Definition: picking.cc:491
CoreWidget * coreWidget_
The main applications widget ( only created in gui mode )
Definition: Core.hh:1596
QStringList scriptingFunctions_
List of all registered scripting functions.
Definition: Core.hh:1348
void slotAddViewModeToolbars(QString _mode, QStringList _usedToolbars)
Add or change Toolbars for a ViewMode (non-userdefined viewMode)
Definition: viewMode.cc:140
This class provides OpenFlippers Python interpreter.
QScriptEngine scriptEngine_
Core scripting engine.
Definition: Core.hh:1342
void moveToolBoxToTop(QString _name)
Move a specific toolbox widget to the top of the side area.
Definition: viewMode.cc:452
void setToolBoxOrientationOnTheRight(bool _toolBoxRight)
Set orientation of tool box (either on the right or the left side of the screen)
Definition: CoreWidget.cc:820
void addViewModeToolboxes(QString _modeName, QString _toolboxList)
Scripting function to set toolboxes in a view mode.
Definition: scripting.cc:189
QVector< ViewMode * > viewModes_
List of available draw modes.
Definition: Core.hh:1605
void setToolBoxSide(QString _side)
Scripting function to set the side of the main window on which the toolbox should be displayed...
Definition: scripting.cc:217
QScriptValue myPrintFunction(QScriptContext *context, QScriptEngine *engine)
Special print function for core logger.
Definition: scripting.cc:336
QString getCurrentViewMode()
Get current view mode.
Definition: scripting.cc:145
void unblockSceneGraphUpdates()
Unblock the scenegraph updates.
Definition: scripting.cc:316
void blockSceneGraphUpdates()
Block the scenegraph updates.
Definition: scripting.cc:311
void slotScriptError(const QScriptValue &error)
Core scripting engine.
Definition: scripting.cc:332
void slotSetView(QString view)
Set the supplied serialized view.
void slotGetScriptingEngine(QScriptEngine *&_engine)
Core scripting engine.
Definition: scripting.cc:79
void setViewModeIcon(QString _mode, QString _iconName)
Set the icon of a viewMode.
Definition: scripting.cc:151
void activateToolbox(QString _pluginName, QString _toolboxName, bool activate)
expand or collapse a toolbox
Definition: scripting.cc:248
void scriptInfo(QString _pluginName, QString _functionName)
Core scripting engine.
void addToolbox(QString _name, QWidget *_widget)
Add a Toolbox from a plugin or from scripting.
Definition: scripting.cc:253
void setViewMode(QString _viewMode)
Set the active ViewMode.
Definition: scripting.cc:137
std::vector< PluginInfo > & plugins()
Index of Plugins toolbox widget.
Definition: Core.cc:765
void scriptLog(QString _message)
Logging signal for ScriptEngine.
void slotScriptInfo(QString _pluginName, QString _functionName)
Core scripting engine.
Definition: scripting.cc:67
void slotSetViewAndWindowGeometry(QString view)
Set the supplied serialized view.
void moveToolBoxToTop(QString _name)
Move selected toolbox to top of side area.
Definition: scripting.cc:171
void addViewModeIcon(QString _modeName, QString _iconName)
Scripting function to set an icon for a view mode.
Definition: scripting.cc:211
void slotExecuteFileScript(QString _filename)
Definition: scripting.cc:75
int getObjectId(QString _filename)
Get object id from filename.
Definition: scripting.cc:130
void slotAddViewModeToolboxes(QString _mode, QStringList _usedWidgets)
Add or change Toolboxes for a ViewMode (non-userdefined viewMode)
Definition: viewMode.cc:93
void executePythonScript(QString _script)
execute the given string as a python script
Definition: scripting.cc:441
void moveToolBoxToBottom(QString _name)
Move selected toolbox to bottom of side area.
Definition: scripting.cc:180
void slotGetAllAvailableFunctions(QStringList &_functions)
Core scripting engine.
Definition: scripting.cc:83
void setViewAndWindowGeometry(QString view)
Called when a plugin requests an update in the viewer.
Definition: scripting.cc:324