plasma-framework/scriptengines/qml/plasmoid/appletinterface.cpp
Aaron Seigo 648fb8cf41 remove activityName
mapping activity IDs to other information (such as the user visible name)
should be done via other mechanisms (e.g. DataEngine or model via import)
2013-02-06 15:29:19 +01:00

502 lines
14 KiB
C++

/*
* Copyright 2008 Chani Armitage <chani@kde.org>
* Copyright 2008, 2009 Aaron Seigo <aseigo@kde.org>
* Copyright 2010 Marco Martin <mart@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 "appletinterface.h"
#include <QAction>
#include <QDir>
#include <QFile>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QScriptEngine>
#include <QSignalMapper>
#include <QTimer>
#include <KDebug>
#include <KGlobalSettings>
#include <KIcon>
#include <KService>
#include <KServiceTypeTrader>
#include <Plasma/Plasma>
#include <Plasma/Applet>
#include <Plasma/Corona>
#include <Plasma/Package>
Q_DECLARE_METATYPE(AppletInterface*)
AppletInterface::AppletInterface(AbstractJsAppletScript *parent)
: QObject(parent),
m_appletScriptEngine(parent),
m_actionSignals(0)
{
qmlRegisterType<AppletInterface>();
connect(this, SIGNAL(releaseVisualFocus()), applet(), SIGNAL(releaseVisualFocus()));
connect(this, SIGNAL(configNeedsSaving()), applet(), SIGNAL(configNeedsSaving()));
connect(applet(), SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)), this, SIGNAL(immutableChanged()));
connect(applet(), SIGNAL(newStatus(Plasma::ItemStatus)), this, SIGNAL(statusChanged()));
connect(m_appletScriptEngine, SIGNAL(formFactorChanged()),
this, SIGNAL(formFactorChanged()));
connect(m_appletScriptEngine, SIGNAL(locationChanged()),
this, SIGNAL(locationChanged()));
connect(m_appletScriptEngine, SIGNAL(contextChanged()),
this, SIGNAL(contextChanged()));
}
AppletInterface::~AppletInterface()
{
}
AppletInterface *AppletInterface::extract(QScriptEngine *engine)
{
QScriptValue appletValue = engine->globalObject().property("plasmoid");
return qobject_cast<AppletInterface*>(appletValue.toQObject());
}
Plasma::DataEngine* AppletInterface::dataEngine(const QString &name)
{
return applet()->dataEngine(name);
}
AppletInterface::FormFactor AppletInterface::formFactor() const
{
return static_cast<FormFactor>(applet()->formFactor());
}
AppletInterface::Location AppletInterface::location() const
{
return static_cast<Location>(applet()->location());
}
QString AppletInterface::currentActivity() const
{
return applet()->containment()->activity();
}
AppletInterface::AspectRatioMode AppletInterface::aspectRatioMode() const
{
return static_cast<AspectRatioMode>(applet()->aspectRatioMode());
}
void AppletInterface::setAspectRatioMode(AppletInterface::AspectRatioMode mode)
{
applet()->setAspectRatioMode(static_cast<Plasma::AspectRatioMode>(mode));
}
bool AppletInterface::shouldConserveResources() const
{
return applet()->shouldConserveResources();
}
void AppletInterface::setFailedToLaunch(bool failed, const QString &reason)
{
m_appletScriptEngine->setFailedToLaunch(failed, reason);
}
bool AppletInterface::isBusy() const
{
return applet()->isBusy();
}
void AppletInterface::setBusy(bool busy)
{
applet()->setBusy(busy);
}
AppletInterface::BackgroundHints AppletInterface::backgroundHints() const
{
return static_cast<BackgroundHints>(static_cast<int>(applet()->backgroundHints()));
}
void AppletInterface::setBackgroundHints(BackgroundHints hint)
{
applet()->setBackgroundHints(Plasma::BackgroundHints(hint));
}
void AppletInterface::setConfigurationRequired(bool needsConfiguring, const QString &reason)
{
m_appletScriptEngine->setConfigurationRequired(needsConfiguring, reason);
}
QString AppletInterface::activeConfig() const
{
return m_currentConfig.isEmpty() ? "main" : m_currentConfig;
}
void AppletInterface::setActiveConfig(const QString &name)
{
if (name == "main") {
m_currentConfig.clear();
return;
}
Plasma::ConfigLoader *loader = m_configs.value(name, 0);
if (!loader) {
QString path = m_appletScriptEngine->filePath("config", name + ".xml");
if (path.isEmpty()) {
return;
}
QFile f(path);
KConfigGroup cg = applet()->config();
loader = new Plasma::ConfigLoader(&cg, &f, this);
m_configs.insert(name, loader);
}
m_currentConfig = name;
}
void AppletInterface::writeConfig(const QString &entry, const QVariant &value)
{
Plasma::ConfigLoader *config = 0;
if (m_currentConfig.isEmpty()) {
config = applet()->configScheme();
} else {
config = m_configs.value(m_currentConfig, 0);
}
if (config) {
KConfigSkeletonItem *item = config->findItemByName(entry);
if (item) {
item->setProperty(value);
config->blockSignals(true);
config->writeConfig();
config->blockSignals(false);
m_appletScriptEngine->configNeedsSaving();
}
} else
kWarning() << "Couldn't find a configuration entry";
}
QVariant AppletInterface::readConfig(const QString &entry) const
{
Plasma::ConfigLoader *config = 0;
QVariant result;
if (m_currentConfig.isEmpty()) {
config = applet()->configScheme();
} else {
config = m_configs.value(m_currentConfig, 0);
}
if (config) {
result = config->property(entry);
}
return result;
}
QString AppletInterface::file(const QString &fileType)
{
return m_appletScriptEngine->filePath(fileType, QString());
}
QString AppletInterface::file(const QString &fileType, const QString &filePath)
{
return m_appletScriptEngine->filePath(fileType, filePath);
}
QList<QAction*> AppletInterface::contextualActions() const
{
QList<QAction*> actions;
Plasma::Applet *a = applet();
if (a->hasFailedToLaunch()) {
return actions;
}
foreach (const QString &name, m_actions) {
QAction *action = a->action(name);
if (action) {
actions << action;
}
}
return actions;
}
void AppletInterface::setActionSeparator(const QString &name)
{
Plasma::Applet *a = applet();
QAction *action = a->action(name);
if (action) {
action->setSeparator(true);
} else {
action = new QAction(this);
action->setSeparator(true);
a->addAction(name, action);
m_actions.append(name);
}
}
void AppletInterface::setAction(const QString &name, const QString &text, const QString &icon, const QString &shortcut)
{
Plasma::Applet *a = applet();
QAction *action = a->action(name);
if (action) {
action->setText(text);
} else {
action = new QAction(text, this);
a->addAction(name, action);
Q_ASSERT(!m_actions.contains(name));
m_actions.append(name);
if (!m_actionSignals) {
m_actionSignals = new QSignalMapper(this);
connect(m_actionSignals, SIGNAL(mapped(QString)),
m_appletScriptEngine, SLOT(executeAction(QString)));
}
connect(action, SIGNAL(triggered()), m_actionSignals, SLOT(map()));
m_actionSignals->setMapping(action, name);
}
if (!icon.isEmpty()) {
action->setIcon(KIcon(icon));
}
if (!shortcut.isEmpty()) {
action->setShortcut(shortcut);
}
action->setObjectName(name);
}
void AppletInterface::removeAction(const QString &name)
{
Plasma::Applet *a = applet();
QAction *action = a->action(name);
if (action) {
if (m_actionSignals) {
m_actionSignals->removeMappings(action);
}
delete action;
}
m_actions.removeAll(name);
}
QAction *AppletInterface::action(QString name) const
{
return applet()->action(name);
}
bool AppletInterface::immutable() const
{
return applet()->immutability() != Plasma::Mutable;
}
bool AppletInterface::userConfiguring() const
{
return applet()->isUserConfiguring();
}
int AppletInterface::apiVersion() const
{
const QString constraint("[X-Plasma-API] == 'javascript' and 'Applet' in [X-Plasma-ComponentTypes]");
KService::List offers = KServiceTypeTrader::self()->query("Plasma/ScriptEngine", constraint);
if (offers.isEmpty()) {
return -1;
}
return offers.first()->property("X-KDE-PluginInfo-Version", QVariant::Int).toInt();
}
bool AppletInterface::include(const QString &script)
{
const QString path = m_appletScriptEngine->filePath("scripts", script);
if (path.isEmpty()) {
return false;
}
return m_appletScriptEngine->include(path);
}
void AppletInterface::debug(const QString &msg)
{
kDebug() << msg;
}
void AppletInterface::setAssociatedApplication(const QString &string)
{
applet()->setAssociatedApplication(string);
}
QString AppletInterface::associatedApplication() const
{
return applet()->associatedApplication();
}
void AppletInterface::setStatus(const AppletInterface::ItemStatus &status)
{
applet()->setStatus((Plasma::ItemStatus)status);
}
AppletInterface::ItemStatus AppletInterface::status() const
{
return (AppletInterface::ItemStatus)((int)(applet()->status()));
}
/*
QString AppletInterface::downloadPath(const QString &file)
{
KDesktopFile config(v.toVariant().value<Plasma::Package>().path() + "/metadata.desktop");
KConfigGroup cg = config.desktopGroup();
const QString pluginName = cg.readEntry("X-KDE-PluginInfo-Name", QString());
destination = KGlobalSettings::downloadPath() + "/Plasma/" + pluginName + '/';
}
*/
QStringList AppletInterface::downloadedFiles() const
{
const QString downloadDir = KGlobalSettings::downloadPath() + "/Plasma/" + applet()->pluginName();
QDir dir(downloadDir);
return dir.entryList(QDir::Files | QDir::NoSymLinks | QDir::Readable);
}
void AppletInterface::gc()
{
QTimer::singleShot(0, m_appletScriptEngine, SLOT(collectGarbage()));
}
///////////// ContainmentInterface
ContainmentInterface::ContainmentInterface(AbstractJsAppletScript *parent)
: APPLETSUPERCLASS(parent),
m_movableApplets(true)
{
qmlRegisterType<ContainmentInterface>();
connect(containment(), SIGNAL(appletRemoved(Plasma::Applet *)), this, SLOT(appletRemovedForward(Plasma::Applet *)));
connect(containment(), SIGNAL(appletAdded(Plasma::Applet *, const QPointF &)), this, SLOT(appletAddedForward(Plasma::Applet *, const QPointF &)));
connect(containment(), SIGNAL(screenChanged(int, int, Plasma::Containment*)), this, SIGNAL(screenChanged()));
connect(containment(), SIGNAL(activityChanged()), this, SIGNAL(activityChanged()));
connect(containment(), SIGNAL(wallpaperChanged()), this, SLOT(loadWallpaper()));
if (containment()->corona()) {
connect(containment()->corona(), SIGNAL(availableScreenRegionChanged()),
this, SIGNAL(availableScreenRegionChanged()));
}
}
QVariantList ContainmentInterface::applets()
{
QVariantList list;
int i = 0;
foreach (Plasma::Applet *applet, containment()->applets()) {
list << QVariant::fromValue(applet);
++i;
}
return list;
}
void ContainmentInterface::setDrawWallpaper(bool drawWallpaper)
{
m_appletScriptEngine->setDrawWallpaper(drawWallpaper);
}
bool ContainmentInterface::drawWallpaper()
{
return m_appletScriptEngine->drawWallpaper();
}
ContainmentInterface::Type ContainmentInterface::containmentType() const
{
return (ContainmentInterface::Type)m_appletScriptEngine->containmentType();
}
void ContainmentInterface::setContainmentType(ContainmentInterface::Type type)
{
m_appletScriptEngine->setContainmentType((Plasma::Containment::Type)type);
}
int ContainmentInterface::screen() const
{
return containment()->screen();
}
QRectF ContainmentInterface::screenGeometry(int id) const
{
QRectF rect;
if (containment()->corona()) {
rect = QRectF(containment()->corona()->screenGeometry(id));
}
return rect;
}
QVariantList ContainmentInterface::availableScreenRegion(int id) const
{
QRegion reg;
if (containment()->corona()) {
reg = containment()->corona()->availableScreenRegion(id);
}
QVariantList regVal;
foreach (QRect rect, reg.rects()) {
regVal << QVariant::fromValue(QRectF(rect));
}
return regVal;
}
void ContainmentInterface::appletAddedForward(Plasma::Applet *applet, const QPointF &pos)
{
QObject *appletGraphicObject = applet->property("graphicObject").value<QObject *>();
QObject *contGraphicObject = containment()->property("graphicObject").value<QObject *>();
qDebug() << "Applet added:" << applet << applet->name() << appletGraphicObject;
if (applet && contGraphicObject && appletGraphicObject) {
appletGraphicObject->setProperty("visible", false);
appletGraphicObject->setProperty("parent", QVariant::fromValue(contGraphicObject));
}
emit appletAdded(appletGraphicObject, pos);
}
void ContainmentInterface::appletRemovedForward(Plasma::Applet *applet)
{
QObject *appletGraphicObject = applet->property("graphicObject").value<QObject *>();
emit appletRemoved(appletGraphicObject);
}
void ContainmentInterface::loadWallpaper()
{
}
QString ContainmentInterface::activityId() const
{
return containment()->activity();
}
#ifndef USE_JS_SCRIPTENGINE
#include "appletinterface.moc"
#endif