Kate
katescript.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "katescript.h"
00020 #include "katescriptdocument.h"
00021 #include "katescriptview.h"
00022 #include "kateview.h"
00023 #include "katedocument.h"
00024
00025 #include <iostream>
00026
00027 #include <QFile>
00028
00029 #include <QScriptEngine>
00030 #include <QScriptValue>
00031 #include <QScriptContext>
00032
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035
00039 Q_DECLARE_METATYPE(KTextEditor::Cursor)
00040
00041
00044 static QScriptValue cursorToScriptValue(QScriptEngine *engine, const KTextEditor::Cursor &cursor)
00045 {
00046 QScriptValue obj = engine->newObject();
00047 obj.setProperty("line", QScriptValue(engine, cursor.line()));
00048 obj.setProperty("column", QScriptValue(engine, cursor.column()));
00049 return obj;
00050 }
00051
00052 static void cursorFromScriptValue(const QScriptValue &obj, KTextEditor::Cursor &cursor)
00053 {
00054 cursor.setLine (obj.property("line").toInt32());
00055 cursor.setColumn (obj.property("column").toInt32());
00056 }
00057
00058 namespace Kate {
00059 namespace Script {
00060
00061 QScriptValue debug(QScriptContext *context, QScriptEngine *engine) {
00062 QStringList message;
00063 for(int i = 0; i < context->argumentCount(); ++i) {
00064 message << context->argument(i).toString();
00065 }
00066
00067 std::cerr << "\033[34m" << qPrintable(message.join(" ")) << "\033[0m\n";
00068 return engine->nullValue();
00069 }
00070
00071 }
00072 }
00073
00074 KateScript::KateScript(const QString &url, const KateScriptInformation &information) :
00075 m_loaded(false), m_loadSuccessful(false), m_url(url), m_information(information), m_engine(0)
00076 , m_document (0), m_view (0)
00077 {
00078 }
00079
00080 KateScript::~KateScript()
00081 {
00082 if(m_loadSuccessful) {
00083
00084 delete m_engine;
00085 delete m_document;
00086 delete m_view;
00087 }
00088 }
00089
00090 void KateScript::displayBacktrace(const QScriptValue &error, const QString &header)
00091 {
00092 if(!m_engine) {
00093 std::cerr << "KateScript::displayBacktrace: no engine, cannot display error\n";
00094 return;
00095 }
00096 std::cerr << "\033[31m";
00097 if(!header.isNull())
00098 std::cerr << qPrintable(header) << ":\n";
00099 if(error.isError())
00100 std::cerr << qPrintable(error.toString()) << '\n';
00101 std::cerr << qPrintable(m_engine->uncaughtExceptionBacktrace().join("\n"));
00102 std::cerr << "\033[0m" << '\n';
00103 }
00104
00105 void KateScript::clearExceptions()
00106 {
00107 m_engine->clearExceptions();
00108 }
00109
00110 QScriptValue KateScript::global(const QString &name)
00111 {
00112
00113 if(!load())
00114 return QScriptValue();
00115 return m_engine->globalObject().property(name);
00116 }
00117
00118 QScriptValue KateScript::function(const QString &name)
00119 {
00120 QScriptValue value = global(name);
00121 if(!value.isFunction())
00122 return QScriptValue();
00123 return value;
00124 }
00125
00126 bool KateScript::load()
00127 {
00128 if(m_loaded)
00129 return m_loadSuccessful;
00130
00131 m_loaded = true;
00132
00133 QString filename = QFile::encodeName(m_url);
00134 QFile file(filename);
00135 if (!file.open(QIODevice::ReadOnly)) {
00136 m_errorMessage = i18n("Unable to read file: '%1'", filename);
00137 kDebug( 13050 ) << m_errorMessage;
00138 m_loadSuccessful = false;
00139 return false;
00140 }
00141 QTextStream stream(&file);
00142 stream.setCodec("UTF-8");
00143 QString source = stream.readAll();
00144 file.close();
00145
00146
00147 m_engine = new QScriptEngine();
00148
00149
00150 qScriptRegisterMetaType (m_engine, cursorToScriptValue, cursorFromScriptValue);
00151
00152 QScriptValue result = m_engine->evaluate(source, m_url);
00153 if(m_engine->hasUncaughtException()) {
00154 displayBacktrace(result, QString("Error loading %1\n").arg(m_url));
00155 m_errorMessage = i18n("Error loading script %1", filename);
00156 m_loadSuccessful = false;
00157 return false;
00158 }
00159
00160 initEngine();
00161 m_loadSuccessful = true;
00162 return true;
00163 }
00164
00165 void KateScript::initEngine() {
00166
00167 m_engine->globalObject().setProperty("document", m_engine->newQObject(m_document = new KateScriptDocument()));
00168 m_engine->globalObject().setProperty("view", m_engine->newQObject(m_view = new KateScriptView()));
00169
00170 m_engine->globalObject().setProperty("debug", m_engine->newFunction(Kate::Script::debug));
00171 }
00172
00173 bool KateScript::setView(KateView *view)
00174 {
00175 if (!load())
00176 return false;
00177
00178 m_document->setDocument (view->doc());
00179 m_view->setView (view);
00180 return true;
00181 }
00182
00183