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 |