qtmobility/src/publishsubscribe/gconflayer_linux.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "gconflayer_linux_p.h"
    42 #include "gconflayer_linux_p.h"
    43 #include <QVariant>
    43 #include <QVariant>
    44 #include <GConfItem>
       
    45 
       
    46 #include <QDebug>
       
    47 
    44 
    48 QTM_BEGIN_NAMESPACE
    45 QTM_BEGIN_NAMESPACE
    49 
    46 
    50 Q_GLOBAL_STATIC(GConfLayer, gConfLayer);
    47 Q_GLOBAL_STATIC(GConfLayer, gConfLayer);
    51 QVALUESPACE_AUTO_INSTALL_LAYER(GConfLayer);
    48 QVALUESPACE_AUTO_INSTALL_LAYER(GConfLayer);
    52 
    49 
    53 GConfLayer::GConfLayer()
    50 GConfLayer::GConfLayer()
    54 {
    51 {
       
    52     GConfItem *gconfItem = new GConfItem("/", true, this);
       
    53     connect(gconfItem, SIGNAL(subtreeChanged(const QString &, const QVariant &)), this, SLOT(notifyChanged(const QString &, const QVariant &)));
    55 }
    54 }
    56 
    55 
    57 GConfLayer::~GConfLayer()
    56 GConfLayer::~GConfLayer()
    58 {
    57 {
    59     QMutableHashIterator<QString, GConfHandle *> i(m_handles);
    58     QMutableHashIterator<QString, GConfHandle *> i(m_handles);
    60     while (i.hasNext()) {
    59     while (i.hasNext()) {
    61         i.next();
    60         i.next();
    62 
    61 
    63         removeHandle(Handle(i.value()));
    62         doRemoveHandle(Handle(i.value()));
    64     }
    63     }
    65 }
    64 }
    66 
    65 
    67 QString GConfLayer::name()
    66 QString GConfLayer::name()
    68 {
    67 {
    95     return true;
    94     return true;
    96 }
    95 }
    97 
    96 
    98 bool GConfLayer::value(Handle handle, QVariant *data)
    97 bool GConfLayer::value(Handle handle, QVariant *data)
    99 {
    98 {
       
    99     QMutexLocker locker(&m_mutex);
   100     GConfHandle *sh = gConfHandle(handle);
   100     GConfHandle *sh = gConfHandle(handle);
   101     if (!sh)
   101     if (!sh)
   102         return false;
   102         return false;
   103 
   103 
   104     return value(InvalidHandle, sh->path, data);
   104     return getValue(InvalidHandle, sh->path, data);
   105 }
   105 }
   106 
   106 
   107 bool GConfLayer::value(Handle handle, const QString &subPath, QVariant *data)
   107 bool GConfLayer::value(Handle handle, const QString &subPath, QVariant *data)
       
   108 {
       
   109     QMutexLocker locker(&m_mutex);
       
   110     return getValue(handle, subPath, data);
       
   111 }
       
   112 
       
   113 bool GConfLayer::getValue(Handle handle, const QString &subPath, QVariant *data)
   108 {
   114 {
   109     if (handle != InvalidHandle && !gConfHandle(handle))
   115     if (handle != InvalidHandle && !gConfHandle(handle))
   110         return false;
   116         return false;
   111 
   117 
   112     QString path(subPath);
   118     QString path(subPath);
   125     } else {
   131     } else {
   126         // want a value that is in a sub path under handle
   132         // want a value that is in a sub path under handle
   127         value = path.mid(index + 1);
   133         value = path.mid(index + 1);
   128         path.truncate(index);
   134         path.truncate(index);
   129 
   135 
   130         handle = item(handle, path);
   136         handle = getItem(handle, path);
   131         createdHandle = true;
   137         createdHandle = true;
   132     }
   138     }
   133 
   139 
   134     GConfHandle *sh = gConfHandle(handle);
   140     GConfHandle *sh = gConfHandle(handle);
   135     if (!sh)
   141     if (!sh)
   136         return false;
   142         return false;
   137 
   143 
   138     QString fullPath(sh->path);
   144     QString fullPath(sh->path);
   139     if (fullPath != QLatin1String("/"))
   145     if (fullPath != QLatin1String("/") && !value.isEmpty())
   140         fullPath.append(QLatin1Char('/'));
   146         fullPath.append(QLatin1Char('/'));
   141 
   147 
   142     fullPath.append(value);
   148     fullPath.append(value);
   143 
   149 
   144     qDebug() << "Read value from" << fullPath;
       
   145     GConfItem gconfItem(fullPath);
   150     GConfItem gconfItem(fullPath);
   146     *data = gconfItem.value();
   151     QVariant readValue = gconfItem.value();
   147     qDebug() << "*data = " << *data;
   152     switch (readValue.type()) {
       
   153     case QVariant::Invalid:
       
   154     case QVariant::Bool:
       
   155     case QVariant::Int:
       
   156     case QVariant::Double:
       
   157     case QVariant::StringList:
       
   158     case QVariant::List:
       
   159         *data = readValue;
       
   160         break;
       
   161     case QVariant::String:
       
   162     {
       
   163         QString readString = readValue.toString();
       
   164         QDataStream readStream(QByteArray::fromBase64(readString.toAscii()));
       
   165         QVariant serializedValue;
       
   166         readStream >> serializedValue;
       
   167         if (serializedValue.isValid()) {
       
   168             *data = serializedValue;
       
   169         } else {
       
   170             *data = readValue;
       
   171         }
       
   172         break;
       
   173     }
       
   174     default:
       
   175         break;
       
   176     }
   148 
   177 
   149     if (createdHandle)
   178     if (createdHandle)
   150         removeHandle(handle);
   179         doRemoveHandle(handle);
   151 
       
   152     return data->isValid();
   180     return data->isValid();
   153 }
   181 }
   154 
   182 
   155 QSet<QString> GConfLayer::children(Handle handle)
   183 QSet<QString> GConfLayer::children(Handle handle)
   156 {
   184 {
       
   185     QMutexLocker locker(&m_mutex);
       
   186 
   157     GConfHandle *sh = gConfHandle(handle);
   187     GConfHandle *sh = gConfHandle(handle);
   158     if (!sh)
   188     if (!sh)
   159         return QSet<QString>();
   189         return QSet<QString>();
   160 
   190 
   161     qDebug() << "Get children from" << sh->path;
       
   162     GConfItem gconfItem(sh->path);
   191     GConfItem gconfItem(sh->path);
   163 
   192 
   164     QSet<QString> ret;
   193     QSet<QString> ret;
   165     foreach (QString child, gconfItem.listEntries() + gconfItem.listDirs()) {
   194     foreach (const QString child, gconfItem.listEntries() + gconfItem.listDirs()) {
   166         int index = child.lastIndexOf(QLatin1Char('/'), -1);
   195         const int index = child.lastIndexOf(QLatin1Char('/'), -1);
   167         ret += child.mid(index + 1);
   196         ret += child.mid(index + 1);
   168         qDebug() << "found" << child.mid(index + 1);
       
   169     }
   197     }
   170 
   198 
   171     return ret;
   199     return ret;
   172 }
   200 }
   173 
   201 
   174 QAbstractValueSpaceLayer::Handle GConfLayer::item(Handle parent, const QString &path)
   202 QAbstractValueSpaceLayer::Handle GConfLayer::item(Handle parent, const QString &subPath)
       
   203 {
       
   204     QMutexLocker locker(&m_mutex);
       
   205     return getItem(parent, subPath);
       
   206 }
       
   207 
       
   208 QAbstractValueSpaceLayer::Handle GConfLayer::getItem(Handle parent, const QString &subPath)
   175 {
   209 {
   176     QString fullPath;
   210     QString fullPath;
   177 
   211 
   178     // Fail on invalid path.
   212     // Fail on invalid path.
   179     if (path.isEmpty() || path.contains(QLatin1String("//")))
   213     if (subPath.isEmpty() || subPath.contains(QLatin1String("//")))
   180         return InvalidHandle;
   214         return InvalidHandle;
   181 
   215 
   182     if (parent == InvalidHandle) {
   216     if (parent == InvalidHandle) {
   183         fullPath = path;
   217         fullPath = subPath;
   184     } else {
   218     } else {
   185         GConfHandle *sh = gConfHandle(parent);
   219         GConfHandle *sh = gConfHandle(parent);
   186         if (!sh)
   220         if (!sh)
   187             return InvalidHandle;
   221             return InvalidHandle;
   188 
   222 
   189         if (path == QLatin1String("/")) {
   223         if (subPath == QLatin1String("/")) {
   190             fullPath = sh->path;
   224             fullPath = sh->path;
   191         } else if (sh->path.endsWith(QLatin1Char('/')) && path.startsWith(QLatin1Char('/')))
   225         } else if (sh->path.endsWith(QLatin1Char('/')) && subPath.startsWith(QLatin1Char('/')))
   192             fullPath = sh->path + path.mid(1);
   226             fullPath = sh->path + subPath.mid(1);
   193         else if (!sh->path.endsWith(QLatin1Char('/')) && !path.startsWith(QLatin1Char('/')))
   227         else if (!sh->path.endsWith(QLatin1Char('/')) && !subPath.startsWith(QLatin1Char('/')))
   194             fullPath = sh->path + QLatin1Char('/') + path;
   228             fullPath = sh->path + QLatin1Char('/') + subPath;
   195         else
   229         else
   196             fullPath = sh->path + path;
   230             fullPath = sh->path + subPath;
   197     }
   231     }
   198 
   232 
   199     if (m_handles.contains(fullPath)) {
   233     if (m_handles.contains(fullPath)) {
   200         GConfHandle *sh = m_handles.value(fullPath);
   234         GConfHandle *sh = m_handles.value(fullPath);
   201         ++sh->refCount;
   235         ++sh->refCount;
   209     return Handle(sh);
   243     return Handle(sh);
   210 }
   244 }
   211 
   245 
   212 void GConfLayer::setProperty(Handle handle, Properties properties)
   246 void GConfLayer::setProperty(Handle handle, Properties properties)
   213 {
   247 {
       
   248     QMutexLocker locker(&m_mutex);
       
   249 
   214     GConfHandle *sh = gConfHandle(handle);
   250     GConfHandle *sh = gConfHandle(handle);
   215     if (!sh)
   251     if (!sh)
   216         return;
   252         return;
       
   253     QString basePath = sh->path;
       
   254     if (!basePath.endsWith(QLatin1Char('/'))) {
       
   255         basePath += QLatin1Char('/');
       
   256     }
   217 
   257 
   218     if (properties & QAbstractValueSpaceLayer::Publish) {
   258     if (properties & QAbstractValueSpaceLayer::Publish) {
   219         qDebug() << "TODO: Start monitoring (child) items from" << sh->path;
   259         m_monitoringHandles.insert(sh);
   220     } else {
   260     } else {
   221         qDebug() << "TODO: Stop monitoring (child) items from" << sh->path;
   261         m_monitoringHandles.remove(sh);
   222     }
   262     }
   223 
       
   224 }
   263 }
   225 
   264 
   226 void GConfLayer::removeHandle(Handle handle)
   265 void GConfLayer::removeHandle(Handle handle)
       
   266 {
       
   267     QMutexLocker locker(&m_mutex);
       
   268     doRemoveHandle(handle);
       
   269 }
       
   270 
       
   271 void GConfLayer::doRemoveHandle(Handle handle)
   227 {
   272 {
   228     GConfHandle *sh = gConfHandle(handle);
   273     GConfHandle *sh = gConfHandle(handle);
   229     if (!sh)
   274     if (!sh)
   230         return;
   275         return;
   231 
   276 
   232     if (--sh->refCount)
   277     if (--sh->refCount)
   233         return;
   278         return;
   234 
   279 
       
   280     m_monitoringHandles.remove(sh);
   235     m_handles.remove(sh->path);
   281     m_handles.remove(sh->path);
   236 
   282 
   237     delete sh;
   283     delete sh;
   238 }
   284 }
   239 
   285 
   240 bool GConfLayer::setValue(QValueSpacePublisher */*creator*/,
   286 bool GConfLayer::setValue(QValueSpacePublisher */*creator*/,
   241                                     Handle handle,
   287                                     Handle handle,
   242                                     const QString &subPath,
   288                                     const QString &subPath,
   243                                     const QVariant &data)
   289                                     const QVariant &data)
   244 {
   290 {
       
   291     QMutexLocker locker(&m_mutex);
       
   292 
   245     GConfHandle *sh = gConfHandle(handle);
   293     GConfHandle *sh = gConfHandle(handle);
   246     if (!sh)
   294     if (!sh)
   247         return false;
   295         return false;
   248 
   296 
   249     QString path(subPath);
   297     QString path(subPath);
   263         path.truncate(index);
   311         path.truncate(index);
   264 
   312 
   265         if (path.isEmpty())
   313         if (path.isEmpty())
   266             path.append(QLatin1Char('/'));
   314             path.append(QLatin1Char('/'));
   267 
   315 
   268         sh = gConfHandle(item(Handle(sh), path));
   316         sh = gConfHandle(getItem(Handle(sh), path));
   269         createdHandle = true;
   317         createdHandle = true;
   270     }
   318     }
   271 
   319 
   272     QString fullPath(sh->path);
   320     QString fullPath(sh->path);
   273     if (fullPath != QLatin1String("/"))
   321     if (fullPath != QLatin1String("/"))
   274         fullPath.append(QLatin1Char('/'));
   322         fullPath.append(QLatin1Char('/'));
   275 
   323 
   276     fullPath.append(value);
   324     fullPath.append(value);
   277 
   325 
   278 
       
   279     qDebug() << "Write value" << data << "to" << fullPath;
       
   280     GConfItem gconfItem(fullPath);
   326     GConfItem gconfItem(fullPath);
   281     gconfItem.set(data);
   327     switch (data.type()) {
       
   328     case QVariant::Invalid:
       
   329     case QVariant::Bool:
       
   330     case QVariant::Int:
       
   331     case QVariant::Double:
       
   332     case QVariant::String:
       
   333     case QVariant::StringList:
       
   334     case QVariant::List:
       
   335         gconfItem.set(data);
       
   336         break;
       
   337     default:
       
   338         QByteArray byteArray;
       
   339         QDataStream writeStream(&byteArray, QIODevice::WriteOnly);
       
   340         writeStream << data;
       
   341         QString serializedValue(byteArray.toBase64());
       
   342         gconfItem.set(serializedValue);
       
   343     }
   282 
   344 
   283     if (createdHandle)
   345     if (createdHandle)
   284         removeHandle(Handle(sh));
   346         doRemoveHandle(Handle(sh));
   285     return true;    //TODO: How to check whether set was ok?
   347 
       
   348     return true;
   286 }
   349 }
   287 
   350 
   288 void GConfLayer::sync()
   351 void GConfLayer::sync()
   289 {
   352 {
   290     //Not needed
   353     //Not needed
   298 
   361 
   299 bool GConfLayer::removeValue(QValueSpacePublisher */*creator*/,
   362 bool GConfLayer::removeValue(QValueSpacePublisher */*creator*/,
   300     Handle handle,
   363     Handle handle,
   301     const QString &subPath)
   364     const QString &subPath)
   302 {
   365 {
       
   366     QMutexLocker locker(&m_mutex);
       
   367 
       
   368     QString fullPath;
       
   369 
   303     GConfHandle *sh = gConfHandle(handle);
   370     GConfHandle *sh = gConfHandle(handle);
   304     if (!sh)
   371     if (!sh)
   305         return false;
   372         return false;
   306 
   373 
   307     QString path(subPath);
   374     if (handle == InvalidHandle) {
   308     while (path.endsWith(QLatin1Char('/')))
   375         fullPath = subPath;
   309         path.chop(1);
       
   310 
       
   311     int index = path.lastIndexOf(QLatin1Char('/'), -1);
       
   312 
       
   313     bool createdHandle = false;
       
   314 
       
   315     QString value;
       
   316     if (index == -1) {
       
   317         value = path;
       
   318     } else {
   376     } else {
   319         // want a value that is in a sub path under handle
   377         if (subPath == QLatin1String("/"))
   320         value = path.mid(index + 1);
   378             fullPath = sh->path;
   321         path.truncate(index);
   379         else if (sh->path.endsWith(QLatin1Char('/')) && subPath.startsWith(QLatin1Char('/')))
   322 
   380             fullPath = sh->path + subPath.mid(1);
   323         if (path.isEmpty())
   381         else if (!sh->path.endsWith(QLatin1Char('/')) && !subPath.startsWith(QLatin1Char('/')))
   324             path.append(QLatin1Char('/'));
   382             fullPath = sh->path + QLatin1Char('/') + subPath;
   325 
   383         else
   326         sh = gConfHandle(item(Handle(sh), path));
   384             fullPath = sh->path + subPath;
   327         createdHandle = true;
   385     }
   328     }
   386 
   329 
       
   330     QString fullPath(sh->path);
       
   331     if (fullPath != QLatin1String("/"))
       
   332         fullPath.append(QLatin1Char('/'));
       
   333 
       
   334     fullPath.append(value);
       
   335 
       
   336     qDebug() << "TODO: Remove value from" << fullPath;
       
   337     GConfItem gconfItem(fullPath);
   387     GConfItem gconfItem(fullPath);
   338     gconfItem.unset();
   388     gconfItem.unset();
   339 
   389 
   340     if (createdHandle)
   390     return true;
   341         removeHandle(Handle(sh));
       
   342 
       
   343     return true;    //TODO: How to check whether unset was ok?
       
   344 }
   391 }
   345 
   392 
   346 void GConfLayer::addWatch(QValueSpacePublisher *, Handle)
   393 void GConfLayer::addWatch(QValueSpacePublisher *, Handle)
   347 {
   394 {
   348     //Not needed
   395     //Not needed
   362 {
   409 {
   363     //Not needed
   410     //Not needed
   364     return false;
   411     return false;
   365 }
   412 }
   366 
   413 
       
   414 void GConfLayer::notifyChanged(const QString &key, const QVariant & /*value*/)
       
   415 {
       
   416     foreach (GConfHandle *handle, m_monitoringHandles.values()) {
       
   417         if (key.startsWith(handle->path)) {
       
   418             emit handleChanged(Handle(handle));
       
   419         }
       
   420     }
       
   421 }
       
   422 
   367 #include "moc_gconflayer_linux_p.cpp"
   423 #include "moc_gconflayer_linux_p.cpp"
   368 
   424 
   369 QTM_END_NAMESPACE
   425 QTM_END_NAMESPACE