Developer Documentation
ScriptingPlugin.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 #include "ScriptingPlugin.hh"
45 
47 
48 
49 
50 ScriptingPlugin::ScriptingPlugin() :
51  lastProblemLine_(0),
52  lastError_(""),
53  errorTimer_(0),
54  descrLayout_(0),
55  scriptWidget_(0),
56  statusBar_(0),
57  highlighterCurrent_(0),
58  highlighterLive_(0),
59  highlighterList_(0),
60  lastFile_(""),
61  scriptPath_(""),
62  debuggerButton_(0)
63 #ifdef ENABLE_SCRIPT_DEBUGGER
64  #ifdef QT_SCRIPTTOOLS_LIB
65  ,debugger_(0)
66  #endif
67 #endif
68 {
69 
70 }
71 
73 
74  if ( OpenFlipper::Options::nogui() )
75  return;
76 
78 
79  // Scriping Menu
80  QMenu *scriptingMenu;
81 
82  emit getMenubarMenu(tr("&Scripting"), scriptingMenu, true );
83 
84  QIcon icon;
85  QAction* showWidget = scriptingMenu->addAction( tr("Show script editor") );
86  icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"scriptEditor.png");
87  showWidget->setIcon(icon);
88  connect( showWidget, SIGNAL( triggered() ) ,
89  this , SLOT( showScriptWidget() ));
90 
91  scriptWidget_ = new ScriptWidget();
92 
93 
94  QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
95 
96  scriptWidget_->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
97 
98  icon.addFile(iconPath+"document-open.png");
99  scriptWidget_->actionLoad_Script->setIcon(icon);
100 
101  icon.addFile(iconPath+"document-save.png");
102  scriptWidget_->actionSave_Script->setIcon(icon);
103 
104  icon.addFile(iconPath+"document-save-as.png");
105  scriptWidget_->actionSave_Script_As->setIcon(icon);
106 
107  icon.addFile(iconPath+"window-close.png");
108  scriptWidget_->actionClose->setIcon(icon);
109 
110  // ==================================================================
111  // Add a toolbar
112  // ==================================================================
113 
114  QToolBar* toolBar = new QToolBar(tr("Scripting Toolbar"));
115 
116  QAction* openButton = new QAction(QIcon(iconPath + "document-open.png"), "Open", toolBar);
117  toolBar->addAction(openButton);
118  connect (openButton, SIGNAL( triggered() ), this, SLOT( slotLoadScript() ) );
119 
120  QAction* saveButton = new QAction(QIcon(iconPath + "document-save.png"), "Save", toolBar);
121  toolBar->addAction(saveButton);
122  connect (saveButton, SIGNAL( triggered() ), this, SLOT( slotSaveScript() ) );
123 
124  QAction* saveAsButton = new QAction(QIcon(iconPath + "document-save-as.png"), "Save as", toolBar);
125  toolBar->addAction(saveAsButton);
126  connect (saveAsButton, SIGNAL( triggered() ), this, SLOT( slotSaveScriptAs() ) );
127 
128  toolBar->addSeparator();
129 
130  debuggerButton_ = new QAction(QIcon(iconPath + "script-debugger.png"), "Enable Debugger", toolBar);
131  debuggerButton_->setCheckable(true);
132  toolBar->addAction(debuggerButton_);
133 
134 #ifdef ENABLE_SCRIPT_DEBUGGER
135  if ( OpenFlipperSettings().value("Scripting/QtScriptDebugger",true).toBool() )
136  debuggerButton_->setChecked(true);
137  else
138  debuggerButton_->setChecked(false);
139 
140  connect (debuggerButton_, SIGNAL( triggered() ), this, SLOT( slotDebuggerButton() ) );
141 #else
142  debuggerButton_->setEnabled(false);
143  debuggerButton_->setToolTip(tr("QtScriptTools library not available. Debugger is not available!"));
144 #endif
145 
146  toolBar->addSeparator();
147 
148  QAction* executeButton = new QAction(QIcon(iconPath + "arrow-right.png"), "Execute", toolBar);
149  toolBar->addAction(executeButton);
150  connect (executeButton, SIGNAL( triggered() ), this, SLOT( slotExecuteScriptButton() ) );
151 
152  scriptWidget_->addToolBar(toolBar);
153 
154  // ==================================================================
155  // Create a status bar
156  // ==================================================================
157 
158  statusBar_ = new QStatusBar();
159 
160  scriptWidget_->setStatusBar( statusBar_ );
161 
162  // ==================================================================
163 
164  scriptWidget_->hide();
165 
166  scriptWidget_->resize(scriptWidget_->width() , std::min(QApplication::desktop()->screenGeometry().height() - 150 , 800) );
167 
168  connect (scriptWidget_->actionLoad_Script, SIGNAL( triggered() ), this, SLOT( slotLoadScript() ) );
169  scriptWidget_->actionLoad_Script->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_O) );
170  connect (scriptWidget_->actionSave_Script, SIGNAL( triggered() ), this, SLOT( slotSaveScript() ) );
171  scriptWidget_->actionSave_Script->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_S) );
172  connect (scriptWidget_->actionSave_Script_As, SIGNAL( triggered() ), this, SLOT( slotSaveScriptAs() ) );
173  connect (scriptWidget_->actionClose, SIGNAL( triggered() ), scriptWidget_, SLOT( close() ) );
174 
175  connect (scriptWidget_->currentScript, SIGNAL( textChanged() ), this, SLOT( slotScriptChanged() ) );
176 
177  connect (scriptWidget_->functionList, SIGNAL( currentItemChanged (QListWidgetItem*, QListWidgetItem*) ),
178  this, SLOT( slotFunctionClicked(QListWidgetItem*) ));
179  connect (scriptWidget_->functionList, SIGNAL( itemDoubleClicked(QListWidgetItem*) ),
180  this, SLOT( slotFunctionDoubleClicked(QListWidgetItem*) ));
181 
182  //filter
183  connect (scriptWidget_->filterButton, SIGNAL( clicked() ),
184  this, SLOT( slotApplyFilter() ));
185  connect (scriptWidget_->resetButton, SIGNAL( clicked() ),
186  scriptWidget_->functionList, SLOT( reset() ));
187  connect (scriptWidget_->resetButton, SIGNAL( clicked() ),
188  scriptWidget_->filterEdit, SLOT( clear() ));
189  connect (scriptWidget_->functionList, SIGNAL(getDescription(QString,QString&,QStringList&,QStringList&)),
190  this , SIGNAL(getDescription(QString,QString&,QStringList&,QStringList&)));
191 
192  scriptWidget_->description->setVisible( false );
193 
194  highlighterCurrent_ = new Highlighter( scriptWidget_->currentScript->document() );
195  highlighterLive_ = new Highlighter( scriptWidget_->liveEdit );
196 // highlighterList_ = new Highlighter( scriptWidget_->functionList );
197  frameTime_.start();
198 
199 
200  // Timer for syntax error while editing. If the Syntax is not correct
201  // And the text does not change for a specified time, the line will be highlighted
202  // And a message printed to the status bar
203  errorTimer_ = new QTimer();
204  errorTimer_->setSingleShot(true);
205  connect(errorTimer_,SIGNAL(timeout()),this,SLOT(slotHighlightError()));
206 
207  // ==================================================================
208  // Setup scripting debugger if available
209  // ==================================================================
210 
211 #ifdef ENABLE_SCRIPT_DEBUGGER
212  #ifdef QT_SCRIPTTOOLS_LIB
213  QScriptEngine* engine;
214  emit getScriptingEngine( engine );
215  debugger_ = new QScriptEngineDebugger;
216 
217  if ( OpenFlipperSettings().value("Scripting/QtScriptDebugger",false).toBool() )
218  debugger_->attachTo(engine);
219  #endif
220 #endif
221 }
222 
223 void ScriptingPlugin::slotApplyFilter(){
224  scriptWidget_->functionList->filter( scriptWidget_->filterEdit->text() );
225 }
226 
228  scriptWidget_->actionSave_Script->setEnabled( true );
229 
230  // Stop timers, as the text changed!
231  errorTimer_->stop();
232 
233  // Check the current script for syntax
234  const QString script = scriptWidget_->currentScript->toPlainText();
235  QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax ( script );
236 
237  switch (syntaxCheck.state() ) {
238  case QScriptSyntaxCheckResult::Error :
239  lastProblemLine_ = syntaxCheck.errorLineNumber();
240  lastError_ = syntaxCheck.errorMessage();
241  errorTimer_->start(500);
242  break;
243  case QScriptSyntaxCheckResult::Valid :
244  break;
245  default :
246  break;
247  }
248 }
249 
251  scriptWidget_->currentScript->highLightErrorLine(lastProblemLine_);
252  statusBar_->showMessage(lastError_,5000);
253 }
254 
256  if ( OpenFlipper::Options::nogui() )
257  return;
258 
259  scriptWidget_->show();
260 
261  // Update list of available functions
262  QStringList completeList;
263  emit getAvailableFunctions( completeList );
264 
265  QStringList plugins;
266  QStringList functions;
267 
268  scriptWidget_->functionList->clear( );
269 
270  //Update Highlighters
271  for ( int i = 0 ; i < completeList.size() ; ++i) {
272 
273  QString plugin = completeList[i].section('.',0,0);
274 
275  // Global functions start with - and are not added as plugins!
276  if (plugin != "-") {
277  if ( ! plugins.contains( plugin ) )
278  plugins.push_back( plugin );
279  }
280 
281 
282  QString function = completeList[i].section('.',1,1);
283  function = function.section('(',0,0);
284  if ( ! functions.contains( function ) )
285  functions.push_back( function );
286 
287  // Either write the whole string or cut the "-." for global functions
288  if ( plugin != "-")
289  scriptWidget_->functionList->addItem( completeList[i] );
290  else
291  scriptWidget_->functionList->addItem( completeList[i].right(completeList[i].size() - 2) );
292 
293  }
294 
295  // Sort the available functions
296  scriptWidget_->functionList->sortItems ( );
297 
298  highlighterCurrent_->pluginPatterns_ = plugins;
299  highlighterCurrent_->functionPatterns_ = functions;
300  highlighterCurrent_->update();
301  highlighterCurrent_->rehighlight();
302 
303  highlighterLive_->pluginPatterns_ = plugins;
304  highlighterLive_->functionPatterns_ = functions;
305  highlighterLive_->update();
306  highlighterLive_->rehighlight();
307 
308  // Bring it to foreground
309  scriptWidget_->raise();
310 
311 }
312 
314  if ( OpenFlipper::Options::nogui() )
315  return;
316 
317  scriptWidget_->hide();
318 }
319 
320 void ScriptingPlugin::slotScriptInfo( QString _pluginName , QString _functionName ) {
321 
322  if ( OpenFlipper::Options::scripting() || OpenFlipper::Options::nogui() )
323  return;
324 
325  scriptWidget_->liveEdit->append( _pluginName + "." + _functionName );
326 
327  QScrollBar* bar = scriptWidget_->liveEdit->verticalScrollBar();
328  bar->setValue(bar->maximum());
329 }
330 
331 void ScriptingPlugin::slotExecuteScript( QString _script ) {
332 
333  if ( OpenFlipper::Options::gui())
334  statusBar_->showMessage(tr("Executing Script"));
335 
336  QScriptEngine* engine;
337  emit getScriptingEngine( engine );
338 
340  OpenFlipper::Options::scripting(true);
341 
342  // Get the filename of the script and set it in the scripting environment
343  engine->globalObject().setProperty("ScriptPath",OpenFlipper::Options::currentScriptDirStr());
344 
345  // Check if the script contains include statements
346  if (_script.contains(QRegExp("^include <")) ) {
347 
348  // Split input script into lines
349  QStringList script = _script.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
350 
351  // Find first include statement
352  int include_index = script.indexOf(QRegExp("^include.*"));
353 
354  while ( include_index != -1) {
355 
356  QString include_statement = script[include_index];
357 
358  // Extract the file path of the include
359  include_statement.remove(QRegExp("^include") );
360  include_statement.remove("<" );
361  include_statement.remove(">" );
362  include_statement = include_statement.trimmed();
363 
364  // Replace the ScriptPath component
365  include_statement.replace("ScriptPath",OpenFlipper::Options::currentScriptDirStr());
366 
367  QFile includeFile(include_statement);
368 
369  if (!includeFile.exists() ) {
370  emit log(LOGERR,"Script file include not found : " + include_statement + " from " + script[include_index] );
371  return;
372  } else {
373 
374  if (!includeFile.open(QFile::ReadOnly | QFile::Text)) {
375  emit log(LOGERR,"Unable to open file : " + include_statement);
376  return;
377  }
378 
379  QTextStream in(&includeFile);
380  script[include_index] = in.readAll();
381  includeFile.close();
382  }
383 
384  // Recombine all script components
385  _script = script.join("\n");
386 
387  // Check for next occurence of an include statement
388  include_index = script.indexOf(QRegExp("^include.*"));
389 
390  }
391 
392  }
393 
394  // Execute the script
395  engine->evaluate( _script );
396 
397  // Catch errors and print some reasonable error message to log and statusbar
398  bool error = false;
399  if ( engine->hasUncaughtException() ) {
400  error = true;
401  QScriptValue result = engine->uncaughtException();
402  QString exception = result.toString();
403  int lineNumber = engine->uncaughtExceptionLineNumber();
404  emit log( LOGERR , tr("Script execution failed at line %1, with : %2 ").arg(lineNumber).arg(exception) );
405 
406  if ( OpenFlipper::Options::gui()) {
407  statusBar_->showMessage(tr("Script execution failed at line %1, with : %2 ").arg(lineNumber).arg(exception));
408 
409  // Get cursor and move it to the line containing the error
410  QTextCursor cursor = scriptWidget_->currentScript->textCursor();
411  cursor.setPosition(0);
412  cursor.movePosition ( QTextCursor::Down, QTextCursor::MoveAnchor, lineNumber - 1 );
413  scriptWidget_->currentScript->setTextCursor(cursor);
414 
415  scriptWidget_->currentScript->highLightErrorLine(lineNumber);
416 
417  lastProblemLine_ = lineNumber;
418  lastError_ = exception;
419 
420  }
421  }
422 
423  if ( OpenFlipper::Options::gui() && !error)
424  statusBar_->clearMessage();
425 
427  OpenFlipper::Options::scripting(false);
428 }
429 
430 void ScriptingPlugin::slotExecuteFileScript( QString _filename ) {
431  QString script;
432 
433  QFile data(_filename);
434  if (data.open(QFile::ReadOnly)) {
435  QTextStream input(&data);
436  do {
437  script.append(input.readLine() + "\n");
438  } while (!input.atEnd());
439 
440  if ( OpenFlipper::Options::gui() )
441  scriptWidget_->currentScript->setPlainText(script);
442 
443  // Set the correct execution environment
444  OpenFlipper::Options::currentScriptDir( _filename.section(OpenFlipper::Options::dirSeparator(), 0, -2) );
445 
446  slotExecuteScript(script);
447 
448  } else
449  emit log(LOGERR,tr("Unable to open script file!"));
450 }
451 
452 void ScriptingPlugin::slotExecuteScriptButton() {
453  slotExecuteScript( scriptWidget_->currentScript->toPlainText() );
454 }
455 
457 
458 #ifdef ENABLE_SCRIPT_DEBUGGER
459  #ifdef QT_SCRIPTTOOLS_LIB
460  QScriptEngine* engine;
461  emit getScriptingEngine( engine );
462 
463  if ( debuggerButton_->isChecked() ) {
464  debugger_->attachTo(engine);
465  } else {
466  debugger_->detach();
467  }
468 
469  OpenFlipperSettings().setValue("Scripting/QtScriptDebugger",debuggerButton_->isChecked());
470  #endif
471 #endif
472 
473 }
474 
475 QString ScriptingPlugin::mangleScript(QString _input ) {
476 
477  // Update list of available functions
478  QStringList functions;
479  emit getAvailableFunctions( functions );
480 
481  std::cerr << "Todo : mangle script " << std::endl;
482  return _input;
483 
484 }
485 
486 void ScriptingPlugin::sleep( int _seconds ) {
487 
488  if ( OpenFlipper::Options::nogui() )
489  return;
490 
491  QTimer timer;
492 
493  timer.setSingleShot(true);
494  timer.start( _seconds * 1000 );
495 
496  while (timer.isActive() )
497  QApplication::processEvents();
498 
499 }
500 
501 void ScriptingPlugin::sleepmsecs( int _mseconds ) {
502 
503  if ( OpenFlipper::Options::nogui() )
504  return;
505 
506  QTimer timer;
507 
508  timer.setSingleShot(true);
509  timer.start( _mseconds );
510 
511  while (timer.isActive() )
512  QApplication::processEvents();
513 
514 }
515 
517  frameTime_.restart();
518 }
519 
520 void ScriptingPlugin::waitFrameEnd( int _mseconds ) {
521  int elapsed = frameTime_.elapsed();
522 
523  // Wait remaining time
524  if ( elapsed < _mseconds ) {
525  sleepmsecs( _mseconds - elapsed );
526  }
527 
528  // restart timer
529  frameTime_.restart();
530 
531 }
532 
533 
535  if ( OpenFlipper::Options::nogui() )
536  return;
537 
538  QMessageBox box;
539 
540  box.addButton(tr("Continue"),QMessageBox::AcceptRole);
541  box.setText(tr("Script execution has been interrupted"));
542  box.setIcon(QMessageBox::Information);
543  box.setWindowModality(Qt::NonModal);
544  box.setWindowTitle(tr("Continue?"));
545  box.setWindowFlags( box.windowFlags() | Qt::WindowStaysOnTopHint);
546  box.show();
547 
548  while ( box.isVisible() )
549  QApplication::processEvents();
550 
551 }
552 
553 void ScriptingPlugin::waitContinue( QString _msg, int _x, int _y ) {
554  if ( OpenFlipper::Options::nogui() )
555  return;
556 
557  QMessageBox box;
558 
559 
560  box.addButton(tr("Continue"),QMessageBox::AcceptRole);
561  box.setText(_msg);
562  box.setIcon(QMessageBox::Information);
563  box.setWindowModality(Qt::NonModal);
564  box.setWindowTitle(tr("Continue?"));
565  box.setWindowFlags( box.windowFlags() | Qt::WindowStaysOnTopHint);
566  if(_x!=-1 && _y!=-1)
567  box.move(_x,_y);
568  box.show();
569 
570  while ( box.isVisible() )
571  QApplication::processEvents();
572 
573 }
574 
575 
576 void ScriptingPlugin::slotLoadScript(){
577 
578  QString lastOpened = OpenFlipperSettings().value("Scripting/CurrentDir",OpenFlipper::Options::currentScriptDirStr()).toString();
579 
580  QString filename = QFileDialog::getOpenFileName(0,
581  tr("Load Script"),lastOpened , tr("Script Files (*.ofs)"));
582 
583  if (filename == "")
584  return;
585 
586  QFileInfo info (filename);
587  OpenFlipperSettings().setValue("Scripting/CurrentDir",info.path());
588 
589  slotLoadScript(filename);
590 }
591 
592 void ScriptingPlugin::slotLoadScript( QString _filename ) {
593 
594  if (_filename == "")
595  return;
596 
597  // Check if we are in gui mode. Otherwise just ignore this call
598  if ( OpenFlipper::Options::gui() ) {
599  scriptWidget_->currentScript->clear();
600 
601  QFile data(_filename);
602 
603  if (data.open(QFile::ReadOnly)) {
604  QTextStream input(&data);
605  do {
606  scriptWidget_->currentScript->appendPlainText(input.readLine());
607  } while (!input.atEnd());
608 
609  lastFile_ = _filename;
610  OpenFlipper::Options::currentScriptDir( QFileInfo(_filename).absolutePath() );
611 
612  scriptWidget_->actionSave_Script->setEnabled( false );
613 
614  scriptWidget_->show();
615  }
616  }
617 
618 }
619 
620 void ScriptingPlugin::slotSaveScript(){
621 
622  QFile file(lastFile_);
623 
624  if ( !file.exists())
625  slotSaveScriptAs();
626  else{
627  //write script to file
628  if (file.open(QFile::WriteOnly)) {
629  QTextStream output(&file);
630  output << scriptWidget_->currentScript->toPlainText();
631  }
632  scriptWidget_->actionSave_Script->setEnabled( false );
633  }
634 }
635 
636 void ScriptingPlugin::slotSaveScriptAs(){
637  QString lastOpened = OpenFlipperSettings().value("Scripting/CurrentDir",OpenFlipper::Options::currentScriptDirStr()).toString();
638 
639  QString filename = QFileDialog::getSaveFileName(scriptWidget_,
640  tr("Save Script"),lastOpened, tr("Script Files (*.ofs)"));
641 
642  if (filename == "") return;
643 
644  QFileInfo info (filename);
645  OpenFlipperSettings().setValue("Scripting/CurrentDir",info.path());
646 
647 
648  QFile data(filename);
649 
650  //perhaps add an extension
651  if (!data.exists()){
652  QFileInfo fi(filename);
653  if (fi.completeSuffix() == ""){
654  filename = filename + ".ofs";
655  data.setFileName(filename);
656  }
657  }
658 
659  //write script to file
660  if (data.open(QFile::WriteOnly)) {
661  QTextStream output(&data);
662  output << scriptWidget_->currentScript->toPlainText();
663  }
664 
665  lastFile_ = filename;
666  OpenFlipper::Options::currentScriptDir( QFileInfo(filename).absolutePath() );
667 
668  scriptWidget_->actionSave_Script->setEnabled( false );
669 }
670 
671 void ScriptingPlugin::slotFunctionClicked(QListWidgetItem * _item)
672 {
673 
674  if ( _item == 0)
675  return;
676 
677  QString slotDescription;
678  QStringList params;
679  QStringList descriptions;
680 
681  emit getDescription(_item->text(), slotDescription, params, descriptions);
682 
683  if ( !slotDescription.isEmpty() ){
684 
685  if (descriptionLabels_.count() > 0){
686  //first remove old stuff
687  for (int i = 0; i < descriptionLabels_.count(); i++){
688  descrLayout_->removeWidget( descriptionLabels_[i] );
689  delete descriptionLabels_[i];
690  }
691  descriptionLabels_.clear();
692  }else
693  descrLayout_ = new QVBoxLayout();
694 
695  QLabel* lSlotName = new QLabel("<B>" + _item->text() + "</B>");
696  QLabel* lDescription = new QLabel(slotDescription);
697  lDescription->setWordWrap(true);
698 
699  descrLayout_->addWidget(lSlotName);
700  descrLayout_->addWidget(lDescription);
701 
702  descriptionLabels_.append(lSlotName);
703  descriptionLabels_.append(lDescription);
704 
705  if ( params.count() == descriptions.count() ){
706 
707  //get parameter-types from function-name
708  QString typeStr = _item->text().section("(",1,1).section(")",0,0);
709  QStringList types = typeStr.split(",");
710 
711  if (types.count() == params.count()){
712 
713  for(int p=0; p < params.count(); p++ ){
714  QLabel* param = new QLabel("<B>" + types[p] + " " + params[p] + ":</B>" );
715  QLabel* descr = new QLabel(descriptions[p]);
716  descr->setWordWrap(true);
717  descrLayout_->addWidget(param);
718  descrLayout_->addWidget(descr);
719 
720  descriptionLabels_.append(param);
721  descriptionLabels_.append(descr);
722  }
723 
724  }
725 
726  }
727 
728 
729  scriptWidget_->description->setLayout( descrLayout_ );
730  }
731 
732  scriptWidget_->description->setVisible( !slotDescription.isEmpty() );
733 }
734 
735 void ScriptingPlugin::slotFunctionDoubleClicked(QListWidgetItem * _item)
736 {
737  scriptWidget_->currentScript->insertPlainText( _item->text() );
738 }
739 
741 {
742  if ( OpenFlipper::Options::nogui() )
743  return;
744 
745  /*
746  * This is called from the VSI and other plugins with pure code
747  * we do not want to overwrite any previously opened scripts
748  */
749  lastFile_ = "";
750  OpenFlipper::Options::currentScriptDir( "" );
751 
752  showScriptWidget ();
753 
754  scriptWidget_->currentScript->setPlainText(_code);
755 }
756 
758  if ( OpenFlipper::Options::nogui() )
759  return;
760 
761  scriptWidget_->currentScript->clear();
762 }
763 
764 
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
void slotScriptChanged()
Called everytime the text in the scriptingwidget is changed by the user.
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void frameStart()
Marks the current time as the frame start ( Use wait sleepFrameLength to wait until _mseconds have pa...
void showScriptInEditor(QString _code)
Show the given Code in the script editor.
void showScriptWidget()
Show the script editor widget.
void sleep(int _seconds)
Sleeps for some seconds in script execution ( Gui will remain functional)
void waitFrameEnd(int _mseconds)
wait until _mseconds have passed since frameStart (if more time has passed, it will return immediatel...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
void clearEditor()
Clear the editor window Clears the script editor window.
void slotExecuteScript(QString _script)
void sleepmsecs(int _mseconds)
Sleeps for some mseconds in script execution ( Gui will remain functional)
void slotHighlightError()
Called when an error is detected when checking the syntax.
void hideScriptWidget()
Hide the script editor widget.
void slotDebuggerButton()
Triggered by the debugger button.