Merge branch 'master' into plasma/declarative

This commit is contained in:
Sebastian Kügler 2011-04-11 17:22:18 +02:00
commit 738b47566c
13 changed files with 131 additions and 182 deletions

View File

@ -20,6 +20,8 @@
#include "datamodel.h"
#include "datasource_p.h"
#include <QTimer>
#include <KDebug>
namespace Plasma
@ -140,6 +142,11 @@ DataModel::DataModel(QObject* parent)
this, SIGNAL(countChanged()));
connect(this, SIGNAL(modelReset()),
this, SIGNAL(countChanged()));
m_roleNamesTimer = new QTimer(this);
m_roleNamesTimer->setSingleShot(true);
connect(m_roleNamesTimer, SIGNAL(timeout()),
this, SLOT(syncRoleNames()));
}
DataModel::~DataModel()
@ -149,13 +156,19 @@ DataModel::~DataModel()
void DataModel::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data)
{
if (!m_keyRoleFilter.isEmpty()) {
QRegExp sourceRegExp(m_sourceFilter);
//a key that matches the one we want exists and is a list of DataEngine::Data
if (data.contains(m_keyRoleFilter) && data.value(m_keyRoleFilter).canConvert<QVariantList>()) {
if (data.contains(m_keyRoleFilter) &&
data.value(m_keyRoleFilter).canConvert<QVariantList>() &&
//matches the source filter regexp?
(m_sourceFilter.isEmpty() || (sourceRegExp.isValid() && sourceRegExp.exactMatch(sourceName)))) {
setItems(sourceName, data.value(m_keyRoleFilter).value<QVariantList>());
//try to match the key we want with a regular expression if set
} else {
QRegExp regExp(m_keyRoleFilter);
if (regExp.isValid()) {
if (regExp.isValid() &&
//matches the source filter regexp?
(m_sourceFilter.isEmpty() || (sourceRegExp.isValid() && sourceRegExp.exactMatch(sourceName)))) {
QHash<QString, QVariant>::const_iterator i;
QVariantList list;
for (i = data.constBegin(); i != data.constEnd(); ++i) {
@ -172,9 +185,14 @@ void DataModel::dataUpdated(const QString &sourceName, const Plasma::DataEngine:
if (!m_dataSource->data().isEmpty()) {
QVariantMap::const_iterator i = m_dataSource->data().constBegin();
QRegExp sourceRegExp(m_sourceFilter);
while (i != m_dataSource->data().constEnd()) {
QVariant value = i.value();
if (value.isValid() && value.canConvert<Plasma::DataEngine::Data>()) {
if (value.isValid() &&
value.canConvert<Plasma::DataEngine::Data>() &&
//matches the source filter regexp?
(m_sourceFilter.isEmpty() || (sourceRegExp.isValid() && sourceRegExp.exactMatch(i.key())))) {
Plasma::DataEngine::Data data = value.value<Plasma::DataEngine::Data>();
data["DataEngineSource"] = i.key();
list.append(data);
@ -219,6 +237,20 @@ void DataModel::setKeyRoleFilter(const QString& key)
m_keyRoleFilter = key;
}
void DataModel::setSourceFilter(const QString& key)
{
if (m_sourceFilter == key) {
return;
}
m_sourceFilter = key;
}
QString DataModel::sourceFilter() const
{
return m_sourceFilter;
}
QString DataModel::keyRoleFilter() const
{
return m_keyRoleFilter;
@ -253,6 +285,13 @@ void DataModel::setItems(const QString &sourceName, const QVariantList &list)
setRoleNames(m_roleNames);
}
m_roleNamesTimer->start(0);
}
void DataModel::syncRoleNames()
{
setRoleNames(m_roleNames);
//make the declarative view reload everything,
//would be nice an incremental update but is not possible
emit modelReset();

View File

@ -26,6 +26,7 @@
#include <Plasma/DataEngine>
class QTimer;
namespace Plasma
{
@ -87,6 +88,7 @@ class DataModel : public QAbstractItemModel
Q_OBJECT
Q_PROPERTY(QObject *dataSource READ dataSource WRITE setDataSource)
Q_PROPERTY(QString keyRoleFilter READ keyRoleFilter WRITE setKeyRoleFilter)
Q_PROPERTY(QString sourceFilter READ sourceFilter WRITE setSourceFilter)
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
@ -96,9 +98,19 @@ public:
void setDataSource(QObject *source);
QObject *dataSource() const;
/**
* Include only items with a key that matches this regexp in the model
*/
void setKeyRoleFilter(const QString& key);
QString keyRoleFilter() const;
/**
* Include only items with a source name that matches this regexp in the model
* @since 4.7
*/
void setSourceFilter(const QString& key);
QString sourceFilter() const;
int roleNameToId(const QString &name);
//Reimplemented
@ -125,10 +137,13 @@ Q_SIGNALS:
private Q_SLOTS:
void dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data);
void removeSource(const QString &sourceName);
void syncRoleNames();
private:
DataSource *m_dataSource;
QString m_keyRoleFilter;
QString m_sourceFilter;
QTimer *m_roleNamesTimer;
QMap<QString, QVector<QVariant> > m_items;
QHash<int, QByteArray> m_roleNames;
QHash<QString, int> m_roleIds;

View File

@ -127,17 +127,13 @@ set(declarative_appletscript_SRCS
plasmoid/appletauthorization.cpp
plasmoid/appletinterface.cpp
plasmoid/declarativeappletscript.cpp
plasmoid/engineaccess.cpp
plasmoid/themedsvg.cpp
simplebindings/bytearrayclass.cpp
simplebindings/bytearrayprototype.cpp
simplebindings/dataengine.cpp
simplebindings/dataenginereceiver.cpp
simplebindings/filedialogproxy.cpp
simplebindings/i18n.cpp
simplebindings/icon.cpp
simplebindings/qscriptbookkeeping.cpp
simplebindings/url.cpp
)
include_directories(${PHONON_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR}/common)

View File

@ -213,13 +213,25 @@ QScriptValue ScriptEnv::openUrl(QScriptContext *context, QScriptEngine *engine)
QScriptValue v = context->argument(0);
KUrl url = v.isString() ? KUrl(v.toString()) : qscriptvalue_cast<KUrl>(v);
if (url.isValid()) {
new KRun(url, 0);
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)
{
@ -261,6 +273,14 @@ void ScriptEnv::registerGetUrl(QScriptValue &obj)
}
}
void ScriptEnv::registerOpenUrl(QScriptValue &obj)
{
QScriptValue value = obj.property("openUrl");
if (!value.isValid()) {
obj.setProperty("openUrl", m_engine->newFunction(ScriptEnv::openUrl));
}
}
bool ScriptEnv::importBuiltinExtension(const QString &extension, QScriptValue &obj)
{
kDebug() << extension;
@ -270,13 +290,15 @@ bool ScriptEnv::importBuiltinExtension(const QString &extension, QScriptValue &o
return true;
#endif
} else if ("launchapp" == extension) {
m_allowedUrls |= AppLaunching;
obj.setProperty("runApplication", m_engine->newFunction(ScriptEnv::runApplication));
obj.setProperty("runCommand", m_engine->newFunction(ScriptEnv::runCommand));
obj.setProperty("openUrl", m_engine->newFunction(ScriptEnv::openUrl));
registerOpenUrl(obj);
return true;
} else if ("http" == extension) {
m_allowedUrls |= HttpUrls;
registerGetUrl(obj);
registerOpenUrl(obj);
return true;
} else if ("networkio" == extension) {
m_allowedUrls |= HttpUrls | NetworkUrls;

View File

@ -34,7 +34,8 @@ public:
enum AllowedUrl { NoUrls = 0,
HttpUrls = 1,
NetworkUrls = 2,
LocalUrls = 4 };
LocalUrls = 4,
AppLaunching = 8};
Q_DECLARE_FLAGS(AllowedUrls, AllowedUrl)
ScriptEnv(QObject *parent, QScriptEngine *engine);
@ -74,6 +75,7 @@ Q_SIGNALS:
private:
void registerGetUrl(QScriptValue &obj);
void registerOpenUrl(QScriptValue &obj);
bool importBuiltinExtension(const QString &extension, QScriptValue &obj);
static QScriptValue debug(QScriptContext *context, QScriptEngine *engine);

View File

@ -147,4 +147,4 @@ Icon=text-x-script
X-KDE-Library=plasma_appletscript_simple_javascript
X-Plasma-API=javascript
X-Plasma-ComponentTypes=Applet
X-KDE-PluginInfo-Version=2
X-KDE-PluginInfo-Version=4

View File

@ -453,6 +453,9 @@ ContainmentInterface::ContainmentInterface(AbstractJsAppletScript *parent)
connect(containment(), SIGNAL(appletAdded(Plasma::Applet *, const QPointF &)), this, SLOT(appletAddedForward(Plasma::Applet *, const QPointF &)));
connect(containment(), SIGNAL(screenChanged(int, int, Plasma::Containment)), this, SLOT(screenChanged()));
connect(containment()->context(), SIGNAL(activityChanged(Plasma::Context *)), this, SIGNAL(activityNameChanged()));
connect(containment()->context(), SIGNAL(changed(Plasma::Context *)), this, SIGNAL(activityIdChanged()));
}
QScriptValue ContainmentInterface::applets()
@ -556,6 +559,16 @@ bool ContainmentInterface::hasMovableApplets() const
return m_movableApplets;
}
QString ContainmentInterface::activityName() const
{
return containment()->context()->currentActivity();
}
QString ContainmentInterface::activityId() const
{
return containment()->context()->currentActivityId();
}
#ifndef USE_JS_SCRIPTENGINE
#include "appletinterface.moc"
#endif

View File

@ -367,6 +367,8 @@ class ContainmentInterface : public APPLETSUPERCLASS
Q_PROPERTY(Type containmentType READ containmentType WRITE setContainmentType)
Q_PROPERTY(int screen READ screen NOTIFY screenChanged)
Q_PROPERTY(bool movableApplets READ hasMovableApplets WRITE setMovableApplets)
Q_PROPERTY(QString activityName READ activityName NOTIFY activityNameChanged)
Q_PROPERTY(QString activityId READ activityId NOTIFY activityIdChanged)
Q_ENUMS(Type)
public:
@ -393,6 +395,9 @@ public:
void setMovableApplets(bool movable);
bool hasMovableApplets() const;
QString activityName() const;
QString activityId() const;
Q_INVOKABLE QScriptValue screenGeometry(int id) const;
Q_INVOKABLE QScriptValue availableScreenRegion(int id) const;
@ -400,6 +405,8 @@ Q_SIGNALS:
void appletAdded(QGraphicsWidget *applet, const QPointF &pos);
void appletRemoved(QGraphicsWidget *applet);
void screenChanged();
void activityNameChanged();
void activityIdChanged();
protected Q_SLOTS:
void appletAddedForward(Plasma::Applet *applet, const QPointF &pos);

View File

@ -46,15 +46,17 @@
#include "plasmoid/declarativeappletscript.h"
#include "engineaccess.h"
#include "plasmoid/appletinterface.h"
#include "plasmoid/themedsvg.h"
#include "common/scriptenv.h"
#include "declarative/packageaccessmanagerfactory.h"
#include "simplebindings/bytearrayclass.h"
//not pretty but only way to avoid a double Q_DECLARE_METATYPE(QVariant) in dataengine.h
#define DECLARATIVE_BINDING
#include "simplebindings/dataengine.h"
#include "simplebindings/dataenginereceiver.h"
#include "simplebindings/i18n.h"
K_EXPORT_PLASMA_APPLETSCRIPTENGINE(declarativeappletscript, DeclarativeAppletScript)
@ -62,8 +64,6 @@ K_EXPORT_PLASMA_APPLETSCRIPTENGINE(declarativeappletscript, DeclarativeAppletScr
QScriptValue constructIconClass(QScriptEngine *engine);
QScriptValue constructKUrlClass(QScriptEngine *engine);
void registerSimpleAppletMetaTypes(QScriptEngine *engine);
void registerNonGuiMetaTypes(QScriptEngine *engine);
DeclarativeAppletScript::DeclarativeAppletScript(QObject *parent, const QVariantList &args)
: AbstractJsAppletScript(parent, args),
m_engine(0),
@ -123,18 +123,12 @@ bool DeclarativeAppletScript::init()
m_interface = new AppletInterface(this);
}
m_engineAccess = new EngineAccess(this);
m_declarativeWidget->engine()->rootContext()->setContextProperty("__engineAccess", m_engineAccess);
connect(applet(), SIGNAL(extenderItemRestored(Plasma::ExtenderItem*)),
this, SLOT(extenderItemRestored(Plasma::ExtenderItem*)));
connect(applet(), SIGNAL(activate()),
this, SLOT(activate()));
//Glorious hack:steal the engine
QDeclarativeExpression *expr = new QDeclarativeExpression(m_declarativeWidget->engine()->rootContext(), m_declarativeWidget->rootObject(), "__engineAccess.setEngine(this)");
expr->evaluate();
delete expr;
setupObjects();
return true;
}
@ -352,10 +346,14 @@ ScriptEnv *DeclarativeAppletScript::scriptEnv()
void DeclarativeAppletScript::setupObjects()
{
QScriptValue global = m_engine->globalObject();
m_engine = m_declarativeWidget->scriptEngine();
connect(m_engine, SIGNAL(signalHandlerException(const QScriptValue &)),
this, SLOT(signalHandlerException(const QScriptValue &)));
m_declarativeWidget->engine()->rootContext()->setContextProperty("__engineAccess", 0);
m_engineAccess->deleteLater();
delete m_env;
m_env = new ScriptEnv(this, m_engine);
QScriptValue global = m_engine->globalObject();
m_self = m_engine->newQObject(m_interface);
m_self.setScope(global);
@ -376,24 +374,27 @@ void DeclarativeAppletScript::setupObjects()
ScriptEnv::registerEnums(global, AppletInterface::staticMetaObject);
bindI18N(m_engine);
global.setProperty("dataEngine", m_engine->newFunction(DeclarativeAppletScript::dataEngine));
global.setProperty("service", m_engine->newFunction(DeclarativeAppletScript::service));
global.setProperty("loadService", m_engine->newFunction(DeclarativeAppletScript::loadService));
//Add stuff from Qt
//TODO: move to libkdeclarative?
ByteArrayClass *baClass = new ByteArrayClass(m_engine);
global.setProperty("ByteArray", baClass->constructor());
global.setProperty("QIcon", constructIconClass(m_engine));
// Add stuff from KDE libs
qScriptRegisterSequenceMetaType<KUrl::List>(m_engine);
global.setProperty("Url", constructKUrlClass(m_engine));
// Add stuff from Plasma
global.setProperty("Svg", m_engine->newFunction(DeclarativeAppletScript::newPlasmaSvg));
global.setProperty("FrameSvg", m_engine->newFunction(DeclarativeAppletScript::newPlasmaFrameSvg));
global.setProperty("ExtenderItem", m_engine->newFunction(DeclarativeAppletScript::newPlasmaExtenderItem));
if (!m_env->importExtensions(description(), m_self, m_auth)) {
return;
}
registerSimpleAppletMetaTypes(m_engine);
registerDataEngineMetaTypes(m_engine);
QTimer::singleShot(0, this, SLOT(configChanged()));
}
QScriptValue DeclarativeAppletScript::dataEngine(QScriptContext *context, QScriptEngine *engine)
@ -460,67 +461,6 @@ QScriptEngine *DeclarativeAppletScript::engine() const
return m_engine;
}
void DeclarativeAppletScript::setEngine(QScriptValue &val)
{
if (val.engine() == m_engine) {
return;
}
m_engine = val.engine();
connect(m_engine, SIGNAL(signalHandlerException(const QScriptValue &)),
this, SLOT(signalHandlerException(const QScriptValue &)));
QScriptValue originalGlobalObject = m_engine->globalObject();
QScriptValue newGlobalObject = m_engine->newObject();
QString eval = QLatin1String("eval");
QString version = QLatin1String("version");
{
QScriptValueIterator iter(originalGlobalObject);
QVector<QString> names;
QVector<QScriptValue> values;
QVector<QScriptValue::PropertyFlags> flags;
while (iter.hasNext()) {
iter.next();
QString name = iter.name();
if (name == version) {
continue;
}
if (name != eval) {
names.append(name);
values.append(iter.value());
flags.append(iter.flags() | QScriptValue::Undeletable);
}
newGlobalObject.setProperty(iter.scriptName(), iter.value());
// m_illegalNames.insert(name);
}
}
m_engine->setGlobalObject(newGlobalObject);
delete m_env;
m_env = new ScriptEnv(this, m_engine);
//m_env->addMainObjectProperties(newGlobalObject);
setupObjects();
if (!m_env->importExtensions(description(), m_self, m_auth)) {
return;
}
qScriptRegisterSequenceMetaType<KUrl::List>(m_engine);
registerNonGuiMetaTypes(m_engine);
registerSimpleAppletMetaTypes(m_engine);
QTimer::singleShot(0, this, SLOT(configChanged()));
}
void DeclarativeAppletScript::signalHandlerException(const QScriptValue &exception)
{
kWarning()<<"Exception caught: "<<exception.toVariant();

View File

@ -47,8 +47,6 @@ public:
DeclarativeAppletScript(QObject *parent, const QVariantList &args);
~DeclarativeAppletScript();
void setEngine(QScriptValue &val);
QString filePath(const QString &type, const QString &file) const;
void executeAction(const QString &name);

View File

@ -1,40 +0,0 @@
/*
* 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 "engineaccess.h"
#include "scriptenv.h"
#include "plasmoid/declarativeappletscript.h"
EngineAccess::EngineAccess(DeclarativeAppletScript *parent)
: QObject(parent),
m_appletScriptEngine(parent)
{
}
EngineAccess::~EngineAccess()
{
}
void EngineAccess::setEngine(QScriptValue val)
{
m_appletScriptEngine->setEngine(val);
}
#include "engineaccess.moc"

View File

@ -1,45 +0,0 @@
/*
* 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.
*/
#ifndef ENGINEACCESS_H
#define ENGINEACCESS_H
#include <QObject>
#include <QScriptValue>
class DeclarativeAppletScript;
class EngineAccess : public QObject
{
Q_OBJECT
public:
EngineAccess(DeclarativeAppletScript *parent);
~EngineAccess();
Q_INVOKABLE void setEngine(QScriptValue val);
private:
DeclarativeAppletScript *m_appletScriptEngine;
};
#endif

View File

@ -32,7 +32,9 @@ using namespace Plasma;
Q_DECLARE_METATYPE(Service*)
Q_DECLARE_METATYPE(ServiceJob*)
#ifndef DECLARATIVE_BINDING
Q_DECLARE_METATYPE(QVariant)
#endif
Q_DECLARE_METATYPE(DataEngine::Dict)
Q_DECLARE_METATYPE(DataEngine::Data)