tidy up the sources and put the app finding code from desktopscripting here

* better name for jsscriptenv (it's about adding gui, as declarative is about add qml)
* break extension code out to their own sources for clarity
This commit is contained in:
Aaron Seigo 2011-05-27 11:33:41 +02:00
parent 3aeded5802
commit 6924341329
6 changed files with 393 additions and 113 deletions

View File

@ -8,8 +8,10 @@ if(KDE_PLATFORM_FEATURE_BINARY_COMPATIBLE_FEATURE_REDUCTION)
endif(KDE_PLATFORM_FEATURE_BINARY_COMPATIBLE_FEATURE_REDUCTION)
set(simple_javascript_engine_SRCS
common/extension_launchapp.cpp
common/extension_io.cpp
common/guiscriptenv.cpp
common/javascriptaddonpackagestructure.cpp
common/jsscriptenv.cpp
plasmoid/abstractjsappletscript.cpp
plasmoid/appletauthorization.cpp
plasmoid/jsappletinterface.cpp
@ -62,6 +64,8 @@ install(FILES data/plasma-scriptengine-applet-simple-javascript.desktop DESTINAT
# RUNNER
set(javascript_runner_engine_SRCS
common/extension_launchapp.cpp
common/extension_io.cpp
common/javascriptaddonpackagestructure.cpp
common/scriptenv.cpp
runner/javascriptrunner.cpp
@ -83,6 +87,8 @@ install(FILES data/plasma-scriptengine-runner-javascript.desktop DESTINATION ${S
# DATAENGINE
set(javascript_dataengine_engine_SRCS
common/extension_launchapp.cpp
common/extension_io.cpp
common/javascriptaddonpackagestructure.cpp
common/scriptenv.cpp
dataengine/javascriptdataengine.cpp
@ -119,6 +125,8 @@ install(FILES data/plasma-javascriptaddon.desktop DESTINATION ${SERVICETYPES_INS
#DECLARATIVE APPLET
set(declarative_appletscript_SRCS
common/extension_launchapp.cpp
common/extension_io.cpp
common/javascriptaddonpackagestructure.cpp
common/declarativescriptenv.cpp
declarative/packageaccessmanager.cpp

View File

@ -0,0 +1,126 @@
/*
* Copyright 2011 Aaron 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 as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* 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 <QDir>
#include <KGlobalSettings>
#include <KIO/Job>
#include <KRun>
#include <KStandardDirs>
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 false;
}
ScriptEnv *env = ScriptEnv::findScriptEnv(engine);
if (!env) {
return false;
}
if (!(env->m_allowedUrls & AppLaunching) &&
!((env->m_allowedUrls & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) {
return false;
}
new KRun(url, 0);
return true;
}
// TODO these should throw an exception
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();
}
ScriptEnv *env = ScriptEnv::findScriptEnv(engine);
if (!env) {
//kDebug() << "findScriptEnv failed";
return engine->undefinedValue();
}
if (url.isLocalFile()) {
if (!(env->m_allowedUrls & LocalUrls)) {
return engine->undefinedValue();
}
} else if (!(env->m_allowedUrls & NetworkUrls) &&
!((env->m_allowedUrls & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) {
return engine->undefinedValue();
}
KIO::Job *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
return engine->newQObject(job);
}
QScriptValue ScriptEnv::userDataPath(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return QDir::homePath();
}
const QString type = context->argument(0).toString();
if (type.isEmpty()) {
return QDir::homePath();
}
if (context->argumentCount() > 1) {
const QString filename = context->argument(1).toString();
return KStandardDirs::locateLocal(type.toLatin1(), filename);
}
if (type.compare("desktop", Qt::CaseInsensitive) == 0) {
return KGlobalSettings::desktopPath();
} else if (type.compare("autostart", Qt::CaseInsensitive) == 0) {
return KGlobalSettings::autostartPath();
} else if (type.compare("documents", Qt::CaseInsensitive) == 0) {
return KGlobalSettings::documentPath();
} else if (type.compare("music", Qt::CaseInsensitive) == 0) {
return KGlobalSettings::musicPath();
} else if (type.compare("video", Qt::CaseInsensitive) == 0) {
return KGlobalSettings::videosPath();
} else if (type.compare("downloads", Qt::CaseInsensitive) == 0) {
return KGlobalSettings::downloadPath();
} else if (type.compare("pictures", Qt::CaseInsensitive) == 0) {
return KGlobalSettings::picturesPath();
}
return QString();
}

View File

@ -0,0 +1,253 @@
/*
* Copyright 2011 Aaron 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 as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* 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 <KEMailSettings>
#include <KMimeTypeTrader>
#include <KStandardDirs>
#include <KRun>
#include <KServiceTypeTrader>
#include <KShell>
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();
const QString exec = KGlobal::dirs()->findExe(app);
if (!exec.isEmpty()) {
return KRun::run(exec, urls, 0);
}
KService::Ptr service = KService::serviceByStorageId(app);
if (service) {
return KRun::run(*service, 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::applicationExists(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return false;
}
const QString application = context->argument(0).toString();
if (application.isEmpty()) {
return false;
}
// first, check for it in $PATH
if (!KStandardDirs::findExe(application).isEmpty()) {
return true;
}
if (KService::serviceByStorageId(application)) {
return true;
}
if (application.contains("'")) {
// apostrophes just screw up the trader lookups below, so check for it
return false;
}
// next, consult ksycoca for an app by that name
if (!KServiceTypeTrader::self()->query("Application", QString("Name =~ '%1'").arg(application)).isEmpty()) {
return true;
}
// next, consult ksycoca for an app by that generic name
if (!KServiceTypeTrader::self()->query("Application", QString("GenericName =~ '%1'").arg(application)).isEmpty()) {
return true;
}
return false;
}
QScriptValue ScriptEnv::defaultApplication(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return false;
}
const QString application = context->argument(0).toString();
if (application.isEmpty()) {
return false;
}
const bool storageId = context->argumentCount() < 2 ? false : context->argument(1).toBool();
// FIXME: there are some pretty horrible hacks below, in the sense that they assume a very
// specific implementation system. there is much room for improvement here. see
// kdebase-runtime/kcontrol/componentchooser/ for all the gory details ;)
if (application.compare("mailer", Qt::CaseInsensitive) == 0) {
KEMailSettings settings;
// in KToolInvocation, the default is kmail; but let's be friendlier :)
QString command = settings.getSetting(KEMailSettings::ClientProgram);
if (command.isEmpty()) {
if (KService::Ptr kontact = KService::serviceByStorageId("kontact")) {
return storageId ? kontact->storageId() : kontact->exec();
} else if (KService::Ptr kmail = KService::serviceByStorageId("kmail")) {
return storageId ? kmail->storageId() : kmail->exec();
}
}
if (!command.isEmpty()) {
if (settings.getSetting(KEMailSettings::ClientTerminal) == "true") {
KConfigGroup confGroup(KGlobal::config(), "General");
const QString preferredTerminal = confGroup.readPathEntry("TerminalApplication",
QString::fromLatin1("konsole"));
command = preferredTerminal + QString::fromLatin1(" -e ") + command;
}
return command;
}
} else if (application.compare("browser", Qt::CaseInsensitive) == 0) {
KConfigGroup config(KGlobal::config(), "General");
QString browserApp = config.readPathEntry("BrowserApplication", QString());
if (browserApp.isEmpty()) {
const KService::Ptr htmlApp = KMimeTypeTrader::self()->preferredService(QLatin1String("text/html"));
if (htmlApp) {
browserApp = storageId ? htmlApp->storageId() : htmlApp->exec();
}
} else if (browserApp.startsWith('!')) {
browserApp = browserApp.mid(1);
}
return browserApp;
} else if (application.compare("terminal", Qt::CaseInsensitive) == 0) {
KConfigGroup confGroup(KGlobal::config(), "General");
return confGroup.readPathEntry("TerminalApplication", QString::fromLatin1("konsole"));
} else if (application.compare("filemanager", Qt::CaseInsensitive) == 0) {
KService::Ptr service = KMimeTypeTrader::self()->preferredService("inode/directory");
if (service) {
return storageId ? service->storageId() : service->exec();
}
} else if (application.compare("windowmanager", Qt::CaseInsensitive) == 0) {
KConfig cfg("ksmserverrc", KConfig::NoGlobals);
KConfigGroup confGroup(&cfg, "General");
return confGroup.readEntry("windowManager", QString::fromLatin1("konsole"));
} else if (KService::Ptr service = KMimeTypeTrader::self()->preferredService(application)) {
return storageId ? service->storageId() : service->exec();
} else {
// try the files in share/apps/kcm_componentchooser/
const QStringList services = KGlobal::dirs()->findAllResources("data","kcm_componentchooser/*.desktop", KStandardDirs::NoDuplicates);
//kDebug() << "ok, trying in" << services.count();
foreach (const QString &service, services) {
KConfig config(service, KConfig::SimpleConfig);
KConfigGroup cg = config.group(QByteArray());
const QString type = cg.readEntry("valueName", QString());
//kDebug() << " checking" << service << type << application;
if (type.compare(application, Qt::CaseInsensitive) == 0) {
KConfig store(cg.readPathEntry("storeInFile", "null"));
KConfigGroup storeCg(&store, cg.readEntry("valueSection", QString()));
const QString exec = storeCg.readPathEntry(cg.readEntry("valueName", "kcm_componenchooser_null"),
cg.readEntry("defaultImplementation", QString()));
if (!exec.isEmpty()) {
return exec;
}
break;
}
}
}
return false;
}
QScriptValue ScriptEnv::applicationPath(QScriptContext *context, QScriptEngine *engine)
{
Q_UNUSED(engine)
if (context->argumentCount() == 0) {
return false;
}
const QString application = context->argument(0).toString();
if (application.isEmpty()) {
return false;
}
// first, check for it in $PATH
const QString path = KStandardDirs::findExe(application);
if (!path.isEmpty()) {
return path;
}
if (KService::Ptr service = KService::serviceByStorageId(application)) {
return KStandardDirs::locate("apps", service->entryPath());
}
if (application.contains("'")) {
// apostrophes just screw up the trader lookups below, so check for it
return QString();
}
// next, consult ksycoca for an app by that name
KService::List offers = KServiceTypeTrader::self()->query("Application", QString("Name =~ '%1'").arg(application));
if (offers.isEmpty()) {
// next, consult ksycoca for an app by that generic name
offers = KServiceTypeTrader::self()->query("Application", QString("GenericName =~ '%1'").arg(application));
}
if (!offers.isEmpty()) {
KService::Ptr offer = offers.first();
return KStandardDirs::locate("apps", offer->entryPath());
}
return QString();
}

View File

@ -153,118 +153,6 @@ bool ScriptEnv::checkForErrors(bool fatal)
return false;
}
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();
const QString exec = KGlobal::dirs()->findExe(app);
if (!exec.isEmpty()) {
return KRun::run(exec, urls, 0);
}
KService::Ptr service = KService::serviceByStorageId(app);
if (service) {
return KRun::run(*service, 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 false;
}
ScriptEnv *env = ScriptEnv::findScriptEnv(engine);
if (!env) {
return false;
}
if (!(env->m_allowedUrls & AppLaunching) &&
!((env->m_allowedUrls & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) {
return false;
}
new KRun(url, 0);
return true;
}
// TODO these should throw an exception
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();
}
ScriptEnv *env = ScriptEnv::findScriptEnv(engine);
if (!env) {
//kDebug() << "findScriptEnv failed";
return engine->undefinedValue();
}
if (url.isLocalFile()) {
if (!(env->m_allowedUrls & LocalUrls)) {
return engine->undefinedValue();
}
} else if (!(env->m_allowedUrls & NetworkUrls) &&
!((env->m_allowedUrls & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) {
return engine->undefinedValue();
}
KIO::Job *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
return engine->newQObject(job);
}
void ScriptEnv::registerGetUrl(QScriptValue &obj)
{
QScriptValue get = obj.property("getUrl");
@ -307,6 +195,7 @@ bool ScriptEnv::importBuiltinExtension(const QString &extension, QScriptValue &o
} else if ("localio" == extension) {
m_allowedUrls |= LocalUrls;
registerGetUrl(obj);
obj.setProperty("", m_engine->newFunction(ScriptEnv::runCommand));
return true;
}

View File

@ -82,8 +82,12 @@ private:
static QScriptValue print(QScriptContext *context, QScriptEngine *engine);
static QScriptValue runApplication(QScriptContext *context, QScriptEngine *engine);
static QScriptValue runCommand(QScriptContext *context, QScriptEngine *engine);
static QScriptValue defaultApplication(QScriptContext *context, QScriptEngine *engine);
static QScriptValue applicationPath(QScriptContext *context, QScriptEngine *engine);
static QScriptValue applicationExists(QScriptContext *context, QScriptEngine *engine);
static QScriptValue openUrl(QScriptContext *context, QScriptEngine *engine);
static QScriptValue getUrl(QScriptContext *context, QScriptEngine *engine);
static QScriptValue userDataPath(QScriptContext *context, QScriptEngine *engine);
static QScriptValue listAddons(QScriptContext *context, QScriptEngine *engine);
static QScriptValue loadAddon(QScriptContext *context, QScriptEngine *engine);
static QScriptValue registerAddon(QScriptContext *context, QScriptEngine *engine);