• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

rocs/RocsCore

  • sources
  • kde-4.12
  • kdeedu
  • rocs
  • RocsCore
QtScriptBackend.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Rocs.
3  Copyright 2004-2011 Tomaz Canabrava <tomaz.canabrava@gmail.com>
4  Copyright 2012 Andreas Cord-Landwehr <cola@uni-paderborn.de>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "QtScriptBackend.h"
21 #include "DataStructure.h"
22 #include "Data.h"
23 #include "Document.h"
24 #include "DocumentManager.h"
25 
26 #include <KLocale>
27 #include <KDebug>
28 #include <QAction>
29 #include <QScriptEngineDebugger>
30 
31 
32 class QtScriptBackendPrivate
33 {
34 public:
35  QString _currentScript;
36  Document *_document;
37  QScriptEngine *_engine;
38  QScriptEngineDebugger *_engineSteps; // used for stepped execution
39  IncludeManager _includeManager;
40  bool _runningTool;
41 
42  QtScriptBackendPrivate()
43  : _engine(new QScriptEngine())
44  , _engineSteps(0)
45  , _runningTool(false)
46  {
47  }
48 
49  ~QtScriptBackendPrivate()
50  {
51  delete _engine;
52  }
53 
54  void createGraphList()
55  {
56  QScriptValue graphList = _engine->newArray();
57  _engine->globalObject().setProperty("graphs", graphList);
58 
59  // Add all the graphs on the array as an array, and if it has a name,
60  // also add it for direct access with it's name.
61  int size = _document->dataStructures().size();
62  for (int i = 0; i < size; i++) {
63  graphList.property("push").call(graphList, QScriptValueList() << _document->dataStructures().at(i)->scriptValue());
64  }
65  }
66 };
67 
68 
69 static QScriptValue debug_script(QScriptContext* context, QScriptEngine* /*engine*/)
70 {
71  DocumentManager::self().activeDocument()->engineBackend()->debug(QString("%1").arg(context->argument(0).toString()));
72  return QScriptValue();
73 }
74 
75 static QScriptValue output_script(QScriptContext *context, QScriptEngine* /*engine*/)
76 {
77  DocumentManager::self().activeDocument()->engineBackend()->output(QString("%1").arg(context->argument(0).toString()));
78  return QScriptValue();
79 }
80 
81 static QScriptValue interrupt_script(QScriptContext *context, QScriptEngine* /*engine*/)
82 {
83  Q_UNUSED(context);
84  DocumentManager::self().activeDocument()->engineBackend()->interrupt();
85  return QScriptValue();
86 }
87 
88 static QScriptValue include_script(QScriptContext *context, QScriptEngine* /*engine*/)
89 {
90  DocumentManager::self().activeDocument()->engineBackend()->include(QString("%1").arg(context->argument(0).toString()));
91  return QScriptValue();
92 }
93 
94 QtScriptBackend::QtScriptBackend(QObject* parent)
95  : QObject(parent)
96  , d(new QtScriptBackendPrivate)
97 {
98 }
99 
100 QtScriptBackend::~QtScriptBackend()
101 {
102 }
103 
104 QScriptEngine* QtScriptBackend::engine() const
105 {
106  return d->_engine;
107 }
108 
109 void QtScriptBackend::loadFile(const QString& file)
110 {
111  d->_currentScript.clear();
112  QFile f(file);
113  if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
114  kDebug() << "File not found";
115  return;
116  }
117 
118  while (! f.atEnd()) {
119  QByteArray line = f.readLine();
120  d->_currentScript += line;
121  }
122  d->_currentScript += '\n';
123 }
124 
125 QScriptValue QtScriptBackend::registerGlobalObject(QObject *qobject, const QString &name)
126 {
127  if (!d->_engine) {
128  d->_engine = new QScriptEngine(this);
129  emit engineCreated(d->_engine);
130  }
131  QScriptValue globalObject = d->_engine->newQObject(qobject);
132  d->_engine->globalObject().setProperty(name, globalObject);
133 
134  return globalObject;
135 }
136 
137 IncludeManager& QtScriptBackend::includeManager() const
138 {
139  return d->_includeManager;
140 }
141 
142 void QtScriptBackend::stop()
143 {
144  // check for stepped execution
145  if (d->_engineSteps) {
146  d->_engineSteps->action(QScriptEngineDebugger::ContinueAction)->trigger();
147  d->_engineSteps->detach();
148  d->_engineSteps->deleteLater();
149  d->_engineSteps = 0;
150  }
151 
152  // abort possibly running execution
153  if (d->_engine && d->_engine->isEvaluating()) {
154  d->_engine->abortEvaluation();
155  }
156 
157  if (d->_engine) {
158  d->_engine->deleteLater();
159  d->_engine = 0;
160  }
161  emit finished();
162 }
163 
164 QString QtScriptBackend::execute()
165 {
166  if (!d->_engine) {
167  d->_engine = new QScriptEngine(this);
168  emit engineCreated(d->_engine);
169  }
170 
171  if (d->_engine->isEvaluating()) {
172  d->_engine->abortEvaluation();
173  }
174  d->_engine->collectGarbage();
175  d->_engine->pushContext();
176  d->_engine->globalObject().setProperty("debug", engine()->newFunction(debug_script));
177  d->_engine->globalObject().setProperty("output", engine()->newFunction(output_script));
178  d->_engine->globalObject().setProperty("interrupt", engine()->newFunction(interrupt_script));
179  d->_engine->globalObject().setProperty("include", engine()->newFunction(include_script));
180 
181  int size = d->_document->dataStructures().size();
182  for (int i = 0; i < size; i++) {
183  d->_document->dataStructures().at(i)->setEngine(d->_engine);
184  connect(d->_document->dataStructures().at(i).get(), SIGNAL(scriptError(QString)), this, SIGNAL(scriptError(QString)));
185  }
186  d->createGraphList();
187  d->_engine->setProcessEventsInterval(100);
188 
189  QString result = d->_engine->evaluate(d->_currentScript, i18n("Rocs Console script")).toString();
190  if (d->_engine && d->_engine->hasUncaughtException()) {
191  emit scriptError(i18n("Script Error: %1", result));
192  emit scriptError(d->_engine->uncaughtExceptionBacktrace().join("\n"));
193  }
194  if (d->_engine) {
195  emit scriptInfo(i18nc("@info status message after successful script execution", "<i>Execution Finished</i>"));
196  d->_engine->popContext();
197  for (int i = 0; i < size; i++) {
198  d->_document->dataStructures().at(i).get()->disconnect(this);
199  }
200  }
201  emit finished();
202  return result;
203 }
204 
205 void QtScriptBackend::executeStep()
206 {
207  // prepare new engine if execution not running yet
208  if (!d->_engine) {
209  d->_engine = new QScriptEngine(this);
210  emit engineCreated(d->_engine);
211  }
212 
213  // create step-executor if not present
214  if (!d->_engineSteps) {
215  d->_engineSteps = new QScriptEngineDebugger(this);
216  d->_engineSteps->setAutoShowStandardWindow(false); // we do not want to have a debugger window
217  d->_engineSteps->attachTo(d->_engine);
218  }
219 
220  if (!d->_engine->isEvaluating()) {
221  d->_engine->globalObject().setProperty("debug", engine()->newFunction(debug_script));
222  d->_engine->globalObject().setProperty("output", engine()->newFunction(output_script));
223  d->_engine->globalObject().setProperty("interrupt", engine()->newFunction(interrupt_script));
224 
225  int size = d->_document->dataStructures().size();
226  for (int i = 0; i < size; i++) {
227  d->_document->dataStructures().at(i)->setEngine(d->_engine);
228  connect(d->_document->dataStructures().at(i).get(), SIGNAL(scriptError(QString)), this, SIGNAL(scriptError(QString)));
229  }
230  d->createGraphList();
231  d->_engine->setProcessEventsInterval(100);
232 
233  QString error = d->_engine->evaluate(d->_currentScript).toString();
234  if (d->_engine && d->_engine->hasUncaughtException()) {
235  emit scriptError(i18n("Script Error: %1", error));
236  }
237  }
238 
239  if (!d->_engine || !d->_engine->isEvaluating()) {
240  scriptInfo(i18nc("@info status message after successful script execution", "<i>Execution Finished</i>"));
241  int size = d->_document->dataStructures().size();
242  for (int i = 0; i < size; i++) {
243  d->_document->dataStructures().at(i).get()->disconnect(this);
244  }
245  emit finished();
246  }
247 }
248 
249 bool QtScriptBackend::isRunning() const
250 {
251  if ((d->_engine) && (d->_engine->isEvaluating())) {
252  return true;
253  }
254  return d->_runningTool;
255 }
256 
257 void QtScriptBackend::setScript(const QString& s, Document *graphs)
258 {
259  d->_currentScript = s;
260  d->_document = graphs;
261 }
262 
263 void QtScriptBackend::debug(const QString& message)
264 {
265  emit scriptError(i18n("The global method \"%1\" is deprecated, please use \"%2\" instead.", QString("debug(message)"), QString("Console.debug(message)")));
266  emit sendDebug(message);
267 }
268 
269 void QtScriptBackend::output(const QString& message)
270 {
271  emit scriptError(i18n("The global method \"%1\" is deprecated, please use \"%2\" instead.", QString("output(message)"), QString("Console.log(message)")));
272  emit sendOutput(message);
273  emit sendDebug(message);
274 }
275 
276 void QtScriptBackend::continueExecutionStep()
277 {
278  if (d->_engine && d->_engineSteps && d->_engine->isEvaluating()) {
279  d->_engineSteps->action(QScriptEngineDebugger::ContinueAction)->trigger();
280  }
281 }
282 
283 void QtScriptBackend::include(const QString& filePath)
284 {
285  //TODO switch to URL usage
286  QString fileName = d->_includeManager.seekFile(filePath);
287 
288  if (d->_includeManager.checkIfWasIncluded(fileName)) {
289  return;
290  }
291 
292  QFile f(fileName);
293  if (f.open(QFile::ReadOnly)) {
294  QString script = d->_includeManager.include(f.readAll(), fileName.section('/', 0, -2), fileName.section('/', -1));
295  d->_engine->currentContext()->setActivationObject(d->_engine->currentContext()->parentContext()->activationObject());
296  QString error = d->_engine->evaluate(script, filePath).toString();
297  if (d->_engine && d->_engine->hasUncaughtException()) {
298  emit scriptError(i18n("Script error in included file %1", filePath));
299  emit scriptError(d->_engine->uncaughtExceptionBacktrace().join("\n"));
300  }
301  }
302 }
303 
304 void QtScriptBackend::interrupt()
305 {
306  if (!d->_engine->isEvaluating()) {
307  return;
308  }
309 
310  //FIXME workaround for now: two signals needed to trigger interrupt
311  if (d->_engineSteps)
312  d->_engineSteps->action(QScriptEngineDebugger::InterruptAction)->trigger();
313  if (d->_engineSteps)
314  d->_engineSteps->action(QScriptEngineDebugger::InterruptAction)->trigger();
315 }
Document::engineBackend
QtScriptBackend * engineBackend() const
Definition: Document.cpp:239
QtScriptBackend::executeStep
void executeStep()
Execute the preset script up to a call of.
Definition: QtScriptBackend.cpp:205
QtScriptBackend::scriptInfo
void scriptInfo(const QString &message)
QtScriptBackend::continueExecutionStep
void continueExecutionStep()
Continue execution of interrupted script.
Definition: QtScriptBackend.cpp:276
DocumentManager.h
DocumentManager::self
static DocumentManager & self()
Definition: DocumentManager.cpp:57
QtScriptBackend::sendOutput
void sendOutput(const QString &message)
DocumentManager::activeDocument
Document * activeDocument() const
Returns the currently active document, or 0 if there document list is empty.
Definition: DocumentManager.cpp:96
QtScriptBackend::stop
void stop()
Abort script evaluation.
Definition: QtScriptBackend.cpp:142
debug_script
static QScriptValue debug_script(QScriptContext *context, QScriptEngine *)
Definition: QtScriptBackend.cpp:69
QtScriptBackend::include
void include(const QString &filePath)
Include script from other script file.
Definition: QtScriptBackend.cpp:283
QtScriptBackend::registerGlobalObject
QScriptValue registerGlobalObject(QObject *qobject, const QString &name)
Register qobject as global object under name name at engine for next simulation run.
Definition: QtScriptBackend.cpp:125
QtScriptBackend::scriptError
void scriptError(const QString &message)
QtScriptBackend::output
void output(const QString &message)
Output the given string message as program output.
Definition: QtScriptBackend.cpp:269
QtScriptBackend::sendDebug
void sendDebug(const QString &message)
QtScriptBackend.h
QObject
IncludeManager
Definition: IncludeManager.h:27
Data.h
Document.h
QtScriptBackend::QtScriptBackend
QtScriptBackend(QObject *parent)
Default constructor.
Definition: QtScriptBackend.cpp:94
DataStructure.h
QtScriptBackend::engineCreated
void engineCreated(QScriptEngine *e)
QtScriptBackend::loadFile
void loadFile(const QString &file)
Definition: QtScriptBackend.cpp:109
QtScriptBackend::debug
void debug(const QString &message)
Output the given string message as debug output.
Definition: QtScriptBackend.cpp:263
interrupt_script
static QScriptValue interrupt_script(QScriptContext *context, QScriptEngine *)
Definition: QtScriptBackend.cpp:81
QtScriptBackend::isRunning
bool isRunning() const
Return true if engine is currently evaluating a script, otherwise false.
Definition: QtScriptBackend.cpp:249
QtScriptBackend::includeManager
IncludeManager & includeManager() const
Definition: QtScriptBackend.cpp:137
QtScriptBackend::execute
QString execute()
Execute the currently set script.
Definition: QtScriptBackend.cpp:164
QtScriptBackend::~QtScriptBackend
~QtScriptBackend()
Default destructor.
Definition: QtScriptBackend.cpp:100
Document
Definition: Document.h:41
output_script
static QScriptValue output_script(QScriptContext *context, QScriptEngine *)
Definition: QtScriptBackend.cpp:75
QtScriptBackend::interrupt
void interrupt()
Interrupt script execution.
Definition: QtScriptBackend.cpp:304
QtScriptBackend::setScript
void setScript(const QString &script, Document *document)
Set the script script and the corresponding document document to be executed on next run...
Definition: QtScriptBackend.cpp:257
include_script
static QScriptValue include_script(QScriptContext *context, QScriptEngine *)
Definition: QtScriptBackend.cpp:88
QtScriptBackend::engine
QScriptEngine * engine() const
Definition: QtScriptBackend.cpp:104
QtScriptBackend::finished
void finished()
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:42:26 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

rocs/RocsCore

Skip menu "rocs/RocsCore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal