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