1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtDocGallery module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #include "qdeclarativegalleryitem.h" |
43 | |
44 | #include <qgalleryresultset.h> |
45 | |
46 | #include <QtCore/qcoreapplication.h> |
47 | #include <QtQml/qqmlinfo.h> |
48 | #include <QtQml/qqmlpropertymap.h> |
49 | |
50 | QT_BEGIN_NAMESPACE_DOCGALLERY |
51 | |
52 | QDeclarativeGalleryItem::QDeclarativeGalleryItem(QObject *parent) |
53 | : QObject(parent) |
54 | , m_metaData(0) |
55 | , m_status(Null) |
56 | , m_updateStatus(Incomplete) |
57 | { |
58 | connect(sender: &m_request, SIGNAL(stateChanged(QGalleryAbstractRequest::State)), |
59 | receiver: this, SLOT(_q_stateChanged())); |
60 | connect(sender: &m_request, SIGNAL(progressChanged(int,int)), receiver: this, SIGNAL(progressChanged())); |
61 | |
62 | connect(sender: &m_request, SIGNAL(itemChanged()), |
63 | receiver: this, SLOT(_q_itemChanged())); |
64 | connect(sender: &m_request, SIGNAL(metaDataChanged(QList<int>)), |
65 | receiver: this, SLOT(_q_metaDataChanged(QList<int>))); |
66 | |
67 | m_metaData = new QQmlPropertyMap(this); |
68 | |
69 | connect(sender: m_metaData, SIGNAL(valueChanged(QString,QVariant)), |
70 | receiver: this, SLOT(_q_valueChanged(QString,QVariant))); |
71 | } |
72 | |
73 | QDeclarativeGalleryItem::~QDeclarativeGalleryItem() |
74 | { |
75 | } |
76 | |
77 | qreal QDeclarativeGalleryItem::progress() const |
78 | { |
79 | const int max = m_request.maximumProgress(); |
80 | |
81 | return max > 0 |
82 | ? qreal(m_request.currentProgress()) / max |
83 | : qreal(0.0); |
84 | } |
85 | |
86 | void QDeclarativeGalleryItem::setPropertyNames(const QStringList &names) |
87 | { |
88 | if (m_updateStatus == Incomplete) { |
89 | m_request.setPropertyNames(names); |
90 | |
91 | emit propertyNamesChanged(); |
92 | } |
93 | } |
94 | |
95 | void QDeclarativeGalleryItem::setAutoUpdate(bool enabled) |
96 | { |
97 | if (m_request.autoUpdate() != enabled) { |
98 | m_request.setAutoUpdate(enabled); |
99 | |
100 | if (enabled) |
101 | deferredExecute(); |
102 | else if (m_status == Idle) |
103 | m_request.cancel(); |
104 | |
105 | emit autoUpdateChanged(); |
106 | } |
107 | } |
108 | |
109 | void QDeclarativeGalleryItem::setItemId(const QVariant &itemId) |
110 | { |
111 | if (m_request.itemId() != itemId) { |
112 | m_request.setItemId(itemId); |
113 | |
114 | if (m_updateStatus != Incomplete) { |
115 | if (itemId.isValid()) |
116 | m_request.execute(); |
117 | else |
118 | m_request.clear(); |
119 | } |
120 | |
121 | emit itemIdChanged(); |
122 | } |
123 | } |
124 | |
125 | void QDeclarativeGalleryItem::componentComplete() |
126 | { |
127 | m_updateStatus = NoUpdate; |
128 | |
129 | if (m_request.itemId().isValid()) |
130 | m_request.execute(); |
131 | } |
132 | |
133 | void QDeclarativeGalleryItem::reload() |
134 | { |
135 | if (m_updateStatus == PendingUpdate) |
136 | m_updateStatus = CanceledUpdate; |
137 | |
138 | m_request.execute(); |
139 | } |
140 | |
141 | void QDeclarativeGalleryItem::cancel() |
142 | { |
143 | if (m_updateStatus == PendingUpdate) |
144 | m_updateStatus = CanceledUpdate; |
145 | |
146 | m_request.cancel(); |
147 | } |
148 | |
149 | void QDeclarativeGalleryItem::clear() |
150 | { |
151 | if (m_updateStatus == PendingUpdate) |
152 | m_updateStatus = CanceledUpdate; |
153 | |
154 | m_request.clear(); |
155 | } |
156 | |
157 | void QDeclarativeGalleryItem::deferredExecute() |
158 | { |
159 | if (m_updateStatus == NoUpdate) { |
160 | m_updateStatus = PendingUpdate; |
161 | |
162 | QCoreApplication::postEvent(receiver: this, event: new QEvent(QEvent::UpdateRequest)); |
163 | } else if (m_updateStatus == CanceledUpdate) { |
164 | m_updateStatus = PendingUpdate; |
165 | } |
166 | } |
167 | |
168 | bool QDeclarativeGalleryItem::event(QEvent *event) |
169 | { |
170 | if (event->type() == QEvent::UpdateRequest) { |
171 | UpdateStatus status = m_updateStatus; |
172 | m_updateStatus = NoUpdate; |
173 | |
174 | if (status == PendingUpdate) |
175 | m_request.execute(); |
176 | |
177 | return true; |
178 | } else { |
179 | return QObject::event(event); |
180 | } |
181 | } |
182 | |
183 | void QDeclarativeGalleryItem::_q_stateChanged() |
184 | { |
185 | m_status = Status(m_request.state()); |
186 | |
187 | if (m_status == Error) { |
188 | const QString message = m_request.errorString(); |
189 | |
190 | if (!message.isEmpty()) { |
191 | qmlInfo(me: this) << message; |
192 | } else { |
193 | switch (m_request.error()) { |
194 | case QDocumentGallery::ConnectionError: |
195 | qmlInfo(me: this) << tr(s: "An error was encountered connecting to the document gallery" ); |
196 | break; |
197 | case QDocumentGallery::ItemIdError: |
198 | qmlInfo(me: this) << tr(s: "The value of item is not a valid item ID" ); |
199 | break; |
200 | default: |
201 | break; |
202 | } |
203 | } |
204 | emit statusChanged(); |
205 | } else if (m_status == Idle && !m_request.autoUpdate()) { |
206 | m_request.cancel(); |
207 | } else { |
208 | emit statusChanged(); |
209 | } |
210 | } |
211 | |
212 | void QDeclarativeGalleryItem::_q_itemChanged() |
213 | { |
214 | if (m_request.isValid()) { |
215 | for (QHash<int, QString>::const_iterator it = m_propertyKeys.constBegin(); |
216 | it != m_propertyKeys.constEnd(); |
217 | ++it) { |
218 | if (m_request.propertyKey(property: it.value()) < 0) |
219 | m_metaData->clear(key: it.value()); |
220 | } |
221 | |
222 | m_propertyKeys.clear(); |
223 | |
224 | const QStringList propertyNames = m_request.propertyNames(); |
225 | |
226 | for (QStringList::const_iterator it = propertyNames.begin(); it != propertyNames.end(); ++it) { |
227 | const int key = m_request.propertyKey(property: *it); |
228 | |
229 | if (key >= 0) { |
230 | m_propertyKeys.insert(akey: key, avalue: *it); |
231 | |
232 | QVariant value = m_request.metaData(key); |
233 | m_metaData->insert(key: *it, value: value.isNull() |
234 | ? QVariant(m_request.propertyType(key)) |
235 | : value); |
236 | } |
237 | } |
238 | } else { |
239 | typedef QHash<int, QString>::const_iterator iterator; |
240 | for (iterator it = m_propertyKeys.constBegin(); it != m_propertyKeys.constEnd(); ++it) |
241 | m_metaData->clear(key: it.value()); |
242 | |
243 | m_propertyKeys.clear(); |
244 | } |
245 | |
246 | emit availableChanged(); |
247 | } |
248 | |
249 | void QDeclarativeGalleryItem::_q_metaDataChanged(const QList<int> &keys) |
250 | { |
251 | typedef QList<int>::const_iterator iterator; |
252 | for (iterator it = keys.begin(); it != keys.end(); ++it){ |
253 | QVariant value = m_request.metaData(key: *it); |
254 | m_metaData->insert(key: m_propertyKeys.value(akey: *it), value: value.isNull() |
255 | ? QVariant(m_request.propertyType(key: *it)) |
256 | : value); |
257 | } |
258 | } |
259 | |
260 | /*! |
261 | \qmltype DocumentGalleryItem |
262 | \instantiates QDeclarativeDocumentGalleryItem |
263 | |
264 | \inmodule QtDocGallery |
265 | \ingroup qml-gallery |
266 | |
267 | \brief The DocumentGalleryItem element allows you to request information |
268 | about a single item from the document gallery |
269 | |
270 | This element is part of the \b {QtMobility.gallery 1.1} module. |
271 | |
272 | |
273 | \sa DocumentGalleryModel, DocumentGalleryType |
274 | */ |
275 | |
276 | QDeclarativeDocumentGalleryItem::QDeclarativeDocumentGalleryItem(QObject *parent) |
277 | : QDeclarativeGalleryItem(parent) |
278 | { |
279 | connect(sender: this, SIGNAL(availableChanged()), receiver: this, SIGNAL(itemTypeChanged())); |
280 | } |
281 | |
282 | QDeclarativeDocumentGalleryItem::~QDeclarativeDocumentGalleryItem() |
283 | { |
284 | } |
285 | |
286 | void QDeclarativeDocumentGalleryItem::classBegin() |
287 | { |
288 | m_request.setGallery(QDeclarativeDocumentGallery::gallery(object: this)); |
289 | } |
290 | |
291 | /*! |
292 | \qmlproperty enum DocumentGalleryItem::status |
293 | |
294 | This property holds the status of an item request. It can be one of: |
295 | |
296 | \list |
297 | \li Null No \l item has been specified. |
298 | \li Active Information about an \l item is being fetched from the gallery. |
299 | \li Finished Information about an \l item is available. |
300 | \li Idle Information about an \l item which will be automatically |
301 | updated is available. |
302 | \li Canceling The query was canceled but hasn't yet reached the |
303 | canceled status. |
304 | \li Canceled The query was canceled. |
305 | \li Error Information about a type could not be retrieved due to an error. |
306 | \endlist |
307 | */ |
308 | |
309 | /*! |
310 | \qmlproperty real DocumentGalleryItem::progress |
311 | |
312 | This property holds the current progress of the request, from 0.0 (started) |
313 | to 1.0 (finished). |
314 | */ |
315 | |
316 | /*! |
317 | \qmlproperty QStringList DocumentGalleryItem::properties |
318 | |
319 | This property holds the item properties a request should return values for. |
320 | */ |
321 | |
322 | /*! |
323 | \qmlproperty bool DocumentGalleryItem::autoUpdate |
324 | |
325 | This property holds whether a request should refresh its results |
326 | automatically. |
327 | */ |
328 | |
329 | /*! |
330 | \qmlproperty variant DocumentGalleryItem::item |
331 | |
332 | This property holds the id of the item to return information about. |
333 | */ |
334 | |
335 | /*! |
336 | \qmlproperty bool DocumentGalleryItem::available |
337 | |
338 | This property holds whether the meta-data of an item is available. |
339 | */ |
340 | |
341 | /*! |
342 | \qmlproperty enum DocumentGalleryItem::itemType |
343 | |
344 | This property holds the type of a gallery item. It can be one of: |
345 | |
346 | \list |
347 | \li DocumentGallery.InvalidType |
348 | \li DocumentGallery.File |
349 | \li DocumentGallery.Folder |
350 | \li DocumentGallery.Document |
351 | \li DocumentGallery.Text |
352 | \li DocumentGallery.Audio |
353 | \li DocumentGallery.Image |
354 | \li DocumentGallery.Video |
355 | \li DocumentGallery.Playlist |
356 | \li DocumentGallery.Artist |
357 | \li DocumentGallery.AlbumArtist |
358 | \li DocumentGallery.Album |
359 | \li DocumentGallery.AudioGenre |
360 | \li DocumentGallery.PhotoAlbum |
361 | \endlist |
362 | */ |
363 | |
364 | QDeclarativeDocumentGallery::ItemType QDeclarativeDocumentGalleryItem::itemType() const |
365 | { |
366 | return QDeclarativeDocumentGallery::itemTypeFromString(string: m_request.itemType()); |
367 | } |
368 | |
369 | /*! |
370 | \qmlproperty url DocumentGalleryItem::itemUrl |
371 | |
372 | This property holds the URL of a gallery item. |
373 | */ |
374 | |
375 | /*! |
376 | \qmlproperty object DocumentGalleryItem::metaData |
377 | |
378 | This property holds the meta-data of a gallery item. |
379 | */ |
380 | |
381 | /*! |
382 | \qmlmethod DocumentGalleryItem::reload() |
383 | |
384 | Re-queries the gallery. |
385 | */ |
386 | |
387 | /*! |
388 | \qmlmethod DocumentGalleryItem::cancel() |
389 | |
390 | Cancels an executing request. |
391 | */ |
392 | |
393 | /*! |
394 | \qmlmethod DocumentGalleryItem::clear() |
395 | |
396 | Clears the results of a request. |
397 | */ |
398 | |
399 | #include "moc_qdeclarativegalleryitem.cpp" |
400 | |
401 | QT_END_NAMESPACE_DOCGALLERY |
402 | |