qtmobility/src/publishsubscribe/contextkitlayer.cpp
changeset 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qvaluespace.h"
       
    43 #include "qvaluespace_p.h"
       
    44 
       
    45 #include <QSet>
       
    46 #include <QDebug>
       
    47 #include <contextproperty.h>
       
    48 #include <contextregistryinfo.h>
       
    49 
       
    50 QTM_BEGIN_NAMESPACE
       
    51 
       
    52 using namespace QValueSpace;
       
    53 
       
    54 /* ContextKit layer
       
    55 
       
    56    This layer makes ContextKit properties visible in the QValueSpace.
       
    57 
       
    58    You can not publish values of ContextKit properties using the
       
    59    QValueSpace.  This might be fixed later.
       
    60 
       
    61    ContextKit properties have names with dots in them, which allows
       
    62    these properties to be arranged in a tree.  The context commander
       
    63    does this in its UI, for example.
       
    64 
       
    65    However, the ContextKit itself does not pay attention to the dots
       
    66    at all: properties just have names and there are no such things as
       
    67    parent / child / sibling relations between properties.  For
       
    68    example, there is a property called "Battery.ChargeLevel", but the
       
    69    ContextKit doesn't know anything about "Battery".  Subscribing to
       
    70    "Battery" is exactly the same as subscribing to any other
       
    71    non-declared property.  When "Battery.ChargeLevel" changes,
       
    72    "Battery" does _not_ receive a change notification.
       
    73 
       
    74    The QValueSpace, on the other hand, has a explicit tree-structure:
       
    75    the key "/foo" represents all its children, like "/foo/bar".  When
       
    76    "/foo/bar" changes, "/foo" _does_ receive a change notification.
       
    77 
       
    78    There are two ways to map ContextKit properties into the
       
    79    QValueSpace: simply as a long list of siblings (a one-level tree),
       
    80    or as the multi-level tree that is implied by their names.
       
    81 
       
    82    We do the latter since that is more natural.  For example, the
       
    83    ContextKit property "Battery.ChargeLevel" is mapped to
       
    84    "/Battery/ChargeLevel", and the key "/Battery" gets a change
       
    85    notifications for all its children.
       
    86 */
       
    87 
       
    88 /* ContextKitHandle - contains a ContextKit property and all its
       
    89                       direct and indirect children.
       
    90 
       
    91    ContextKitHandles do not form a hierarchy between each other; think
       
    92    of them as individual little trees that are created in direct
       
    93    response to requests to the ContextKitLayer.  The properties in
       
    94    these trees can overlap; a single ContextKit property can be
       
    95    accessed via many ContextKitHandles.
       
    96  */
       
    97 
       
    98 class ContextKitHandle : public QObject {
       
    99     
       
   100     Q_OBJECT
       
   101 
       
   102 public:
       
   103     ContextKitHandle (ContextKitHandle *parent, const QString &root);
       
   104     ~ContextKitHandle ();
       
   105 
       
   106     bool value (const QString &path, QVariant *data);
       
   107     void subscribe ();
       
   108     void unsubscribe ();
       
   109     QSet<QString> children ();
       
   110 
       
   111 signals:
       
   112     void valueChanged();
       
   113 
       
   114 private:
       
   115     QString prefix;
       
   116     QHash<QString, ContextProperty *> props;
       
   117 
       
   118     void insert (const QString &path, const QString &key);
       
   119 };
       
   120 
       
   121 void ContextKitHandle::insert (const QString &path, const QString &key)
       
   122 {
       
   123     ContextProperty *prop = new ContextProperty (key);
       
   124     connect (prop, SIGNAL (valueChanged()),
       
   125              this, SIGNAL (valueChanged()));
       
   126     props.insert (path, prop);
       
   127 }
       
   128 
       
   129 ContextKitHandle::ContextKitHandle (ContextKitHandle *parent, const QString &path)
       
   130 {
       
   131     QString key = path;
       
   132     if (key.startsWith("/"))
       
   133         key = key.mid(1);
       
   134     key = key.replace('/', '.');
       
   135     if (parent)
       
   136         key = parent->prefix + key;
       
   137 
       
   138     prefix = (key == "")? "" : key + ".";
       
   139     foreach (const QString &k, ContextRegistryInfo::instance()->listKeys())
       
   140     {
       
   141         if (k == key)
       
   142             insert ("", k);
       
   143         else if (k.startsWith (prefix))
       
   144             insert (k.mid(prefix.length()).replace ('.', '/'), k);
       
   145     }
       
   146 }
       
   147 
       
   148 ContextKitHandle::~ContextKitHandle ()
       
   149 {
       
   150     foreach (ContextProperty *prop, props.values())
       
   151         delete prop;
       
   152 }
       
   153 
       
   154 bool
       
   155 ContextKitHandle::value (const QString &path, QVariant *data)
       
   156 {
       
   157     // path always starts with a "/".
       
   158     ContextProperty *p = props.value (path.mid(1));
       
   159     if (p)
       
   160     {
       
   161         *data = p->value();
       
   162         return true;
       
   163     }
       
   164     else
       
   165         return false;
       
   166 }
       
   167 
       
   168 void
       
   169 ContextKitHandle::subscribe ()
       
   170 {
       
   171     foreach (ContextProperty *p, props.values())
       
   172         p->subscribe ();
       
   173 }
       
   174 
       
   175 void
       
   176 ContextKitHandle::unsubscribe ()
       
   177 {
       
   178     foreach (ContextProperty *p, props.values())
       
   179         p->unsubscribe ();
       
   180 }
       
   181 
       
   182 QSet<QString>
       
   183 ContextKitHandle::children ()
       
   184 {
       
   185     QSet<QString> kids;
       
   186 
       
   187     foreach (const QString &path, props.keys())
       
   188     {
       
   189         int pos = path.indexOf("/");
       
   190         if (pos >= 0)
       
   191             kids.insert (path.left(pos));
       
   192         else
       
   193             kids.insert (path);
       
   194     }
       
   195     return kids;
       
   196 }
       
   197 
       
   198 /* ContextKitLayer - implements QAbstractValueSpaceLayer interface to
       
   199                      hook ContextKit into QValueSpace.
       
   200    
       
   201    It mainly creates ContextKitHandles and dispatches to them.
       
   202 */
       
   203 
       
   204 class ContextKitLayer : public QAbstractValueSpaceLayer
       
   205 {
       
   206     Q_OBJECT
       
   207 
       
   208 public:
       
   209     ContextKitLayer();
       
   210     virtual ~ContextKitLayer();
       
   211 
       
   212     /* ValueSpaceLayer interface - Common functions */
       
   213     QString name();
       
   214     bool startup(Type);
       
   215     QUuid id();
       
   216     unsigned int order();
       
   217     LayerOptions layerOptions() const;
       
   218 
       
   219     Handle item(Handle parent, const QString &);
       
   220     void removeHandle(Handle);
       
   221     void setProperty(Handle handle, Properties);
       
   222 
       
   223     bool value(Handle, QVariant *);
       
   224     bool value(Handle, const QString &, QVariant *);
       
   225     QSet<QString> children(Handle);
       
   226 
       
   227     /* ValueSpaceLayer interface - QValueSpaceSubscriber functions */
       
   228     bool supportsInterestNotification() const { return true; }
       
   229     bool notifyInterest(Handle handle, bool interested);
       
   230 
       
   231     /* ValueSpaceLayer interface - QValueSpacePublisher functions */
       
   232     bool setValue(QValueSpacePublisher *, Handle, const QString &, const QVariant &) { return false; }
       
   233     bool removeValue(QValueSpacePublisher *, Handle, const QString &) { return false; }
       
   234     bool removeSubTree(QValueSpacePublisher *, Handle) { return false; }
       
   235     void addWatch(QValueSpacePublisher *, Handle) { return; }
       
   236     void removeWatches(QValueSpacePublisher *, Handle) { return; }
       
   237     void sync() { return; }
       
   238 
       
   239     static ContextKitLayer *instance();
       
   240 
       
   241 private slots:
       
   242     void contextHandleChanged();
       
   243 };
       
   244 
       
   245 QVALUESPACE_AUTO_INSTALL_LAYER(ContextKitLayer);
       
   246 
       
   247 ContextKitLayer::ContextKitLayer ()
       
   248 {
       
   249 }
       
   250 
       
   251 ContextKitLayer::~ContextKitLayer ()
       
   252 {
       
   253 }
       
   254 
       
   255 Q_GLOBAL_STATIC(ContextKitLayer, contextKitLayer);
       
   256 ContextKitLayer *ContextKitLayer::instance ()
       
   257 {
       
   258     return contextKitLayer ();
       
   259 }
       
   260 
       
   261 QString ContextKitLayer::name()
       
   262 {
       
   263     return "ContextKit Layer";
       
   264 }
       
   265 
       
   266 bool ContextKitLayer::startup(Type)
       
   267 {
       
   268     return true;
       
   269 }
       
   270 
       
   271 QUuid ContextKitLayer::id()
       
   272 {
       
   273     return QVALUESPACE_CONTEXTKIT_LAYER;
       
   274 }
       
   275 
       
   276 unsigned int ContextKitLayer::order()
       
   277 {
       
   278     return 0;
       
   279 }
       
   280 
       
   281 LayerOptions ContextKitLayer::layerOptions () const
       
   282 {
       
   283     return TransientLayer | ReadOnlyLayer;
       
   284 }
       
   285 
       
   286 QAbstractValueSpaceLayer::Handle ContextKitLayer::item (Handle parent, const QString &subPath)
       
   287 {
       
   288     return (Handle) new ContextKitHandle ((parent == InvalidHandle)
       
   289                                           ? NULL
       
   290                                           : (ContextKitHandle *) parent,
       
   291                                           subPath);
       
   292 }
       
   293 
       
   294 void ContextKitLayer::removeHandle (Handle handle)
       
   295 {
       
   296     ContextKitHandle *h = (ContextKitHandle *)handle;
       
   297     delete h;
       
   298 }
       
   299 
       
   300 void ContextKitLayer::setProperty (Handle handle, Properties properties)
       
   301 {
       
   302     ContextKitHandle *h = (ContextKitHandle *)handle;
       
   303 
       
   304     if (properties & Publish)
       
   305         connect (h, SIGNAL(valueChanged()),
       
   306                  this, SLOT(contextHandleChanged()));
       
   307     else
       
   308         disconnect (h, SIGNAL(valueChanged()),
       
   309                     this, SLOT(contextHandleChanged()));
       
   310 }
       
   311 
       
   312 void ContextKitLayer::contextHandleChanged()
       
   313 {
       
   314     ContextKitHandle *h = (ContextKitHandle *)sender();
       
   315     emit handleChanged ((Handle) h);
       
   316 }
       
   317 
       
   318 bool ContextKitLayer::value (Handle handle, QVariant *data)
       
   319 {
       
   320     ContextKitHandle *h = (ContextKitHandle *)handle;
       
   321     return h->value ("", data);
       
   322 }
       
   323 
       
   324 bool ContextKitLayer::value (Handle handle, const QString &subPath, QVariant *data)
       
   325 {
       
   326     ContextKitHandle *h = (ContextKitHandle *)handle;
       
   327     return h->value (subPath, data);
       
   328 }
       
   329 
       
   330 bool ContextKitLayer::notifyInterest(Handle handle, bool interested)
       
   331 {
       
   332     ContextKitHandle *h = (ContextKitHandle *)handle;
       
   333 
       
   334     if (interested)
       
   335         h->subscribe();
       
   336     else
       
   337         h->unsubscribe();
       
   338     return true;
       
   339 }
       
   340 
       
   341 QSet<QString> ContextKitLayer::children (Handle handle)
       
   342 {
       
   343     ContextKitHandle *h = (ContextKitHandle *)handle;
       
   344     return h->children ();
       
   345 }
       
   346 
       
   347 #include "contextkitlayer.moc"
       
   348 QTM_END_NAMESPACE
       
   349