--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qtmobility/src/publishsubscribe/contextkitlayer.cpp Fri Apr 16 15:51:22 2010 +0300
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvaluespace.h"
+#include "qvaluespace_p.h"
+
+#include <QSet>
+#include <QDebug>
+#include <contextproperty.h>
+#include <contextregistryinfo.h>
+
+QTM_BEGIN_NAMESPACE
+
+using namespace QValueSpace;
+
+/* ContextKit layer
+
+ This layer makes ContextKit properties visible in the QValueSpace.
+
+ You can not publish values of ContextKit properties using the
+ QValueSpace. This might be fixed later.
+
+ ContextKit properties have names with dots in them, which allows
+ these properties to be arranged in a tree. The context commander
+ does this in its UI, for example.
+
+ However, the ContextKit itself does not pay attention to the dots
+ at all: properties just have names and there are no such things as
+ parent / child / sibling relations between properties. For
+ example, there is a property called "Battery.ChargeLevel", but the
+ ContextKit doesn't know anything about "Battery". Subscribing to
+ "Battery" is exactly the same as subscribing to any other
+ non-declared property. When "Battery.ChargeLevel" changes,
+ "Battery" does _not_ receive a change notification.
+
+ The QValueSpace, on the other hand, has a explicit tree-structure:
+ the key "/foo" represents all its children, like "/foo/bar". When
+ "/foo/bar" changes, "/foo" _does_ receive a change notification.
+
+ There are two ways to map ContextKit properties into the
+ QValueSpace: simply as a long list of siblings (a one-level tree),
+ or as the multi-level tree that is implied by their names.
+
+ We do the latter since that is more natural. For example, the
+ ContextKit property "Battery.ChargeLevel" is mapped to
+ "/Battery/ChargeLevel", and the key "/Battery" gets a change
+ notifications for all its children.
+*/
+
+/* ContextKitHandle - contains a ContextKit property and all its
+ direct and indirect children.
+
+ ContextKitHandles do not form a hierarchy between each other; think
+ of them as individual little trees that are created in direct
+ response to requests to the ContextKitLayer. The properties in
+ these trees can overlap; a single ContextKit property can be
+ accessed via many ContextKitHandles.
+ */
+
+class ContextKitHandle : public QObject {
+
+ Q_OBJECT
+
+public:
+ ContextKitHandle (ContextKitHandle *parent, const QString &root);
+ ~ContextKitHandle ();
+
+ bool value (const QString &path, QVariant *data);
+ void subscribe ();
+ void unsubscribe ();
+ QSet<QString> children ();
+
+signals:
+ void valueChanged();
+
+private:
+ QString prefix;
+ QHash<QString, ContextProperty *> props;
+
+ void insert (const QString &path, const QString &key);
+};
+
+void ContextKitHandle::insert (const QString &path, const QString &key)
+{
+ ContextProperty *prop = new ContextProperty (key);
+ connect (prop, SIGNAL (valueChanged()),
+ this, SIGNAL (valueChanged()));
+ props.insert (path, prop);
+}
+
+ContextKitHandle::ContextKitHandle (ContextKitHandle *parent, const QString &path)
+{
+ QString key = path;
+ if (key.startsWith("/"))
+ key = key.mid(1);
+ key = key.replace('/', '.');
+ if (parent)
+ key = parent->prefix + key;
+
+ prefix = (key == "")? "" : key + ".";
+ foreach (const QString &k, ContextRegistryInfo::instance()->listKeys())
+ {
+ if (k == key)
+ insert ("", k);
+ else if (k.startsWith (prefix))
+ insert (k.mid(prefix.length()).replace ('.', '/'), k);
+ }
+}
+
+ContextKitHandle::~ContextKitHandle ()
+{
+ foreach (ContextProperty *prop, props.values())
+ delete prop;
+}
+
+bool
+ContextKitHandle::value (const QString &path, QVariant *data)
+{
+ // path always starts with a "/".
+ ContextProperty *p = props.value (path.mid(1));
+ if (p)
+ {
+ *data = p->value();
+ return true;
+ }
+ else
+ return false;
+}
+
+void
+ContextKitHandle::subscribe ()
+{
+ foreach (ContextProperty *p, props.values())
+ p->subscribe ();
+}
+
+void
+ContextKitHandle::unsubscribe ()
+{
+ foreach (ContextProperty *p, props.values())
+ p->unsubscribe ();
+}
+
+QSet<QString>
+ContextKitHandle::children ()
+{
+ QSet<QString> kids;
+
+ foreach (const QString &path, props.keys())
+ {
+ int pos = path.indexOf("/");
+ if (pos >= 0)
+ kids.insert (path.left(pos));
+ else
+ kids.insert (path);
+ }
+ return kids;
+}
+
+/* ContextKitLayer - implements QAbstractValueSpaceLayer interface to
+ hook ContextKit into QValueSpace.
+
+ It mainly creates ContextKitHandles and dispatches to them.
+*/
+
+class ContextKitLayer : public QAbstractValueSpaceLayer
+{
+ Q_OBJECT
+
+public:
+ ContextKitLayer();
+ virtual ~ContextKitLayer();
+
+ /* ValueSpaceLayer interface - Common functions */
+ QString name();
+ bool startup(Type);
+ QUuid id();
+ unsigned int order();
+ LayerOptions layerOptions() const;
+
+ Handle item(Handle parent, const QString &);
+ void removeHandle(Handle);
+ void setProperty(Handle handle, Properties);
+
+ bool value(Handle, QVariant *);
+ bool value(Handle, const QString &, QVariant *);
+ QSet<QString> children(Handle);
+
+ /* ValueSpaceLayer interface - QValueSpaceSubscriber functions */
+ bool supportsInterestNotification() const { return true; }
+ bool notifyInterest(Handle handle, bool interested);
+
+ /* ValueSpaceLayer interface - QValueSpacePublisher functions */
+ bool setValue(QValueSpacePublisher *, Handle, const QString &, const QVariant &) { return false; }
+ bool removeValue(QValueSpacePublisher *, Handle, const QString &) { return false; }
+ bool removeSubTree(QValueSpacePublisher *, Handle) { return false; }
+ void addWatch(QValueSpacePublisher *, Handle) { return; }
+ void removeWatches(QValueSpacePublisher *, Handle) { return; }
+ void sync() { return; }
+
+ static ContextKitLayer *instance();
+
+private slots:
+ void contextHandleChanged();
+};
+
+QVALUESPACE_AUTO_INSTALL_LAYER(ContextKitLayer);
+
+ContextKitLayer::ContextKitLayer ()
+{
+}
+
+ContextKitLayer::~ContextKitLayer ()
+{
+}
+
+Q_GLOBAL_STATIC(ContextKitLayer, contextKitLayer);
+ContextKitLayer *ContextKitLayer::instance ()
+{
+ return contextKitLayer ();
+}
+
+QString ContextKitLayer::name()
+{
+ return "ContextKit Layer";
+}
+
+bool ContextKitLayer::startup(Type)
+{
+ return true;
+}
+
+QUuid ContextKitLayer::id()
+{
+ return QVALUESPACE_CONTEXTKIT_LAYER;
+}
+
+unsigned int ContextKitLayer::order()
+{
+ return 0;
+}
+
+LayerOptions ContextKitLayer::layerOptions () const
+{
+ return TransientLayer | ReadOnlyLayer;
+}
+
+QAbstractValueSpaceLayer::Handle ContextKitLayer::item (Handle parent, const QString &subPath)
+{
+ return (Handle) new ContextKitHandle ((parent == InvalidHandle)
+ ? NULL
+ : (ContextKitHandle *) parent,
+ subPath);
+}
+
+void ContextKitLayer::removeHandle (Handle handle)
+{
+ ContextKitHandle *h = (ContextKitHandle *)handle;
+ delete h;
+}
+
+void ContextKitLayer::setProperty (Handle handle, Properties properties)
+{
+ ContextKitHandle *h = (ContextKitHandle *)handle;
+
+ if (properties & Publish)
+ connect (h, SIGNAL(valueChanged()),
+ this, SLOT(contextHandleChanged()));
+ else
+ disconnect (h, SIGNAL(valueChanged()),
+ this, SLOT(contextHandleChanged()));
+}
+
+void ContextKitLayer::contextHandleChanged()
+{
+ ContextKitHandle *h = (ContextKitHandle *)sender();
+ emit handleChanged ((Handle) h);
+}
+
+bool ContextKitLayer::value (Handle handle, QVariant *data)
+{
+ ContextKitHandle *h = (ContextKitHandle *)handle;
+ return h->value ("", data);
+}
+
+bool ContextKitLayer::value (Handle handle, const QString &subPath, QVariant *data)
+{
+ ContextKitHandle *h = (ContextKitHandle *)handle;
+ return h->value (subPath, data);
+}
+
+bool ContextKitLayer::notifyInterest(Handle handle, bool interested)
+{
+ ContextKitHandle *h = (ContextKitHandle *)handle;
+
+ if (interested)
+ h->subscribe();
+ else
+ h->unsubscribe();
+ return true;
+}
+
+QSet<QString> ContextKitLayer::children (Handle handle)
+{
+ ContextKitHandle *h = (ContextKitHandle *)handle;
+ return h->children ();
+}
+
+#include "contextkitlayer.moc"
+QTM_END_NAMESPACE
+