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 "qgalleryquerymodel.h"
43
44#include "qgalleryresultset.h"
45#include "qgalleryqueryrequest.h"
46
47#include <QtCore/qstringlist.h>
48#include <QtCore/qpointer.h>
49
50QT_BEGIN_NAMESPACE_DOCGALLERY
51
52class QGalleryQueryModelPrivate
53{
54public:
55 typedef QHash<int, QString> RoleProperties;
56
57 QGalleryQueryModelPrivate(QAbstractGallery *gallery)
58 : q_ptr(0)
59 , resultSet(0)
60 , columnCount(0)
61 , rowCount(0)
62 , query(gallery)
63 {
64 }
65
66 void setObject(QGalleryQueryModel *object)
67 {
68 q_ptr = object;
69
70 QObject::connect(sender: &query, SIGNAL(resultSetChanged(QGalleryResultSet*)),
71 receiver: q_ptr, SLOT(_q_resultSetChanged(QGalleryResultSet*)));
72 QObject::connect(sender: &query, SIGNAL(stateChanged(QGalleryAbstractRequest::State)),
73 receiver: q_ptr, SIGNAL(stateChanged(QGalleryAbstractRequest::State)));
74 QObject::connect(sender: &query, SIGNAL(finished()), receiver: q_ptr, SIGNAL(finished()));
75 QObject::connect(sender: &query, SIGNAL(canceled()), receiver: q_ptr, SIGNAL(canceled()));
76 QObject::connect(sender: &query, SIGNAL(errorChanged()), receiver: q_ptr, SIGNAL(errorChanged()));
77 QObject::connect(sender: &query, SIGNAL(error(int,QString)), receiver: q_ptr, SIGNAL(error(int,QString)));
78 QObject::connect(sender: &query, SIGNAL(galleryChanged()), receiver: q_ptr, SIGNAL(galleryChanged()));
79 QObject::connect(sender: &query, SIGNAL(sortPropertyNamesChanged()), receiver: q_ptr, SIGNAL(sortPropertyNamesChanged()));
80 QObject::connect(sender: &query, SIGNAL(autoUpdateChanged()), receiver: q_ptr, SIGNAL(autoUpdateChanged()));
81 QObject::connect(sender: &query, SIGNAL(offsetChanged()), receiver: q_ptr, SIGNAL(offsetChanged()));
82 QObject::connect(sender: &query, SIGNAL(limitChanged()), receiver: q_ptr, SIGNAL(limitChanged()));
83 QObject::connect(sender: &query, SIGNAL(rootTypeChanged()), receiver: q_ptr, SIGNAL(rootTypeChanged()));
84 QObject::connect(sender: &query, SIGNAL(rootItemChanged()), receiver: q_ptr, SIGNAL(rootItemChanged()));
85 QObject::connect(sender: &query, SIGNAL(scopeChanged()), receiver: q_ptr, SIGNAL(scopeChanged()));
86 QObject::connect(sender: &query, SIGNAL(filterChanged()), receiver: q_ptr, SIGNAL(filterChanged()));
87 }
88
89 void updateRoles(int column);
90 void updateRoles();
91 void _q_resultSetChanged(QGalleryResultSet *resultSet);
92 void _q_itemsInserted(int index, int count);
93 void _q_itemsRemoved(int index, int count);
94 void _q_itemsMoved(int from, int to, int count);
95 void _q_metaDataChanged(int index, int count, const QList<int> &keys);
96
97 QGalleryQueryModel *q_ptr;
98 QGalleryResultSet *resultSet;
99 int columnCount;
100 int rowCount;
101 QGalleryQueryRequest query;
102 QVector<RoleProperties> roleProperties;
103 QVector<int> roleKeys;
104 QVector<int> columnOffsets;
105 QVector<Qt::ItemFlags> itemFlags;
106 QVector<QHash<int, QVariant> > headerData;
107};
108
109void QGalleryQueryModelPrivate::updateRoles(int column)
110{
111 if (resultSet) {
112 int offset = column != 0 ? columnOffsets.at(i: column - 1) : 0;
113
114 const RoleProperties &properties = roleProperties.at(i: column);
115
116 itemFlags[column] = Qt::ItemFlags();
117
118 typedef RoleProperties::const_iterator iterator;
119 for (iterator it = properties.begin(), end = properties.end(); it != end; ++it) {
120 const int key = resultSet->propertyKey(property: it.value());
121
122 if (key > -1) {
123 roleKeys.insert(i: offset, t: it.key());
124 roleKeys.insert(i: offset + 1, t: key);
125
126 offset += 2;
127
128 if (it.key() == Qt::DisplayRole && !properties.contains(akey: Qt::EditRole) &&
129 (resultSet->propertyAttributes(key) & QGalleryProperty::CanWrite)) {
130 roleKeys.insert(i: offset, t: Qt::EditRole);
131 roleKeys.insert(i: offset + 1, t: key);
132
133 offset += 2;
134 }
135
136 itemFlags[column] |= Qt::ItemIsEnabled | Qt::ItemIsSelectable;
137
138 if ((it.key() == Qt::DisplayRole || it.key() == Qt::EditRole)
139 && (resultSet->propertyAttributes(key) & QGalleryProperty::CanWrite)) {
140 itemFlags[column] |= Qt::ItemIsEditable;
141 }
142 }
143 }
144
145 const int difference = column != 0 ? offset - columnOffsets.at(i: column - 1) : offset;
146 for (int i = column + 1; i < columnCount; ++i)
147 columnOffsets[i] += difference;
148
149 columnOffsets[column] = offset;
150 }
151}
152
153void QGalleryQueryModelPrivate::updateRoles()
154{
155 roleKeys.clear();
156
157 if (resultSet) {
158 int offset = 0;
159
160 for (int column = 0; column < columnCount; ++column) {
161 const RoleProperties &properties = roleProperties.at(i: column);
162
163 itemFlags[column] = Qt::ItemFlags();
164
165 typedef RoleProperties::const_iterator iterator;
166 for (iterator it = properties.begin(), end = properties.end(); it != end; ++it) {
167 const int key = resultSet->propertyKey(property: it.value());
168
169 if (key > -1) {
170 roleKeys.append(t: it.key());
171 roleKeys.append(t: key);
172
173 offset += 2;
174
175 if (it.key() == Qt::DisplayRole && !properties.contains(akey: Qt::EditRole) &&
176 (resultSet->propertyAttributes(key) & QGalleryProperty::CanWrite)) {
177 roleKeys.append(t: Qt::EditRole);
178 roleKeys.append(t: key);
179
180 offset += 2;
181 }
182
183 itemFlags[column] |= Qt::ItemIsEnabled | Qt::ItemIsSelectable;
184
185 if ((it.key() == Qt::DisplayRole || it.key() == Qt::EditRole)
186 && (resultSet->propertyAttributes(key) & QGalleryProperty::CanWrite)) {
187 itemFlags[column] |= Qt::ItemIsEditable;
188 }
189 }
190 }
191 columnOffsets[column] = offset;
192 }
193 }
194}
195
196void QGalleryQueryModelPrivate::_q_resultSetChanged(QGalleryResultSet *set)
197{
198 if (rowCount > 0) {
199 q_ptr->beginRemoveRows(parent: QModelIndex(), first: 0, last: rowCount - 1);
200 rowCount = 0;
201 q_ptr->endRemoveRows();
202 }
203
204 resultSet = set;
205
206 if (resultSet) {
207 QObject::connect(
208 sender: resultSet, SIGNAL(itemsInserted(int,int)), receiver: q_ptr, SLOT(_q_itemsInserted(int,int)));
209 QObject::connect(
210 sender: resultSet, SIGNAL(itemsRemoved(int,int)), receiver: q_ptr, SLOT(_q_itemsRemoved(int,int)));
211 QObject::connect(
212 sender: resultSet, SIGNAL(itemsMoved(int,int,int)),
213 receiver: q_ptr, SLOT(_q_itemsMoved(int,int,int)));
214 QObject::connect(
215 sender: resultSet, SIGNAL(metaDataChanged(int,int,QList<int>)),
216 receiver: q_ptr, SLOT(_q_metaDataChanged(int,int,QList<int>)));
217
218 const int count = resultSet->itemCount();
219 if (count > 0) {
220 q_ptr->beginInsertRows(parent: QModelIndex(), first: 0, last: count - 1);
221 rowCount = count;
222 q_ptr->endInsertRows();
223 }
224 }
225}
226
227void QGalleryQueryModelPrivate::_q_itemsInserted(int index, int count)
228{
229 q_ptr->beginInsertRows(parent: QModelIndex(), first: index, last: index + count - 1);
230 rowCount = resultSet->itemCount();
231 q_ptr->endInsertRows();
232}
233
234void QGalleryQueryModelPrivate::_q_itemsRemoved(int index, int count)
235{
236 q_ptr->beginRemoveRows(parent: QModelIndex(), first: index, last: index + count -1);
237 rowCount = resultSet->itemCount();
238 q_ptr->endRemoveRows();
239}
240
241void QGalleryQueryModelPrivate::_q_itemsMoved(int from, int to, int count)
242{
243 q_ptr->beginMoveRows(sourceParent: QModelIndex(), sourceFirst: from, sourceLast: from + count - 1, destinationParent: QModelIndex(), destinationRow: to);
244 q_ptr->endMoveRows();
245}
246
247void QGalleryQueryModelPrivate::_q_metaDataChanged(int index, int count, const QList<int> &keys)
248{
249 for (int i = 0, column = 0; i < roleKeys.count(); i += 2) {
250 if (i == columnOffsets.at(i: column))
251 column += 1;
252
253 if (keys.contains(t: roleKeys.at(i: i + 1))) {
254 const int start = column;
255
256 column += 1;
257
258 for (i = columnOffsets.at(i: start); i < roleKeys.count(); i += 2) {
259 if (i == columnOffsets.at(i: column))
260 break;
261
262 if (keys.contains(t: roleKeys.at(i: i + 1))) {
263 i = columnOffsets.at(i: column) - 2;
264
265 column += 1;
266 }
267 }
268
269 emit q_ptr->dataChanged(
270 topLeft: q_ptr->createIndex(arow: index, acolumn: start),
271 bottomRight: q_ptr->createIndex(arow: index + count - 1, acolumn: column - 1));
272
273 column += 1;
274 }
275 }
276}
277
278/*!
279 \class QGalleryQueryModel
280
281 \ingroup gallery
282
283 \inmodule QtDocGallery
284
285 \brief The QGalleryQueryModel class provides a model for the results of a
286 gallery query.
287
288 The meta-data that should be queried by a QGalleryQueryModel is specified
289 by adding columns to the model, each column has a set of \l roleProperties()
290 which map item data roles to gallery properties. After the model query
291 has been executed the values of the properties requested for each column can
292 be addressed using the roles they were mapped to.
293
294 The \l rootType property identifies the type of gallery item the request
295 should return, if the root type has derivative types (i.e. an audio file is
296 just a special case of a regular file) these will also be included in the
297 result set.
298
299 The \l rootItem property takes the ID of an item the query should only
300 return the children of. Depending on the \l scope of the query this may
301 be {AllDescendents}{all descendents} or just the {DirectDescendents}
302 {direct descendents} of the root item.
303
304 The results of a query can be further limited by setting a \l filter on the
305 model. The model will evaluate the QGalleryFilter and only include
306 items with meta-data matching the expression.
307
308 The order the results are returned in can be specified in the
309 sortPropertyNames property which takes an ordered list of property names.
310 By default properties are sorted in ascending order, but this can be
311 specified explicitly be prefixing the property name with a '+' character
312 for ascending order and a '-' character for descending order.
313
314 If the \l autoUpdate property is true when the query is executed it will
315 enter an \l {QGalleryAbstractRequest::Idle}{Idle} state on finishing and
316 will refresh the queried information if the items matching the query change.
317 If the gallery can't provide updates it will instead go immediately to the
318 \l {QGalleryAbstractRequest::Finished}{Finished} state. Automatic updates
319 can be canceled by calling cancel() on a idle model.
320
321 \sa QGalleryQueryRequest, QDocumentGallery
322*/
323
324/*!
325 Constructs a new query model.
326
327 The \a parent is passed to QAbstractItemModel.
328*/
329
330QGalleryQueryModel::QGalleryQueryModel(QObject *parent)
331 : QAbstractItemModel(parent)
332 , d_ptr(new QGalleryQueryModelPrivate(0))
333{
334 d_ptr->setObject(this);
335}
336
337/*!
338 Constructs a new model which queries items from a \a gallery.
339
340 The \a parent is passed to QAbstractItemModel.
341*/
342
343QGalleryQueryModel::QGalleryQueryModel(QAbstractGallery *gallery, QObject *parent)
344 : QAbstractItemModel(parent)
345 , d_ptr(new QGalleryQueryModelPrivate(gallery))
346{
347 d_ptr->setObject(this);
348}
349
350/*!
351*/
352
353QGalleryQueryModel::~QGalleryQueryModel()
354{
355}
356
357/*!
358 \property QGalleryQueryModel::gallery
359
360 \brief The Gallery a model executes its queries against.
361*/
362
363QAbstractGallery *QGalleryQueryModel::gallery() const
364{
365 return d_ptr->query.gallery();
366}
367
368void QGalleryQueryModel::setGallery(QAbstractGallery *gallery)
369{
370 d_ptr->query.setGallery(gallery);
371}
372
373/*!
374 \fn QGalleryQueryModel::galleryChanged()
375
376 Signals that the value of \l gallery has changed.
377*/
378
379/*!
380 Returns the meta-data properties which a \a column maps to roles.
381*/
382
383QHash<int, QString> QGalleryQueryModel::roleProperties(int column) const
384{
385 return d_func()->roleProperties.value(i: column);
386}
387
388/*!
389 Sets the meta-data \a properties which a \a column maps to roles.
390
391 New properties will not be populated until the query is executed.
392*/
393
394void QGalleryQueryModel::setRoleProperties(int column, const QHash<int, QString> &properties)
395{
396 Q_D(QGalleryQueryModel);
397
398 if (column >= 0 && column < d->columnCount) {
399 d->roleProperties[column] = properties;
400
401 d->updateRoles(column);
402
403 if (d->rowCount > 0)
404 emit dataChanged(topLeft: createIndex(arow: 0, acolumn: column), bottomRight: createIndex(arow: d->rowCount - 1, acolumn: column));
405 }
406}
407
408/*!
409 Adds a column which maps the given \a properties to a query model.
410
411 The column will not be populated until the query is executed.
412*/
413
414void QGalleryQueryModel::addColumn(const QHash<int, QString> &properties)
415{
416 Q_D(QGalleryQueryModel);
417
418 beginInsertColumns(parent: QModelIndex(), first: d->columnCount, last: d->columnCount);
419
420 d->roleProperties.append(t: properties);
421 d->itemFlags.append(t: Qt::ItemFlags());
422 d->columnOffsets.append(t: d->columnOffsets.isEmpty() ? 0 : d->columnOffsets.last());
423 d->headerData.append(t: QHash<int, QVariant>());
424
425 d->columnCount += 1;
426
427 d->updateRoles(column: d->columnCount - 1);
428
429 endInsertColumns();
430}
431
432/*!
433 Adds a column which maps a meta-data \a property to \a role to a query
434 model.
435
436 The column will not be populated until the query is executed.
437*/
438
439void QGalleryQueryModel::addColumn(const QString &property, int role)
440{
441 QHash<int, QString> properties;
442
443 properties.insert(akey: role, avalue: property);
444
445 addColumn(properties);
446}
447
448/*!
449 Inserts a column which maps the given \a properties into a query model at
450 \a index.
451
452 The column will not be populated until the query is executed.
453*/
454
455void QGalleryQueryModel::insertColumn(int index, const QHash<int, QString> &properties)
456{
457 Q_D(QGalleryQueryModel);
458
459 beginInsertColumns(parent: QModelIndex(), first: index, last: index);
460
461 d->roleProperties.insert(i: index, t: properties);
462 d->itemFlags.insert(i: index, t: Qt::ItemFlags());
463 d->columnOffsets.insert(i: index, t: index < d->columnCount ? d->columnOffsets.at(i: index) : 0);
464 d->headerData.insert(i: index, t: QHash<int, QVariant>());
465
466 d->columnCount += 1;
467
468 d->updateRoles(column: index);
469
470 endInsertColumns();
471}
472
473/*!
474 Inserts a column which maps a meta-data \a property to \a role into a
475 query model at \a index.
476
477 The column will not be populated until the query is executed.
478*/
479
480void QGalleryQueryModel::insertColumn(int index, const QString &property, int role)
481{
482 QHash<int, QString> properties;
483
484 properties.insert(akey: role, avalue: property);
485
486 insertColumn(index, properties);
487}
488
489/*!
490 Removes the column at \a index from a query model.
491*/
492
493void QGalleryQueryModel::removeColumn(int index)
494{
495 Q_D(QGalleryQueryModel);
496
497 beginRemoveColumns(parent: QModelIndex(), first: index, last: index);
498
499 const int offset = index != 0 ? d->columnOffsets.at(i: index - 1) : 0;
500 const int count = d->columnOffsets.at(i: index);
501 const int difference = count - offset;
502
503 d->roleProperties.remove(i: index);
504 d->itemFlags.remove(i: index);
505 d->columnOffsets.remove(i: index);
506 d->roleKeys.remove(i: offset, n: difference);
507 d->headerData.remove(i: index);
508
509 d->columnCount -= 1;
510
511 for (int i = index; i < d->columnCount; ++i)
512 d->columnOffsets[i] -= difference;
513
514 endRemoveColumns();
515}
516
517/*!
518 \property QGalleryQueryModel::sortPropertyNames
519
520 \brief A list of names of meta-data properties the results of a query
521 should be sorted on.
522
523 Prefixing a property name with the '+' character indicates it should be sorted
524 in ascending order, and a '-' character prefix indicates a descending order.
525 If there is no prefix ascending order is assumed.
526*/
527
528QStringList QGalleryQueryModel::sortPropertyNames() const
529{
530 return d_ptr->query.sortPropertyNames();
531}
532
533void QGalleryQueryModel::setSortPropertyNames(const QStringList &names)
534{
535 d_ptr->query.setSortPropertyNames(names);
536}
537
538/*!
539 \fn QGalleryQueryModel::sortPropertyNamesChanged()
540
541 Signals that the value of \l sortPropertyNames has changed.
542*/
543
544/*!
545 \property QGalleryQueryModel::autoUpdate
546
547 \brief Whether a query should continue to update its result set after the
548 initial query succeeded.
549*/
550
551bool QGalleryQueryModel::autoUpdate() const
552{
553 return d_ptr->query.autoUpdate();
554}
555
556void QGalleryQueryModel::setAutoUpdate(bool enabled)
557{
558 d_ptr->query.setAutoUpdate(enabled);
559}
560
561/*!
562 \fn QGalleryQueryModel::autoUpdateChanged()
563
564 Signals that the value of \l autoUpdate has changed.
565*/
566
567/*!
568 \property QGalleryQueryModel::offset
569
570 \brief The offset of the first item a query should return.
571*/
572
573int QGalleryQueryModel::offset() const
574{
575 return d_ptr->query.offset();
576}
577
578void QGalleryQueryModel::setOffset(int offset)
579{
580 d_ptr->query.setOffset(offset);
581}
582
583/*!
584 \fn QGalleryQueryModel::offsetChanged()
585
586 Signals that the value of \l offset has changed.
587*/
588
589/*!
590 \property QGalleryQueryModel::limit
591
592 \brief The maximum number of items a query should return.
593*/
594
595int QGalleryQueryModel::limit() const
596{
597 return d_ptr->query.limit();
598}
599
600void QGalleryQueryModel::setLimit(int limit)
601{
602 d_ptr->query.setLimit(limit);
603}
604
605/*!
606 \fn QGalleryQueryModel::limitChanged()
607
608 Signals that the value of \l limit has changed.
609*/
610
611/*!
612 \property QGalleryQueryModel::rootType
613
614 \brief The root item type the results of a query should be restricted to.
615*/
616
617QString QGalleryQueryModel::rootType() const
618{
619 return d_ptr->query.rootType();
620}
621
622void QGalleryQueryModel::setRootType(const QString &itemType)
623{
624 d_ptr->query.setRootType(itemType);
625}
626
627/*!
628 \fn QGalleryQueryModel::rootTypeChanged()
629
630 Signals that the value of \l rootType has changed.
631*/
632
633/*!
634 \property QGalleryQueryModel::rootItem
635
636 \brief The ID of the item a query should return the descendents of.
637
638 \sa scope()
639*/
640
641QVariant QGalleryQueryModel::rootItem() const
642{
643 return d_ptr->query.rootItem();
644}
645
646void QGalleryQueryModel::setRootItem(const QVariant &itemId)
647{
648 d_ptr->query.setRootItem(itemId);
649}
650
651/*!
652 \fn QGalleryQueryModel::rootItemChanged()
653
654 Signals that the value of \l rootItem has changed.
655*/
656
657/*!
658 \property QGalleryQueryModel::scope
659
660 \brief Whether a query will return all descendents of its root item or
661 just the direct decendents.
662
663 \sa rootItem()
664*/
665
666QGalleryQueryRequest::Scope QGalleryQueryModel::scope() const
667{
668 return d_ptr->query.scope();
669}
670
671void QGalleryQueryModel::setScope(QGalleryQueryRequest::Scope scope)
672{
673 d_ptr->query.setScope(scope);
674}
675
676/*!
677 \fn QGalleryQueryModel::scopeChanged()
678
679 Signals that the value of \l scope has changed.
680*/
681
682/*!
683 \property QGalleryQueryModel::filter
684
685 \brief A filter restricting the results of a query.
686*/
687
688QGalleryFilter QGalleryQueryModel::filter() const
689{
690 return d_ptr->query.filter();
691}
692
693void QGalleryQueryModel::setFilter(const QGalleryFilter &filter)
694{
695 d_ptr->query.setFilter(filter);
696}
697
698/*!
699 \fn QGalleryQueryModel::filterChanged()
700
701 Signals that the value of \l filter has changed.
702*/
703
704/*!
705 Executes a query.
706*/
707
708void QGalleryQueryModel::execute()
709{
710 QStringList propertyNames;
711
712 typedef QVector<QGalleryQueryModelPrivate::RoleProperties>::const_iterator iterator;
713 for (iterator it = d_ptr->roleProperties.constBegin(), end = d_ptr->roleProperties.constEnd();
714 it != end;
715 ++it) {
716 propertyNames += it->values();
717 }
718
719 propertyNames.removeDuplicates();
720
721 d_ptr->query.setPropertyNames(propertyNames);
722
723 d_ptr->query.execute();
724
725 d_ptr->updateRoles();
726}
727
728/*!
729 Cancels a query.
730*/
731
732void QGalleryQueryModel::cancel()
733{
734 d_ptr->query.cancel();
735}
736
737/*!
738 Clears the results of a query.
739*/
740
741void QGalleryQueryModel::clear()
742{
743 d_ptr->query.clear();
744}
745
746/*!
747 \property QGalleryQueryModel::error
748
749 \brief The error encountered by an unsuccessful query.
750*/
751
752int QGalleryQueryModel::error() const
753{
754 return d_ptr->query.error();
755}
756
757/*!
758 \property QGalleryQueryModel::errorString
759
760 \brief A string describing the cause of an \l error in more detail.
761
762 This may be an empty string if more information is not known.
763*/
764
765QString QGalleryQueryModel::errorString() const
766{
767 return d_ptr->query.errorString();
768}
769
770/*!
771 \fn QGalleryQueryModel::errorChanged()
772
773 Signals that the \l error and \l errorString properties have changed.
774*/
775
776/*!
777 \fn QGalleryQueryModel::canceled()
778
779 Signals that the query was canceled.
780*/
781
782/*!
783 \fn QGalleryQueryModel::finished()
784
785 Signals that the query has finished.
786*/
787
788/*!
789 \property QGalleryQueryModel::state
790
791 \brief The state of a query.
792*/
793
794QGalleryAbstractRequest::State QGalleryQueryModel::state() const
795{
796 return d_ptr->query.state();
797}
798
799/*!
800 \fn QGalleryQueryModel::stateChanged(QGalleryAbstractRequest::State state)
801
802 Signals that the \a state of the query has changed.
803*/
804
805
806/*!
807 \reimp
808*/
809
810QModelIndex QGalleryQueryModel::index(int row, int column, const QModelIndex &parent) const
811{
812 return !parent.isValid()
813 && row >= 0
814 && row < d_ptr->rowCount
815 && column >= 0
816 && column < d_ptr->columnCount
817 ? createIndex(arow: row, acolumn: column)
818 : QModelIndex();
819}
820
821/*!
822 \reimp
823*/
824
825QModelIndex QGalleryQueryModel::parent(const QModelIndex &index) const
826{
827 Q_UNUSED(index);
828
829 return QModelIndex();
830}
831
832/*!
833 \reimp
834*/
835
836int QGalleryQueryModel::rowCount(const QModelIndex &parent) const
837{
838 return !parent.isValid() ? d_ptr->rowCount : 0;
839}
840
841/*!
842 \reimp
843*/
844
845int QGalleryQueryModel::columnCount(const QModelIndex &parent) const
846{
847 return !parent.isValid() ? d_ptr->columnCount : 0;
848}
849
850/*!
851 \reimp
852*/
853
854QVariant QGalleryQueryModel::data(const QModelIndex &index, int role) const
855{
856 if (index.isValid()) {
857 if (d_ptr->resultSet->currentIndex() != index.row())
858 d_ptr->resultSet->fetch(index: index.row());
859
860 const int offset = index.column() != 0 ? d_ptr->columnOffsets.at(i: index.column() - 1) : 0;
861 const int count = d_ptr->columnOffsets.at(i: index.column());
862
863 for (int i = offset; i < count; i += 2) {
864 if (d_ptr->roleKeys.at(i) == role)
865 return d_ptr->resultSet->metaData(key: d_ptr->roleKeys.at(i: i + 1));
866 }
867 }
868 return QVariant();
869}
870
871/*!
872 \reimp
873*/
874
875bool QGalleryQueryModel::setData(const QModelIndex &index, const QVariant &value, int role)
876{
877 if (index.isValid()) {
878 if (d_ptr->resultSet->currentIndex() != index.row())
879 d_ptr->resultSet->fetch(index: index.row());
880
881 const int offset = index.column() != 0 ? d_ptr->columnOffsets.at(i: index.column() - 1) : 0;
882 const int count = d_ptr->columnOffsets.at(i: index.column());
883
884 for (int i = offset; i < count; i += 2) {
885 if (d_ptr->roleKeys.at(i) == role)
886 return d_ptr->resultSet->setMetaData(key: d_ptr->roleKeys.at(i: i + 1), value);
887 }
888 }
889 return false;
890}
891
892/*!
893 Returns the ID of the item at \a index.
894*/
895
896QVariant QGalleryQueryModel::itemId(const QModelIndex &index) const
897{
898 if (index.isValid()) {
899 if (d_ptr->resultSet->currentIndex() != index.row())
900 d_ptr->resultSet->fetch(index: index.row());
901
902 return d_ptr->resultSet->itemId();
903 }
904 return QVariant();
905}
906
907/*!
908 Returns the URL of the item at \a index.
909*/
910
911QUrl QGalleryQueryModel::itemUrl(const QModelIndex &index) const
912{
913 if (index.isValid()) {
914 if (d_ptr->resultSet->currentIndex() != index.row())
915 d_ptr->resultSet->fetch(index: index.row());
916
917 return d_ptr->resultSet->itemUrl();
918 }
919 return QUrl();
920}
921
922/*!
923 Returns the type of the item at \a index.
924*/
925
926QString QGalleryQueryModel::itemType(const QModelIndex &index) const
927{
928 if (index.isValid()) {
929 if (d_ptr->resultSet->currentIndex() != index.row())
930 d_ptr->resultSet->fetch(index: index.row());
931
932 return d_ptr->resultSet->itemType();
933 }
934 return QString();
935}
936
937/*!
938 \reimp
939*/
940
941QVariant QGalleryQueryModel::headerData(int section, Qt::Orientation orientation, int role) const
942{
943 if (role == Qt::EditRole)
944 role = Qt::DisplayRole;
945
946 return orientation == Qt::Horizontal
947 ? d_func()->headerData.value(i: section).value(akey: role)
948 : QVariant();
949}
950
951/*!
952 \reimp
953*/
954
955bool QGalleryQueryModel::setHeaderData(
956 int section, Qt::Orientation orientation, const QVariant &value, int role)
957{
958 if (orientation == Qt::Horizontal && section >= 0 && section < d_ptr->columnCount) {
959 if (role == Qt::EditRole)
960 role = Qt::DisplayRole;
961
962 d_ptr->headerData[section].insert(akey: role, avalue: value);
963
964 emit headerDataChanged(orientation, first: section, last: section);
965
966 return true;
967 } else {
968 return false;
969 }
970}
971
972/*!
973 \reimp
974*/
975
976Qt::ItemFlags QGalleryQueryModel::flags(const QModelIndex &index) const
977{
978 return d_ptr->itemFlags.value(i: index.column()) ;
979}
980
981#include "moc_qgalleryquerymodel.cpp"
982
983QT_END_NAMESPACE_DOCGALLERY
984

source code of qtdocgallery/src/gallery/qgalleryquerymodel.cpp