[tor-commits] [vidalia/alpha] Improve the engine

chiiph at torproject.org chiiph at torproject.org
Sat Jul 2 21:53:47 UTC 2011


commit 6bae6e29816be171462ae028a9adc1dcaab778d6
Author: Tomas Touceda <chiiph at torproject.org>
Date:   Mon Jun 13 01:56:37 2011 -0300

    Improve the engine
    
    - Add include and importExtension functions from qtscriptgenerator.
    - Improve the ADD_CLASS macro
    - Add a way to access the settings that belong to a tab from inside
      a plugin.
---
 src/vidalia/plugin/PluginEngine.cpp                |   86 +++++++++++++++++++-
 src/vidalia/plugin/PluginEngine.h                  |   15 ++--
 .../plugin/prototypes/VidaliaTabPrototype.cpp      |   52 +++++++++++-
 .../plugin/prototypes/VidaliaTabPrototype.h        |    6 ++
 4 files changed, 149 insertions(+), 10 deletions(-)

diff --git a/src/vidalia/plugin/PluginEngine.cpp b/src/vidalia/plugin/PluginEngine.cpp
index 883dc24..9604b8d 100644
--- a/src/vidalia/plugin/PluginEngine.cpp
+++ b/src/vidalia/plugin/PluginEngine.cpp
@@ -6,8 +6,14 @@
 PluginEngine::PluginEngine(QObject *parent)
   : QScriptEngine(parent)
 {
-  ADD_CLASS("VidaliaTab", VidaliaTabPrototype, VidaliaTab *, 
-      VidaliaTabPrototype::constructor)
+  ADD_CLASS(VidaliaTabPrototype)
+
+  globalObject().setProperty("include", newFunction(includeScript));
+  globalObject().setProperty("importExtension", newFunction(importExtension));
+
+  DebugDialog::outputDebug("Available extensions:");
+  foreach(QString ext, availableExtensions())
+    DebugDialog::outputDebug(QString("  %1").arg(ext));
 
   loadAllPlugins();
 }
@@ -74,3 +80,79 @@ PluginEngine::getAllActions()
 
   return actions;
 }
+
+QScriptValue 
+PluginEngine::importExtension(QScriptContext *context, QScriptEngine *engine)
+{
+    return engine->importExtension(context->argument(0).toString());
+}
+
+QScriptValue 
+PluginEngine::includeScript(QScriptContext *context, QScriptEngine *engine)
+{
+  QString currentFileName = engine->globalObject().property("qs").property("script").property("absoluteFilePath").toString();
+  QFileInfo currentFileInfo(currentFileName);
+  QString path = currentFileInfo.path();
+  QString importFile = context->argument(0).toString();
+  QFileInfo importInfo(importFile);
+  if (importInfo.isRelative()) {
+      importFile =  path + "/" + importInfo.filePath();
+  }
+  if (!loadFile(importFile, engine)) {
+      return context->throwError(QString("Failed to resolve include: %1").arg(importFile));
+  }
+  return engine->toScriptValue(true);
+}
+
+bool 
+PluginEngine::loadFile(QString fileName, QScriptEngine *engine)
+{
+    // avoid loading files more than once
+    static QSet<QString> loadedFiles;
+    QFileInfo fileInfo(fileName);
+    QString absoluteFileName = fileInfo.absoluteFilePath();
+    QString absolutePath = fileInfo.absolutePath();
+    QString canonicalFileName = fileInfo.canonicalFilePath();
+    if (loadedFiles.contains(canonicalFileName)) {
+        return true;
+    }
+    loadedFiles.insert(canonicalFileName);
+    QString path = fileInfo.path();
+
+    // load the file
+    QFile file(fileName);
+    if (file.open(QFile::ReadOnly)) {
+        QTextStream stream(&file);
+        QString contents = stream.readAll();
+        file.close();
+
+        int endlineIndex = contents.indexOf('\n');
+        QString line = contents.left(endlineIndex);
+        int lineNumber = 1;
+
+        // strip off #!/usr/bin/env qscript line
+        if (line.startsWith("#!")) {
+            contents.remove(0, endlineIndex+1);
+            ++lineNumber;
+        }
+
+        // set qt.script.absoluteFilePath
+        QScriptValue script = engine->globalObject().property("qs").property("script");
+        QScriptValue oldFilePathValue = script.property("absoluteFilePath");
+        QScriptValue oldPathValue = script.property("absolutePath");
+        script.setProperty("absoluteFilePath", engine->toScriptValue(absoluteFileName));
+        script.setProperty("absolutePath", engine->toScriptValue(absolutePath));
+
+        QScriptValue r = engine->evaluate(contents, fileName, lineNumber);
+        if (engine->hasUncaughtException()) {
+            QStringList backtrace = engine->uncaughtExceptionBacktrace();
+            qDebug() << QString("    %1\n%2\n\n").arg(r.toString()).arg(backtrace.join("\n"));
+            return true;
+        }
+        script.setProperty("absoluteFilePath", oldFilePathValue); // if we come from includeScript(), or whereever
+        script.setProperty("absolutePath", oldPathValue); // if we come from includeScript(), or whereever
+    } else {
+        return false;
+    }
+    return true;
+}
diff --git a/src/vidalia/plugin/PluginEngine.h b/src/vidalia/plugin/PluginEngine.h
index 7876803..6496ca6 100644
--- a/src/vidalia/plugin/PluginEngine.h
+++ b/src/vidalia/plugin/PluginEngine.h
@@ -8,12 +8,11 @@
 
 class PluginWrapper;
 
