From d479e58faf1c97297c4f84b765cec3f2bed4181d Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Wed, 12 Jan 2011 01:46:00 +0000 Subject: [PATCH] FEATURE: Boolean applicationExists(String name) and String defaultApplication(String kind) svn path=/trunk/KDE/kdebase/workspace/; revision=1213892 --- scriptengine.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++++++- scriptengine.h | 2 + 2 files changed, 142 insertions(+), 1 deletion(-) diff --git a/scriptengine.cpp b/scriptengine.cpp index 7b2058c09..fb1df9244 100644 --- a/scriptengine.cpp +++ b/scriptengine.cpp @@ -25,10 +25,14 @@ #include #include +#include #include #include #include +// KIO +#include // no camelcase include + #include #include #include @@ -52,7 +56,8 @@ ScriptEngine::ScriptEngine(Plasma::Corona *corona, QObject *parent) AppInterface *interface = new AppInterface(this); connect(interface, SIGNAL(print(QString)), this, SIGNAL(print(QString))); m_scriptSelf = newQObject(interface, QScriptEngine::QtOwnership, - QScriptEngine::ExcludeSuperClassProperties | QScriptEngine::ExcludeSuperClassMethods); + QScriptEngine::ExcludeSuperClassProperties | + QScriptEngine::ExcludeSuperClassMethods); setupEngine(); connect(this, SIGNAL(signalHandlerException(QScriptValue)), this, SLOT(exception(QScriptValue))); } @@ -294,6 +299,138 @@ QScriptValue ScriptEngine::loadTemplate(QScriptContext *context, QScriptEngine * return rv; } +QScriptValue ScriptEngine::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 ScriptEngine::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; +} + void ScriptEngine::setupEngine() { QScriptValue v = globalObject(); @@ -316,6 +453,8 @@ void ScriptEngine::setupEngine() m_scriptSelf.setProperty("panels", newFunction(ScriptEngine::panels)); m_scriptSelf.setProperty("fileExists", newFunction(ScriptEngine::fileExists)); m_scriptSelf.setProperty("loadTemplate", newFunction(ScriptEngine::loadTemplate)); + m_scriptSelf.setProperty("applicationExists", newFunction(ScriptEngine::applicationExists)); + m_scriptSelf.setProperty("defaultApplication", newFunction(ScriptEngine::defaultApplication)); setGlobalObject(m_scriptSelf); } diff --git a/scriptengine.h b/scriptengine.h index fb0d74468..52fbfb2c9 100644 --- a/scriptengine.h +++ b/scriptengine.h @@ -76,6 +76,8 @@ private: static QScriptValue panels(QScriptContext *context, QScriptEngine *engine); static QScriptValue fileExists(QScriptContext *context, QScriptEngine *engine); static QScriptValue loadTemplate(QScriptContext *context, QScriptEngine *engine); + static QScriptValue applicationExists(QScriptContext *context, QScriptEngine *engine); + static QScriptValue defaultApplication(QScriptContext *context, QScriptEngine *engine); // helpers static QScriptValue createContainment(const QString &type, const QString &defautPlugin,