isolate out the common QScriptEngine setup that is sharable between the various ScriptEngines; this will prevent having to reimplement (or more likely copy and paste) the extensions loading, print, debug, etc. from the applet implementation to get that support in dataengines and runners.
svn path=/trunk/KDE/kdebase/runtime/; revision=1070936
This commit is contained in:
parent
5946da0f42
commit
a85e29367a
@ -1,6 +1,8 @@
|
||||
# APPLET
|
||||
|
||||
set(simple_javascript_engine_SRCS
|
||||
appletauthorization.cpp
|
||||
scriptenv.cpp
|
||||
simplejavascriptapplet.cpp
|
||||
simplebindings/animationgroup.cpp
|
||||
simplebindings/appletinterface.cpp
|
||||
|
45
scriptengines/javascript/appletauthorization.cpp
Normal file
45
scriptengines/javascript/appletauthorization.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010 Aaron J. Seigo <aseigo@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2 as
|
||||
* published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "appletauthorization.h"
|
||||
#include "simplejavascriptapplet.h"
|
||||
|
||||
AppletAuthorization::AppletAuthorization(SimpleJavaScriptApplet *scriptEngine)
|
||||
: Authorization(),
|
||||
m_scriptEngine(scriptEngine)
|
||||
{
|
||||
}
|
||||
|
||||
bool AppletAuthorization::authorizeRequiredExtension(const QString &extension)
|
||||
{
|
||||
bool ok = m_scriptEngine->applet()->hasAuthorization(extension);
|
||||
|
||||
if (!ok) {
|
||||
m_scriptEngine->setFailedToLaunch(true,
|
||||
i18n("Authorization for required extension '%1' was denied.",
|
||||
extension));
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool AppletAuthorization::authorizeOptionalExtension(const QString &extension)
|
||||
{
|
||||
return m_scriptEngine->applet()->hasAuthorization(extension);
|
||||
}
|
||||
|
39
scriptengines/javascript/appletauthorization.h
Normal file
39
scriptengines/javascript/appletauthorization.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010 Aaron J. Seigo <aseigo@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2 as
|
||||
* published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef APPLETAUTHORIZATION_H
|
||||
#define APPLETAUTHORIZATION_H
|
||||
|
||||
#include "authorization.h"
|
||||
|
||||
class SimpleJavaScriptApplet;
|
||||
|
||||
class AppletAuthorization : public Authorization
|
||||
{
|
||||
public:
|
||||
AppletAuthorization(SimpleJavaScriptApplet *scriptEngine);
|
||||
|
||||
bool authorizeRequiredExtension(const QString &extension);
|
||||
bool authorizeOptionalExtension(const QString &extension);
|
||||
|
||||
private:
|
||||
SimpleJavaScriptApplet *m_scriptEngine;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
35
scriptengines/javascript/authorization.h
Normal file
35
scriptengines/javascript/authorization.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010 Aaron J. Seigo <aseigo@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2 as
|
||||
* published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef AUTHORIZATION_H
|
||||
#define AUTHORIZATION_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class Authorization
|
||||
{
|
||||
public:
|
||||
Authorization() {}
|
||||
virtual ~Authorization() {}
|
||||
|
||||
virtual bool authorizeRequiredExtension(const QString &) { return true; }
|
||||
virtual bool authorizeOptionalExtension(const QString &) { return true; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
292
scriptengines/javascript/scriptenv.cpp
Normal file
292
scriptengines/javascript/scriptenv.cpp
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright 2007-2008 Richard J. Moore <rich@kde.org>
|
||||
* Copyright 2009 Aaron J. Seigo <aseigo@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2 as
|
||||
* published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "scriptenv.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QFile>
|
||||
#include <QMetaEnum>
|
||||
|
||||
#include <KDebug>
|
||||
#include <KFileDialog>
|
||||
#include <KIO/Job>
|
||||
#include <KLocale>
|
||||
#include <KMimeType>
|
||||
#include <KService>
|
||||
#include <KShell>
|
||||
#include <KStandardDirs>
|
||||
#include <KRun>
|
||||
|
||||
#include "simplejavascriptapplet.h"
|
||||
#include "simplebindings/filedialogproxy.h"
|
||||
|
||||
ScriptEnv::ScriptEnv(QObject *parent)
|
||||
: QScriptEngine(parent),
|
||||
m_allowedUrls(NoUrls)
|
||||
{
|
||||
QScriptValue global = globalObject();
|
||||
global.setProperty("print", newFunction(ScriptEnv::print));
|
||||
global.setProperty("debug", newFunction(ScriptEnv::print));
|
||||
}
|
||||
|
||||
ScriptEnv::~ScriptEnv()
|
||||
{
|
||||
}
|
||||
|
||||
void ScriptEnv::registerEnums(QScriptValue &scriptValue, const QMetaObject &meta)
|
||||
{
|
||||
//manually create enum values. ugh
|
||||
for (int i = 0; i < meta.enumeratorCount(); ++i) {
|
||||
QMetaEnum e = meta.enumerator(i);
|
||||
//kDebug() << e.name();
|
||||
for (int i=0; i < e.keyCount(); ++i) {
|
||||
//kDebug() << e.key(i) << e.value(i);
|
||||
scriptValue.setProperty(e.key(i), QScriptValue(this, e.value(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptEnv::include(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
kWarning() << i18n("Unable to load script file: %1", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
QString script = file.readAll();
|
||||
//kDebug() << "Script says" << script;
|
||||
|
||||
evaluate(script);
|
||||
if (hasUncaughtException()) {
|
||||
emit reportError(this, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QScriptValue ScriptEnv::runApplication(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
if (context->argumentCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KUrl::List urls;
|
||||
if (context->argumentCount() > 1) {
|
||||
urls = qscriptvalue_cast<KUrl::List>(context->argument(1));
|
||||
}
|
||||
|
||||
const QString app = context->argument(0).toString();
|
||||
|
||||
KService::Ptr service = KService::serviceByStorageId(app);
|
||||
if (service) {
|
||||
return KRun::run(*service, urls, 0);
|
||||
}
|
||||
|
||||
const QString exec = KGlobal::dirs()->findExe(app);
|
||||
if (!exec.isEmpty()) {
|
||||
return KRun::run(exec, urls, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QScriptValue ScriptEnv::runCommand(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
if (context->argumentCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString exec = KGlobal::dirs()->findExe(context->argument(0).toString());
|
||||
if (!exec.isEmpty()) {
|
||||
QString args;
|
||||
if (context->argumentCount() > 1) {
|
||||
const QStringList argList = qscriptvalue_cast<QStringList>(context->argument(1));
|
||||
if (!argList.isEmpty()) {
|
||||
args = ' ' + KShell::joinArgs(argList);
|
||||
}
|
||||
}
|
||||
|
||||
return KRun::runCommand(exec + args, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QScriptValue ScriptEnv::openUrl(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
if (context->argumentCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QScriptValue v = context->argument(0);
|
||||
KUrl url = v.isString() ? KUrl(v.toString()) : qscriptvalue_cast<KUrl>(v);
|
||||
if (url.isValid()) {
|
||||
return KRun::runUrl(url, KMimeType::findByUrl(url)->name(), 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QScriptValue ScriptEnv::getUrl(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
if (context->argumentCount() == 0) {
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
QScriptValue v = context->argument(0);
|
||||
KUrl url = v.isString() ? KUrl(v.toString()) : qscriptvalue_cast<KUrl>(v);
|
||||
|
||||
if (!url.isValid()) {
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
if (url.isLocalFile()) {
|
||||
if (!(static_cast<ScriptEnv*>(engine)->m_allowedUrls & LocalUrls)) {
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
} else if (!(static_cast<ScriptEnv*>(engine)->m_allowedUrls & NetworkUrls) &&
|
||||
!((static_cast<ScriptEnv*>(engine)->m_allowedUrls & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) {
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
KIO::Job *job = KIO::get(url);
|
||||
return engine->newQObject(job);
|
||||
}
|
||||
|
||||
void ScriptEnv::registerGetUrl(QScriptValue &obj)
|
||||
{
|
||||
QScriptValue get = obj.property("getUrl");
|
||||
if (!get.isValid()) {
|
||||
obj.setProperty("getUrl", newFunction(ScriptEnv::getUrl));
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptEnv::importBuiltinExtension(const QString &extension, QScriptValue &obj)
|
||||
{
|
||||
kDebug() << extension;
|
||||
if ("filedialog" == extension) {
|
||||
FileDialogProxy::registerWithRuntime(this);
|
||||
return true;
|
||||
} else if ("launchapp" == extension) {
|
||||
obj.setProperty("runApplication", newFunction(ScriptEnv::runApplication));
|
||||
obj.setProperty("runCommand", newFunction(ScriptEnv::runCommand));
|
||||
obj.setProperty("openUrl", newFunction(ScriptEnv::openUrl));
|
||||
return true;
|
||||
} else if ("http" == extension) {
|
||||
m_allowedUrls |= HttpUrls;
|
||||
registerGetUrl(obj);
|
||||
return true;
|
||||
} else if ("networkio" == extension) {
|
||||
m_allowedUrls |= HttpUrls | NetworkUrls;
|
||||
registerGetUrl(obj);
|
||||
return true;
|
||||
} else if ("localio" == extension) {
|
||||
m_allowedUrls |= LocalUrls;
|
||||
registerGetUrl(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScriptEnv::importExtensions(const KPluginInfo &info, QScriptValue &obj, Authorization &auth)
|
||||
{
|
||||
QStringList requiredExtensions = info.service()->property("X-Plasma-RequiredExtensions", QVariant::StringList).toStringList();
|
||||
kDebug() << "required extensions are" << requiredExtensions;
|
||||
foreach (const QString &ext, requiredExtensions) {
|
||||
QString extension = ext.toLower();
|
||||
if (m_extensions.contains(extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!auth.authorizeRequiredExtension(extension)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!importBuiltinExtension(extension, obj)) {
|
||||
importExtension(extension);
|
||||
}
|
||||
|
||||
if (hasUncaughtException()) {
|
||||
emit reportError(this, true);
|
||||
return false;
|
||||
} else {
|
||||
m_extensions << extension;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList optionalExtensions = info.service()->property("X-Plasma-OptionalExtensions", QVariant::StringList).toStringList();
|
||||
kDebug() << "optional extensions are" << optionalExtensions;
|
||||
foreach (const QString &ext, optionalExtensions) {
|
||||
QString extension = ext.toLower();
|
||||
|
||||
if (m_extensions.contains(extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!auth.authorizeOptionalExtension(extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!importBuiltinExtension(extension, obj)) {
|
||||
importExtension(extension);
|
||||
}
|
||||
|
||||
if (hasUncaughtException()) {
|
||||
emit reportError(this, false);
|
||||
} else {
|
||||
m_extensions << extension;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QSet<QString> ScriptEnv::loadedExtensions() const
|
||||
{
|
||||
return m_extensions;
|
||||
}
|
||||
|
||||
QScriptValue ScriptEnv::debug(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
if (context->argumentCount() != 1) {
|
||||
return context->throwError(i18n("debug takes one argument"));
|
||||
}
|
||||
|
||||
kDebug() << context->argument(0).toString();
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
QScriptValue ScriptEnv::print(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
if (context->argumentCount() != 1) {
|
||||
return context->throwError(i18n("print() takes one argument"));
|
||||
}
|
||||
|
||||
std::cout << context->argument(0).toString().toLocal8Bit().constData() << std::endl;
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
#include "scriptenv.moc"
|
70
scriptengines/javascript/scriptenv.h
Normal file
70
scriptengines/javascript/scriptenv.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2007-2008 Richard J. Moore <rich@kde.org>
|
||||
* Copyright 2009 Aaron J. Seigo <aseigo@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2 as
|
||||
* published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTENV_H
|
||||
#define SCRIPTENV_H
|
||||
|
||||
#include <QScriptEngine>
|
||||
#include <QSet>
|
||||
|
||||
#include <KPluginInfo>
|
||||
|
||||
#include "authorization.h"
|
||||
|
||||
class ScriptEnv : public QScriptEngine
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum AllowedUrl { NoUrls = 0,
|
||||
HttpUrls = 1,
|
||||
NetworkUrls = 2,
|
||||
LocalUrls = 4 };
|
||||
Q_DECLARE_FLAGS(AllowedUrls, AllowedUrl)
|
||||
|
||||
ScriptEnv(QObject *parent);
|
||||
~ScriptEnv();
|
||||
|
||||
void registerEnums(QScriptValue &scriptValue, const QMetaObject &meta);
|
||||
bool include(const QString &path);
|
||||
|
||||
bool importExtensions(const KPluginInfo &info, QScriptValue &obj, Authorization &authorizer);
|
||||
QSet<QString> loadedExtensions() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void reportError(ScriptEnv *engine, bool fatal);
|
||||
|
||||
private:
|
||||
void registerGetUrl(QScriptValue &obj);
|
||||
bool importBuiltinExtension(const QString &extension, QScriptValue &obj);
|
||||
|
||||
static QScriptValue debug(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue print(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue runApplication(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue runCommand(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue openUrl(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue getUrl(QScriptContext *context, QScriptEngine *engine);
|
||||
|
||||
QSet<QString> m_extensions;
|
||||
AllowedUrls m_allowedUrls;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(ScriptEnv::AllowedUrls)
|
||||
|
||||
#endif
|
||||
|
@ -38,8 +38,7 @@
|
||||
AppletInterface::AppletInterface(SimpleJavaScriptApplet *parent)
|
||||
: QObject(parent),
|
||||
m_appletScriptEngine(parent),
|
||||
m_actionSignals(0),
|
||||
m_allowedUrls(SimpleJavaScriptApplet::NoUrls)
|
||||
m_actionSignals(0)
|
||||
{
|
||||
connect(this, SIGNAL(releaseVisualFocus()), applet(), SIGNAL(releaseVisualFocus()));
|
||||
connect(this, SIGNAL(configNeedsSaving()), applet(), SIGNAL(configNeedsSaving()));
|
||||
@ -319,16 +318,6 @@ int AppletInterface::apiVersion() const
|
||||
return offers.first()->property("X-KDE-PluginInfo-Version", QVariant::Int).toInt();
|
||||
}
|
||||
|
||||
SimpleJavaScriptApplet::AllowedUrls AppletInterface::allowedUrls() const
|
||||
{
|
||||
return m_allowedUrls;
|
||||
}
|
||||
|
||||
void AppletInterface::setAllowedUrls(const SimpleJavaScriptApplet::AllowedUrls &allowedUrls)
|
||||
{
|
||||
m_allowedUrls = allowedUrls;
|
||||
}
|
||||
|
||||
bool AppletInterface::include(const QString &script)
|
||||
{
|
||||
const QString path = package()->filePath("scripts", script);
|
||||
|
@ -235,9 +235,6 @@ enum QtScrollBarPolicy {
|
||||
bool immutable() const;
|
||||
int apiVersion() const;
|
||||
|
||||
SimpleJavaScriptApplet::AllowedUrls allowedUrls() const;
|
||||
void setAllowedUrls(const SimpleJavaScriptApplet::AllowedUrls &allowedUrls);
|
||||
|
||||
inline Plasma::Applet *applet() const { return m_appletScriptEngine->applet(); }
|
||||
|
||||
Q_SIGNALS:
|
||||
@ -255,7 +252,6 @@ private:
|
||||
QSignalMapper *m_actionSignals;
|
||||
QString m_currentConfig;
|
||||
QMap<QString, Plasma::ConfigLoader*> m_configs;
|
||||
SimpleJavaScriptApplet::AllowedUrls m_allowedUrls;
|
||||
};
|
||||
|
||||
class PopupAppletInterface : public AppletInterface
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QScriptEngine>
|
||||
#include <QFile>
|
||||
#include <QUiLoader>
|
||||
#include <QGraphicsLayout>
|
||||
@ -48,12 +47,13 @@
|
||||
#include <Plasma/PopupApplet>
|
||||
#include <Plasma/VideoWidget>
|
||||
|
||||
#include "appletauthorization.h"
|
||||
#include "scriptenv.h"
|
||||
#include "simplebindings/animationgroup.h"
|
||||
#include "simplebindings/dataengine.h"
|
||||
#include "simplebindings/i18n.h"
|
||||
#include "simplebindings/appletinterface.h"
|
||||
#include "simplebindings/bytearrayclass.h"
|
||||
#include "simplebindings/filedialogproxy.h"
|
||||
#include "simplebindings/variant.h"
|
||||
|
||||
using namespace Plasma;
|
||||
@ -89,19 +89,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void registerEnums(QScriptEngine *engine, QScriptValue &scriptValue, const QMetaObject &meta)
|
||||
{
|
||||
//manually create enum values. ugh
|
||||
for (int i = 0; i < meta.enumeratorCount(); ++i) {
|
||||
QMetaEnum e = meta.enumerator(i);
|
||||
//kDebug() << e.name();
|
||||
for (int i=0; i < e.keyCount(); ++i) {
|
||||
//kDebug() << e.key(i) << e.value(i);
|
||||
scriptValue.setProperty(e.key(i), QScriptValue(engine, e.value(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KSharedPtr<UiLoader> SimpleJavaScriptApplet::s_widgetLoader;
|
||||
QHash<QString, Plasma::Animator::Animation> SimpleJavaScriptApplet::s_animationDefs;
|
||||
|
||||
@ -111,7 +98,8 @@ SimpleJavaScriptApplet::SimpleJavaScriptApplet(QObject *parent, const QVariantLi
|
||||
Q_UNUSED(args)
|
||||
// kDebug() << "Script applet launched, args" << applet()->startupArguments();
|
||||
|
||||
m_engine = new QScriptEngine(this);
|
||||
m_engine = new ScriptEnv(this);
|
||||
connect(m_engine, SIGNAL(reportError(ScriptEnv*,bool)), this, SLOT(engineReportsError(ScriptEnv*,bool)));
|
||||
}
|
||||
|
||||
SimpleJavaScriptApplet::~SimpleJavaScriptApplet()
|
||||
@ -121,6 +109,11 @@ SimpleJavaScriptApplet::~SimpleJavaScriptApplet()
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleJavaScriptApplet::engineReportsError(ScriptEnv *engine, bool fatal)
|
||||
{
|
||||
reportError(engine, fatal);
|
||||
}
|
||||
|
||||
void SimpleJavaScriptApplet::reportError(QScriptEngine *engine, bool fatal)
|
||||
{
|
||||
SimpleJavaScriptApplet *jsApplet = qobject_cast<SimpleJavaScriptApplet *>(engine->parent());
|
||||
@ -271,22 +264,7 @@ void SimpleJavaScriptApplet::constraintsEvent(Plasma::Constraints constraints)
|
||||
|
||||
bool SimpleJavaScriptApplet::include(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
kWarning() << i18n("Unable to load script file: %1", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
QString script = file.readAll();
|
||||
//kDebug() << "Script says" << script;
|
||||
|
||||
m_engine->evaluate(script);
|
||||
if (m_engine->hasUncaughtException()) {
|
||||
reportError(m_engine, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return m_engine->include(path);
|
||||
}
|
||||
|
||||
void SimpleJavaScriptApplet::populateAnimationsHash()
|
||||
@ -307,201 +285,15 @@ bool SimpleJavaScriptApplet::init()
|
||||
{
|
||||
setupObjects();
|
||||
|
||||
if (!importExtensions()) {
|
||||
AppletAuthorization auth(this);
|
||||
if (!m_engine->importExtensions(description(), m_self, auth)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
kDebug() << "ScriptName:" << applet()->name();
|
||||
kDebug() << "ScriptCategory:" << applet()->category();
|
||||
|
||||
return include(mainScript());
|
||||
}
|
||||
|
||||
QScriptValue SimpleJavaScriptApplet::runApplication(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
if (context->argumentCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KUrl::List urls;
|
||||
if (context->argumentCount() > 1) {
|
||||
urls = qscriptvalue_cast<KUrl::List>(context->argument(1));
|
||||
}
|
||||
|
||||
const QString app = context->argument(0).toString();
|
||||
|
||||
KService::Ptr service = KService::serviceByStorageId(app);
|
||||
if (service) {
|
||||
return KRun::run(*service, urls, 0);
|
||||
}
|
||||
|
||||
const QString exec = KGlobal::dirs()->findExe(app);
|
||||
if (!exec.isEmpty()) {
|
||||
return KRun::run(exec, urls, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QScriptValue SimpleJavaScriptApplet::runCommand(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
if (context->argumentCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString exec = KGlobal::dirs()->findExe(context->argument(0).toString());
|
||||
if (!exec.isEmpty()) {
|
||||
QString args;
|
||||
if (context->argumentCount() > 1) {
|
||||
const QStringList argList = qscriptvalue_cast<QStringList>(context->argument(1));
|
||||
if (!argList.isEmpty()) {
|
||||
args = ' ' + KShell::joinArgs(argList);
|
||||
}
|
||||
}
|
||||
|
||||
return KRun::runCommand(exec + args, 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QScriptValue SimpleJavaScriptApplet::openUrl(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
if (context->argumentCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QScriptValue v = context->argument(0);
|
||||
KUrl url = v.isString() ? KUrl(v.toString()) : qscriptvalue_cast<KUrl>(v);
|
||||
if (url.isValid()) {
|
||||
return KRun::runUrl(url, KMimeType::findByUrl(url)->name(), 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QScriptValue SimpleJavaScriptApplet::getUrl(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
if (context->argumentCount() == 0) {
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
QScriptValue v = context->argument(0);
|
||||
KUrl url = v.isString() ? KUrl(v.toString()) : qscriptvalue_cast<KUrl>(v);
|
||||
|
||||
if (!url.isValid()) {
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
AppletInterface *interface = extractAppletInterface(engine);
|
||||
AllowedUrls allowed = interface ? interface->allowedUrls() : NoUrls;
|
||||
if (url.isLocalFile()) {
|
||||
if (!(allowed & LocalUrls)) {
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
} else if (!(allowed & NetworkUrls) &&
|
||||
!((allowed & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) {
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
KIO::Job *job = KIO::get(url);
|
||||
return engine->newQObject(job);
|
||||
}
|
||||
|
||||
void SimpleJavaScriptApplet::registerGetUrl()
|
||||
{
|
||||
QScriptValue get = m_self.property("getUrl");
|
||||
if (!get.isValid()) {
|
||||
m_self.setProperty("getUrl", m_engine->newFunction(SimpleJavaScriptApplet::getUrl));
|
||||
}
|
||||
}
|
||||
|
||||
bool SimpleJavaScriptApplet::importBuiltinExtesion(const QString &extension)
|
||||
{
|
||||
kDebug() << extension;
|
||||
if ("filedialog" == extension) {
|
||||
FileDialogProxy::registerWithRuntime(m_engine);
|
||||
return true;
|
||||
} else if ("launchapp" == extension) {
|
||||
m_self.setProperty("runApplication", m_engine->newFunction(SimpleJavaScriptApplet::runApplication));
|
||||
m_self.setProperty("runCommand", m_engine->newFunction(SimpleJavaScriptApplet::runCommand));
|
||||
m_self.setProperty("openUrl", m_engine->newFunction(SimpleJavaScriptApplet::openUrl));
|
||||
return true;
|
||||
} else if ("http" == extension) {
|
||||
m_interface->setAllowedUrls(m_interface->allowedUrls() | HttpUrls);
|
||||
registerGetUrl();
|
||||
return true;
|
||||
} else if ("networkio" == extension) {
|
||||
m_interface->setAllowedUrls(m_interface->allowedUrls() | HttpUrls | NetworkUrls);
|
||||
registerGetUrl();
|
||||
return true;
|
||||
} else if ("localio" == extension) {
|
||||
m_interface->setAllowedUrls(m_interface->allowedUrls() | LocalUrls);
|
||||
registerGetUrl();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SimpleJavaScriptApplet::importExtensions()
|
||||
{
|
||||
KPluginInfo info = description();
|
||||
QStringList requiredExtensions = info.service()->property("X-Plasma-RequiredExtensions", QVariant::StringList).toStringList();
|
||||
kDebug() << "required extensions are" << requiredExtensions;
|
||||
foreach (const QString &ext, requiredExtensions) {
|
||||
QString extension = ext.toLower();
|
||||
if (m_extensions.contains(extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!applet()->hasAuthorization(extension)) {
|
||||
setFailedToLaunch(true,
|
||||
i18n("Authorization for required extension '%1' was denied.",
|
||||
extension));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!importBuiltinExtesion(extension)) {
|
||||
m_engine->importExtension(extension);
|
||||
}
|
||||
|
||||
if (m_engine->hasUncaughtException()) {
|
||||
reportError(m_engine, true);
|
||||
return false;
|
||||
} else {
|
||||
m_extensions << extension;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList optionalExtensions = info.service()->property("X-Plasma-OptionalExtensions", QVariant::StringList).toStringList();
|
||||
kDebug() << "optional extensions are" << optionalExtensions;
|
||||
foreach (const QString &ext, optionalExtensions) {
|
||||
QString extension = ext.toLower();
|
||||
|
||||
if (m_extensions.contains(extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!applet()->hasAuthorization(extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!importBuiltinExtesion(extension)) {
|
||||
m_engine->importExtension(extension);
|
||||
}
|
||||
|
||||
if (m_engine->hasUncaughtException()) {
|
||||
reportError(m_engine);
|
||||
} else {
|
||||
m_extensions << extension;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return m_engine->include(mainScript());
|
||||
}
|
||||
|
||||
void SimpleJavaScriptApplet::setupObjects()
|
||||
@ -539,16 +331,13 @@ void SimpleJavaScriptApplet::setupObjects()
|
||||
}
|
||||
global.setProperty("startupArguments", args);
|
||||
|
||||
registerEnums(m_engine, global, AppletInterface::staticMetaObject);
|
||||
m_engine->registerEnums(global, AppletInterface::staticMetaObject);
|
||||
|
||||
|
||||
// Add a global loadui method for ui files
|
||||
QScriptValue fun = m_engine->newFunction(SimpleJavaScriptApplet::loadui);
|
||||
global.setProperty("loadui", fun);
|
||||
|
||||
fun = m_engine->newFunction(SimpleJavaScriptApplet::print);
|
||||
global.setProperty("print", fun);
|
||||
|
||||
// Work around bug in 4.3.0
|
||||
qMetaTypeId<QVariant>();
|
||||
|
||||
@ -585,7 +374,7 @@ void SimpleJavaScriptApplet::setupObjects()
|
||||
|
||||
QSet<QString> SimpleJavaScriptApplet::loadedExtensions() const
|
||||
{
|
||||
return m_extensions;
|
||||
return m_engine->loadedExtensions();
|
||||
}
|
||||
|
||||
AppletInterface *SimpleJavaScriptApplet::extractAppletInterface(QScriptEngine *engine)
|
||||
@ -827,29 +616,10 @@ QScriptValue SimpleJavaScriptApplet::createWidget(QScriptContext *context, QScri
|
||||
fun.setProperty("adjustSize", engine->newFunction(widgetAdjustSize));
|
||||
|
||||
//register enums will be accessed for instance as frame.Sunken for Frame shadow...
|
||||
registerEnums(engine, fun, *w->metaObject());
|
||||
static_cast<ScriptEnv*>(engine)->registerEnums(fun, *w->metaObject());
|
||||
return fun;
|
||||
}
|
||||
|
||||
QScriptValue SimpleJavaScriptApplet::notSupported(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
QString message = context->callee().property("message").toString();
|
||||
return context->throwError(i18n("This operation was not supported, %1", message) );
|
||||
}
|
||||
|
||||
|
||||
QScriptValue SimpleJavaScriptApplet::print(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
if (context->argumentCount() != 1) {
|
||||
return context->throwError(i18n("print() takes one argument"));
|
||||
}
|
||||
|
||||
//TODO: a GUI console? :)
|
||||
std::cout << context->argument(0).toString().toLocal8Bit().constData() << std::endl;
|
||||
return engine->undefinedValue();
|
||||
}
|
||||
|
||||
void SimpleJavaScriptApplet::collectGarbage()
|
||||
{
|
||||
m_engine->collectGarbage();
|
||||
|
@ -27,22 +27,16 @@
|
||||
|
||||
#include "simplebindings/uiloader.h"
|
||||
|
||||
class QScriptEngine;
|
||||
class QScriptContext;
|
||||
|
||||
class AppletInterface;
|
||||
class ScriptEnv;
|
||||
|
||||
class SimpleJavaScriptApplet : public Plasma::AppletScript
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum AllowedUrl { NoUrls = 0,
|
||||
HttpUrls = 1,
|
||||
NetworkUrls = 2,
|
||||
LocalUrls = 4 };
|
||||
Q_DECLARE_FLAGS(AllowedUrls, AllowedUrl)
|
||||
|
||||
SimpleJavaScriptApplet(QObject *parent, const QVariantList &args);
|
||||
~SimpleJavaScriptApplet();
|
||||
bool init();
|
||||
@ -58,16 +52,18 @@ public:
|
||||
|
||||
static QString findImageFile(QScriptEngine *engine, const QString &file);
|
||||
|
||||
public slots:
|
||||
public Q_SLOTS:
|
||||
void dataUpdated( const QString &name, const Plasma::DataEngine::Data &data );
|
||||
void configChanged();
|
||||
void executeAction(const QString &name);
|
||||
void collectGarbage();
|
||||
|
||||
private Q_SLOTS:
|
||||
void engineReportsError(ScriptEnv *engine, bool fatal);
|
||||
|
||||
private:
|
||||
void registerGetUrl();
|
||||
bool importExtensions();
|
||||
bool importBuiltinExtesion(const QString &extension);
|
||||
bool importBuiltinExtension(const QString &extension);
|
||||
void setupObjects();
|
||||
void callFunction(const QString &functionName, const QScriptValueList &args = QScriptValueList());
|
||||
static void populateAnimationsHash();
|
||||
@ -88,18 +84,8 @@ private:
|
||||
|
||||
void installWidgets(QScriptEngine *engine);
|
||||
static QScriptValue createWidget(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue notSupported(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue print(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue widgetAdjustSize(QScriptContext *context, QScriptEngine *engine);
|
||||
|
||||
// run extension
|
||||
static QScriptValue runApplication(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue runCommand(QScriptContext *context, QScriptEngine *engine);
|
||||
static QScriptValue openUrl(QScriptContext *context, QScriptEngine *engine);
|
||||
|
||||
// file io extensions
|
||||
static QScriptValue getUrl(QScriptContext *context, QScriptEngine *engine);
|
||||
|
||||
static AppletInterface *extractAppletInterface(QScriptEngine *engine);
|
||||
static QGraphicsWidget *extractParent(QScriptContext *context,
|
||||
QScriptEngine *engine,
|
||||
@ -109,15 +95,12 @@ private:
|
||||
private:
|
||||
static KSharedPtr<UiLoader> s_widgetLoader;
|
||||
static QHash<QString, Plasma::Animator::Animation> s_animationDefs;
|
||||
QScriptEngine *m_engine;
|
||||
ScriptEnv *m_engine;
|
||||
QScriptValue m_self;
|
||||
QVariantList m_args;
|
||||
QSet<QString> m_extensions;
|
||||
AppletInterface *m_interface;
|
||||
friend class AppletInterface;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SimpleJavaScriptApplet::AllowedUrls)
|
||||
|
||||
#endif // SCRIPT_H
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user