-#define ADD_CLASS(name, protoType, absType, ctor) \
-  protoType __proto; \
-  QScriptValue __script = newQObject(&__proto, QScriptEngine::ScriptOwnership); \
-  setDefaultPrototype(qMetaTypeId<absType>(), __script); \
-  QScriptValue __ctor = newFunction(ctor, __script); \
-  globalObject().setProperty(name, __ctor);
+#define ADD_CLASS(protoType) \
+  QScriptValue __script##protoType = newQObject(new protoType); \
+  setDefaultPrototype(protoType::metaTypeId(), __script##protoType); \
+  globalObject().setProperty(protoType::name(), newFunction(protoType::constructor, __script##protoType));
+
 
 class PluginEngine : public QScriptEngine {
   Q_OBJECT
@@ -28,6 +27,10 @@ class PluginEngine : public QScriptEngine {
     void pluginTab(VidaliaTab *);
 
   protected:
+    static QScriptValue importExtension(QScriptContext *context, QScriptEngine *engine);
+    static bool loadFile(QString fileName, QScriptEngine *engine);
+    static QScriptValue includeScript(QScriptContext *context, QScriptEngine *engine);
+
     void loadAllPlugins();
     void tryLoadPlugin(QDir path);
 
diff --git a/src/vidalia/plugin/prototypes/VidaliaTabPrototype.cpp b/src/vidalia/plugin/prototypes/VidaliaTabPrototype.cpp
index 58170ef..52b8fef 100644
--- a/src/vidalia/plugin/prototypes/VidaliaTabPrototype.cpp
+++ b/src/vidalia/plugin/prototypes/VidaliaTabPrototype.cpp
@@ -4,7 +4,55 @@ VidaliaTabPrototype::VidaliaTabPrototype(QObject *parent)
   : QObject(parent)
 {}
 
-QScriptValue VidaliaTabPrototype::constructor(QScriptContext *context, QScriptEngine *engine)
+QScriptValue
+VidaliaTabPrototype::constructor(QScriptContext *context, QScriptEngine *engine)
 {
-  return engine->newQObject(new VidaliaTab(QString("titulooo"), QString("nombreee")), QScriptEngine::ScriptOwnership);
+  if((context->argumentCount() > 2) or (context->argumentCount() < 1))
+    return QScriptValue(QScriptValue::NullValue);
+
+  QString title = "";
+  QString name = "";
+
+  title = qscriptvalue_cast<QString>(context->argument(0));
+  if(context->argumentCount() > 1)
+    name = qscriptvalue_cast<QString>(context->argument(1));
+
+  return engine->newQObject(new VidaliaTab(title, name), QScriptEngine::ScriptOwnership);
+}
+
+int 
+VidaliaTabPrototype::metaTypeId() {
+  return qMetaTypeId<VidaliaTab *>();
+}
+
+QString
+VidaliaTabPrototype::name() {
+  return QString("VidaliaTab");
+}
+
+void
+VidaliaTabPrototype::setLayout(QLayout *layout)
+{
+  VidaliaTab *obj = qscriptvalue_cast<VidaliaTab *>(thisObject());
+
+  if(obj)
+    obj->setLayout(layout);
+}
+
+QVariant 
+VidaliaTabPrototype::getSetting(QString name, QVariant defaultValue)
+{
+  VidaliaTab *obj = qscriptvalue_cast<VidaliaTab *>(thisObject());
+
+  if(obj)
+    return obj->getSetting(name, defaultValue);
+}
+
+void 
+VidaliaTabPrototype::saveSetting(QString name, QVariant value)
+{
+  VidaliaTab *obj = qscriptvalue_cast<VidaliaTab *>(thisObject());
+
+  if(obj)
+    obj->saveSetting(name, value);
 }
diff --git a/src/vidalia/plugin/prototypes/VidaliaTabPrototype.h b/src/vidalia/plugin/prototypes/VidaliaTabPrototype.h
index dbd89cd..59d640d 100644
--- a/src/vidalia/plugin/prototypes/VidaliaTabPrototype.h
+++ b/src/vidalia/plugin/prototypes/VidaliaTabPrototype.h
@@ -13,6 +13,12 @@ class VidaliaTabPrototype : public QObject, public QScriptable
   public:
     VidaliaTabPrototype(QObject *parent = 0);
     static QScriptValue constructor(QScriptContext *context, QScriptEngine *engine);
+    static int metaTypeId();
+    static QString name();
+
+    Q_INVOKABLE void setLayout(QLayout *layout);
+    Q_INVOKABLE QVariant getSetting(QString name, QVariant defaultValue);
+    Q_INVOKABLE void saveSetting(QString name, QVariant value);
 };
 
 Q_DECLARE_METATYPE(VidaliaTab *);





More information about the tor-commits mailing list