summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Holland <dominik.holland@pelagicore.com>2016-05-23 11:37:10 +0200
committerDominik Holland <dominik.holland@pelagicore.com>2016-06-07 17:56:50 +0000
commit3c2dec567fe8a339e02b1c6bc889245fd98fd012 (patch)
treee0efb3422db4944b9d9660407a2f074c79b75e07
parente3e018bb74f4633c1fcbc468dda865f36ecc7c24 (diff)
downloadqtivi-3c2dec567fe8a339e02b1c6bc889245fd98fd012.tar.gz
Added the QIviSearchAndBrowseModel class
This class is a generic feature which can be used to browse thru lists and filter or sort them. For filtering, sorting or searching for data the QtIvi Query Language is used. Task-number: QTAUTO-86 Change-Id: Ib74b00370ee51f263584323592d0249c441b58a9 Reviewed-by: Robert Griebl <robert.griebl@pelagicore.com>
-rw-r--r--src/imports/core/plugin.cpp3
-rw-r--r--src/ivicore/ivicore.pro10
-rw-r--r--src/ivicore/qivisearchandbrowsemodel.cpp610
-rw-r--r--src/ivicore/qivisearchandbrowsemodel.h177
-rw-r--r--src/ivicore/qivisearchandbrowsemodel_p.h109
-rw-r--r--src/ivicore/qivisearchandbrowsemodelinterface.cpp79
-rw-r--r--src/ivicore/qivisearchandbrowsemodelinterface.h104
-rw-r--r--src/ivicore/qivisearchandbrowsemodelinterface_p.h73
8 files changed, 1162 insertions, 3 deletions
diff --git a/src/imports/core/plugin.cpp b/src/imports/core/plugin.cpp
index 22f6530..fef1c51 100644
--- a/src/imports/core/plugin.cpp
+++ b/src/imports/core/plugin.cpp
@@ -53,10 +53,11 @@ public:
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtIvi"));
- Q_UNUSED(uri);
+ qRegisterMetaType<QIviServiceObject*>();
qmlRegisterUncreatableType<QIviAbstractFeature>(uri, 1, 0, "AbstractFeature", "AbstractFeature is not accessible directly");
qmlRegisterUncreatableType<QIviAbstractZonedFeature>(uri, 1, 0, "AbstractZonedFeature", "AbstractZonedFeature is not accessible directly");
+ qmlRegisterType<QIviSearchAndBrowseModel>(uri, 1, 0, "SearchAndBrowseModel");
}
};
diff --git a/src/ivicore/ivicore.pro b/src/ivicore/ivicore.pro
index d5e530e..f28f769 100644
--- a/src/ivicore/ivicore.pro
+++ b/src/ivicore/ivicore.pro
@@ -30,7 +30,11 @@ HEADERS += \
qivipropertytester_p.h \
qivitypetraits.h \
qiviabstractfeaturelistmodel.h \
- qiviabstractfeaturelistmodel_p.h
+ qiviabstractfeaturelistmodel_p.h \
+ qivisearchandbrowsemodel.h \
+ qivisearchandbrowsemodel_p.h \
+ qivisearchandbrowsemodelinterface.h \
+ qivisearchandbrowsemodelinterface_p.h
SOURCES += \
qiviservicemanager.cpp \
@@ -42,7 +46,9 @@ SOURCES += \
qivipropertyattribute.cpp \
qiviproperty.cpp \
qivipropertyfactory.cpp \
- qiviabstractfeaturelistmodel.cpp
+ qiviabstractfeaturelistmodel.cpp \
+ qivisearchandbrowsemodel.cpp \
+ qivisearchandbrowsemodelinterface.cpp
include(queryparser/queryparser.pri)
diff --git a/src/ivicore/qivisearchandbrowsemodel.cpp b/src/ivicore/qivisearchandbrowsemodel.cpp
new file mode 100644
index 0000000..358055d
--- /dev/null
+++ b/src/ivicore/qivisearchandbrowsemodel.cpp
@@ -0,0 +1,610 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#include "qivisearchandbrowsemodel.h"
+#include "qivisearchandbrowsemodel_p.h"
+
+#include "qivisearchandbrowsemodelinterface.h"
+#include "queryparser/qiviqueryparser_p.h"
+
+#include <QMetaObject>
+#include <QDebug>
+
+QIviSearchAndBrowseModelPrivate::QIviSearchAndBrowseModelPrivate(const QString &interface, QIviSearchAndBrowseModel *model)
+ : QIviAbstractFeatureListModelPrivate(interface, model)
+ , q_ptr(model)
+ , m_chunkSize(30)
+ , m_queryTerm(nullptr)
+ , m_moreAvailable(false)
+ , m_identifier(QUuid::createUuid())
+ , m_fetchMoreThreshold(10)
+ , m_fetchedDataCount(0)
+ , m_canGoBack(false)
+ , m_loadingType(QIviSearchAndBrowseModel::FetchMore)
+{
+ qRegisterMetaType<QIviSearchAndBrowseListItem>();
+}
+
+QIviSearchAndBrowseModelPrivate::~QIviSearchAndBrowseModelPrivate()
+{
+ delete m_queryTerm;
+}
+
+void QIviSearchAndBrowseModelPrivate::init()
+{
+ Q_Q(QIviSearchAndBrowseModel);
+ q->setDiscoveryMode(QIviAbstractFeature::NoAutoDiscovery);
+
+ QObject::connect(q, &QAbstractListModel::rowsInserted,
+ q, &QIviSearchAndBrowseModel::countChanged);
+ QObject::connect(q, &QAbstractListModel::rowsRemoved,
+ q, &QIviSearchAndBrowseModel::countChanged);
+ QObject::connect(q, &QAbstractListModel::modelReset,
+ q, &QIviSearchAndBrowseModel::countChanged);
+ QObjectPrivate::connect(q, &QIviSearchAndBrowseModel::fetchMoreThresholdReached,
+ this, &QIviSearchAndBrowseModelPrivate::onFetchMoreThresholdReached);
+}
+
+void QIviSearchAndBrowseModelPrivate::onDataFetched(const QUuid &identifer, const QList<QVariant> &items, int start, bool moreAvailable)
+{
+ if (!items.count() || identifer != m_identifier)
+ return;
+
+ Q_Q(QIviSearchAndBrowseModel);
+ m_moreAvailable = moreAvailable;
+
+ if (m_loadingType == QIviSearchAndBrowseModel::FetchMore) {
+ q->beginInsertRows(QModelIndex(), m_itemList.count(), m_itemList.count() + items.count() -1);
+ m_itemList += items;
+ m_fetchedDataCount = m_itemList.count();
+ q->endInsertRows();
+ } else {
+ if (m_itemList.count() < start + items.count()) {
+ qWarning() << "countChanged signal needs to be emitted before the dataFetched signal";
+ return;
+ }
+
+ m_fetchedDataCount = start + items.count();
+
+ for (int i = 0; i < items.count(); i++)
+ m_itemList.replace(start + i, items.at(i));
+ q->dataChanged(q->index(start), q->index(start + items.count() -1));
+ }
+}
+
+void QIviSearchAndBrowseModelPrivate::onCountChanged(const QUuid &identifier, int new_length)
+{
+ if (identifier != m_identifier || m_loadingType != QIviSearchAndBrowseModel::DataChanged || m_itemList.count() == new_length)
+ return;
+
+ Q_Q(QIviSearchAndBrowseModel);
+ q->beginInsertRows(QModelIndex(), m_itemList.count(), m_itemList.count() + new_length -1);
+ for (int i = 0; i < new_length; i++)
+ m_itemList.append(QVariant());
+ q->endInsertRows();
+}
+
+void QIviSearchAndBrowseModelPrivate::onDataChanged(const QUuid &identifier, const QList<QVariant> &data, int start, int count)
+{
+ if (identifier != m_identifier)
+ return;
+ Q_UNUSED(data)
+ Q_UNUSED(start)
+ Q_UNUSED(count)
+
+ //TODO Handle add/update/remove here.
+}
+
+void QIviSearchAndBrowseModelPrivate::onFetchMoreThresholdReached()
+{
+ Q_Q(QIviSearchAndBrowseModel);
+ q->fetchMore(QModelIndex());
+}
+
+void QIviSearchAndBrowseModelPrivate::resetModel()
+{
+ Q_Q(QIviSearchAndBrowseModel);
+ q->beginResetModel();
+ m_itemList.clear();
+ q->endResetModel();
+ m_fetchedDataCount = 0;
+
+ checkType();
+ parseQuery();
+
+ m_moreAvailable = false;
+ q->fetchMore(QModelIndex());
+}
+
+void QIviSearchAndBrowseModelPrivate::parseQuery()
+{
+ if (!searchBackend())
+ return;
+
+ delete m_queryTerm;
+ m_queryTerm = nullptr;
+ m_orderTerms.clear();
+
+ if (m_query.isEmpty())
+ return;
+
+ if (!searchBackend()->supportedFlags().testFlag(QIviSearchAndBrowseModelInterface::SupportsFiltering) && !searchBackend()->supportedFlags().testFlag(QIviSearchAndBrowseModelInterface::SupportsSorting)) {
+ qWarning("The backend doesn't support filtering or sorting. Changing the query will have no effect");
+ return;
+ }
+
+ QIviQueryParser parser;
+ parser.setQuery(m_query);
+ parser.setAllowedIdentifiers(searchBackend()->supportedIdentifiers(m_contentType));
+
+ m_queryTerm = parser.parse();
+
+ if (!m_queryTerm) {
+ qWarning("%s", qPrintable(parser.lastError()));
+ return;
+ }
+ m_orderTerms = parser.orderTerms();
+}
+
+void QIviSearchAndBrowseModelPrivate::checkType()
+{
+ if (!searchBackend() || m_contentType.isEmpty())
+ return;
+
+ QSet<QString> types = searchBackend()->availableContentTypes();
+ if (!types.contains(m_contentType)) {
+ QString error = QString(QLatin1String("Unsupported type: \"%1\" \n Supported types are: \n")).arg(m_contentType);
+ for (const QString &type : types)
+ error.append(type + QLatin1String("\n"));
+ qWarning("%s", qPrintable(error));
+ }
+}
+
+void QIviSearchAndBrowseModelPrivate::clearToDefaults()
+{
+ m_chunkSize = 30;
+ delete m_queryTerm;
+ m_queryTerm = nullptr;
+ m_moreAvailable = false;
+ m_identifier = QUuid::createUuid();
+ m_fetchMoreThreshold = 10;
+ m_contentType = QString();
+ m_fetchedDataCount = 0;
+ m_canGoBack = false;
+ m_loadingType = QIviSearchAndBrowseModel::FetchMore;
+}
+
+void QIviSearchAndBrowseModelPrivate::setCanGoBack(bool canGoBack)
+{
+ Q_Q(QIviSearchAndBrowseModel);
+ if (m_canGoBack == canGoBack)
+ return;
+
+ m_canGoBack = canGoBack;
+ emit q->canGoBackChanged(m_canGoBack);
+}
+
+const QIviSearchAndBrowseListItem *QIviSearchAndBrowseModelPrivate::itemAt(int i) const
+{
+ QVariant var = m_itemList.at(i);
+ if (!var.isValid())
+ return nullptr;
+ const void *data = var.constData();
+
+ QMetaType type(var.userType());
+ if (!type.flags().testFlag(QMetaType::IsGadget)) {
+ qCritical() << "QVariant at" << i << "needs to use the Q_GADGET macro";
+ return nullptr;
+ }
+
+ const QMetaObject *mo = type.metaObject();
+ while (mo) {
+ if (mo->className() == QIviSearchAndBrowseListItem::staticMetaObject.className())
+ return reinterpret_cast<const QIviSearchAndBrowseListItem*>(data);
+ mo = mo->superClass();
+ }
+
+ qCritical() << "QVariant at" << i << "is not derived from QIviSearchAndBrowseListItem";
+
+ return nullptr;
+}
+
+QIviSearchAndBrowseModelInterface *QIviSearchAndBrowseModelPrivate::searchBackend() const
+{
+ Q_Q(const QIviSearchAndBrowseModel);
+ QIviServiceObject* so = q->serviceObject();
+ if (so)
+ return qobject_cast<QIviSearchAndBrowseModelInterface*>(so->interfaceInstance(QIviStringSearchAndBrowseModelInterfaceName));
+
+ return nullptr;
+}
+
+void QIviSearchAndBrowseModelPrivate::updateContentType(const QString &contentType)
+{
+ Q_Q(QIviSearchAndBrowseModel);
+ m_query = QString();
+ emit q->queryChanged(m_query);
+ m_contentType = contentType;
+ emit q->contentTypeChanged(m_contentType);
+ setCanGoBack(searchBackend()->canGoBack(m_identifier, m_contentType));
+
+ resetModel();
+}
+
+QIviSearchAndBrowseModel::QIviSearchAndBrowseModel(QObject *parent)
+ : QIviAbstractFeatureListModel(*new QIviSearchAndBrowseModelPrivate(QIviStringSearchAndBrowseModelInterfaceName, this), parent)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ d->init();
+}
+
+QIviSearchAndBrowseModel::~QIviSearchAndBrowseModel()
+{
+}
+
+QString QIviSearchAndBrowseModel::query() const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ return d->m_query;
+}
+
+void QIviSearchAndBrowseModel::setQuery(const QString &query)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ if (d->m_query == query)
+ return;
+
+ //TODO If we use the stateless navigation this needs to be prevented on the second+ model
+
+ d->m_query = query;
+ emit queryChanged(d->m_query);
+
+ //The query is checked in resetModel
+ d->resetModel();
+}
+
+int QIviSearchAndBrowseModel::chunkSize() const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ return d->m_chunkSize;
+}
+
+void QIviSearchAndBrowseModel::setChunkSize(int chunkSize)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ if (d->m_chunkSize == chunkSize)
+ return;
+
+ d->m_chunkSize = chunkSize;
+ emit chunkSizeChanged(chunkSize);
+}
+
+int QIviSearchAndBrowseModel::fetchMoreThreshold() const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ return d->m_fetchMoreThreshold;
+}
+
+void QIviSearchAndBrowseModel::setFetchMoreThreshold(int fetchMoreThreshold)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ if (d->m_fetchMoreThreshold == fetchMoreThreshold)
+ return;
+
+ d->m_fetchMoreThreshold = fetchMoreThreshold;
+ emit fetchMoreThresholdChanged(fetchMoreThreshold);
+}
+
+QString QIviSearchAndBrowseModel::contentType() const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ return d->m_contentType;
+}
+
+void QIviSearchAndBrowseModel::setContentType(const QString &contentType)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ if (d->m_contentType == contentType)
+ return;
+
+ d->m_contentType = contentType;
+ d->resetModel();
+
+ emit contentTypeChanged(contentType);
+}
+
+QStringList QIviSearchAndBrowseModel::availableContentTypes() const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ return d->m_availableContentTypes;
+}
+
+bool QIviSearchAndBrowseModel::canGoBack() const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ return d->m_canGoBack;
+}
+
+QIviSearchAndBrowseModel::LoadingType QIviSearchAndBrowseModel::loadingType() const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ return d->m_loadingType;
+}
+
+void QIviSearchAndBrowseModel::setLoadingType(QIviSearchAndBrowseModel::LoadingType loadingType)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ if (d->m_loadingType == loadingType)
+ return;
+
+ if (loadingType == QIviSearchAndBrowseModel::DataChanged && !d->searchBackend()->supportedFlags().testFlag(QIviSearchAndBrowseModelInterface::SupportsGetSize)) {
+ qWarning("The backend doesn't support the DataChanged loading type. This call will have no effect");
+ return;
+ }
+
+ d->m_loadingType = loadingType;
+ emit loadingTypeChanged(loadingType);
+
+ d->resetModel();
+}
+
+int QIviSearchAndBrowseModel::rowCount(const QModelIndex &parent) const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ if (parent.isValid())
+ return 0;
+
+ return d->m_itemList.count();
+}
+
+QVariant QIviSearchAndBrowseModel::data(const QModelIndex &index, int role) const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ Q_UNUSED(role)
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+
+ if (row >= d->m_itemList.count() || row < 0)
+ return QVariant();
+
+ if (row >= d->m_fetchedDataCount - d->m_fetchMoreThreshold && canFetchMore(QModelIndex()))
+ emit fetchMoreThresholdReached();
+
+ const QIviSearchAndBrowseListItem *item = d->itemAt(row);
+ if (!item)
+ return QVariant();
+
+ switch (role) {
+ case NameRole: return item->name();
+ case TypeRole: return item->type();
+ case CanGoForwardRole: return canGoForward(row);
+ case ItemRole: return d->m_itemList.at(row);
+ }
+
+ return QVariant();
+}
+
+QVariantMap QIviSearchAndBrowseModel::get(int i) const
+{
+ QVariantMap map;
+ map[QLatin1String("name")] = data(index(i,0), NameRole);
+ map[QLatin1String("type")] = data(index(i,0), TypeRole);
+ map[QLatin1String("canGoForward")] = data(index(i,0), CanGoForwardRole);
+ map[QLatin1String("item")] = data(index(i,0), ItemRole);
+
+ return map;
+}
+
+void QIviSearchAndBrowseModel::goBack()
+{
+ Q_D(QIviSearchAndBrowseModel);
+ QIviSearchAndBrowseModelInterface *backend = d->searchBackend();
+
+ if (!backend) {
+ qWarning("No backend connected");
+ return;
+ }
+
+ if (!backend->canGoBack(d->m_identifier, d->m_contentType)) {
+ qWarning("Can't go backward anymore");
+ return;
+ }
+
+ QString newContentType = backend->goBack(d->m_identifier, d->m_contentType);
+ if (!newContentType.isEmpty())
+ d->updateContentType(newContentType);
+}
+
+bool QIviSearchAndBrowseModel::canGoForward(int i) const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ QIviSearchAndBrowseModelInterface *backend = d->searchBackend();
+
+ if (i >= d->m_itemList.count() || i < 0)
+ return false;
+
+ if (!backend) {
+ qWarning("No backend connected");
+ return false;
+ }
+
+ const QIviSearchAndBrowseListItem *item = d->itemAt(i);
+ if (!item)
+ return false;
+
+ return backend->canGoForward(d->m_identifier, d->m_contentType, item->id());
+}
+
+QIviSearchAndBrowseModel *QIviSearchAndBrowseModel::goForward(int i, NavigationType navigationType)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ QIviSearchAndBrowseModelInterface *backend = d->searchBackend();
+
+ if (i >= d->m_itemList.count() || i < 0)
+ return nullptr;
+
+ if (!backend) {
+ qWarning("No backend connected");
+ return nullptr;
+ }
+
+ const QIviSearchAndBrowseListItem *item = d->itemAt(i);
+ if (!item)
+ return nullptr;
+
+ if (!backend->canGoForward(d->m_identifier, d->m_contentType, item->id())) {
+ qWarning("Can't go forward anymore");
+ return nullptr;
+ }
+
+ if (navigationType == OutOfModelNavigation) {
+ if (backend->supportedFlags() & QIviSearchAndBrowseModelInterface::SupportsStatelessNavigation) {
+ QString newContentType = backend->goForward(d->m_identifier, d->m_contentType, item->id());
+ QIviSearchAndBrowseModel* newModel = new QIviSearchAndBrowseModel(serviceObject(), newContentType, this);
+ return newModel;
+ } else {
+ qWarning("The backend doesn't support the OutOfModelNavigation");
+ return nullptr;
+ }
+ } else {
+ QString newContentType = backend->goForward(d->m_identifier, d->m_contentType, item->id());
+ d->updateContentType(newContentType);
+ }
+
+ return nullptr;
+}
+
+bool QIviSearchAndBrowseModel::canFetchMore(const QModelIndex &parent) const
+{
+ Q_D(const QIviSearchAndBrowseModel);
+ if (parent.isValid())
+ return false;
+
+ return d->m_moreAvailable;
+}
+
+void QIviSearchAndBrowseModel::fetchMore(const QModelIndex &parent)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ if (parent.isValid())
+ return;
+
+ if (!d->searchBackend() || d->m_contentType.isEmpty())
+ return;
+
+ d->m_moreAvailable = false;
+ d->searchBackend()->fetchData(d->m_identifier, d->m_contentType, d->m_queryTerm, d->m_orderTerms, d->m_fetchedDataCount, d->m_chunkSize);
+}
+
+QHash<int, QByteArray> QIviSearchAndBrowseModel::roleNames() const
+{
+ static QHash<int, QByteArray> roles;
+ if (roles.isEmpty()) {
+ roles[NameRole] = "name";
+ roles[TypeRole] = "type";
+ roles[ItemRole] = "item";
+ roles[CanGoForwardRole] = "canGoForward";
+ }
+ return roles;
+}
+
+QIviSearchAndBrowseModel::QIviSearchAndBrowseModel(QIviServiceObject *serviceObject, const QString &contentType, QObject *parent)
+ : QIviSearchAndBrowseModel(parent)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ d->init();
+ setServiceObject(serviceObject);
+ setContentType(contentType);
+}
+
+QIviSearchAndBrowseModel::QIviSearchAndBrowseModel(QIviSearchAndBrowseModelPrivate &dd, QObject *parent)
+ : QIviAbstractFeatureListModel(dd, parent)
+{
+ Q_D(QIviSearchAndBrowseModel);
+ d->init();
+}
+
+bool QIviSearchAndBrowseModel::acceptServiceObject(QIviServiceObject *serviceObject)
+{
+ if (serviceObject)
+ return serviceObject->interfaces().contains(interfaceName());
+ return false;
+}
+
+void QIviSearchAndBrowseModel::connectToServiceObject(QIviServiceObject *serviceObject)
+{
+ Q_UNUSED(serviceObject);
+
+ Q_D(QIviSearchAndBrowseModel);
+
+ QIviSearchAndBrowseModelInterface* backend = d->searchBackend();
+ if (!backend)
+ return;
+
+ QObjectPrivate::connect(backend, &QIviSearchAndBrowseModelInterface::dataFetched,
+ d, &QIviSearchAndBrowseModelPrivate::onDataFetched);
+ QObjectPrivate::connect(backend, &QIviSearchAndBrowseModelInterface::countChanged,
+ d, &QIviSearchAndBrowseModelPrivate::onCountChanged);
+ QObjectPrivate::connect(backend, &QIviSearchAndBrowseModelInterface::dataChanged,
+ d, &QIviSearchAndBrowseModelPrivate::onDataChanged);
+
+ d->setCanGoBack(backend->canGoBack(d->m_identifier, d->m_contentType));
+
+ d->resetModel();
+}
+
+void QIviSearchAndBrowseModel::disconnectFromServiceObject(QIviServiceObject *serviceObject)
+{
+ QIviSearchAndBrowseModelInterface *backend = qobject_cast<QIviSearchAndBrowseModelInterface*>(serviceObject->interfaceInstance(QIviStringSearchAndBrowseModelInterfaceName));
+
+ if (backend)
+ disconnect(backend, 0, this, 0);
+}
+
+void QIviSearchAndBrowseModel::clearServiceObject()
+{
+ Q_D(QIviSearchAndBrowseModel);
+ d->clearToDefaults();
+}
+
+ #include "moc_qivisearchandbrowsemodel.cpp"
diff --git a/src/ivicore/qivisearchandbrowsemodel.h b/src/ivicore/qivisearchandbrowsemodel.h
new file mode 100644
index 0000000..6a5d89e
--- /dev/null
+++ b/src/ivicore/qivisearchandbrowsemodel.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#ifndef QIVISEARCHANDBROWSEMODEL_H
+#define QIVISEARCHANDBROWSEMODEL_H
+
+#include <QtIviCore/QIviAbstractFeatureListModel>
+#include <QtIviCore/QIviServiceObject>
+
+QT_BEGIN_NAMESPACE
+
+class QIviSearchAndBrowseModelPrivate;
+
+static const QLatin1String QIviStringSearchAndBrowseModelInterfaceName("com.qt-project.qtivi.SearchAndBrowseModel");
+
+class Q_QTIVICORE_EXPORT QIviSearchAndBrowseListItem
+{
+ Q_GADGET
+
+ Q_PROPERTY(QString id READ id)
+ Q_PROPERTY(QString name READ name)
+ Q_PROPERTY(QString type READ type)
+public:
+ virtual ~QIviSearchAndBrowseListItem() {};
+
+ virtual QString id() const { return QString(); }
+ virtual QString name() const { return QString(); }
+ virtual QString type() const { return QString(); }
+};
+
+class Q_QTIVICORE_EXPORT QIviSearchAndBrowseModel : public QIviAbstractFeatureListModel
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
+ Q_PROPERTY(QString contentType READ contentType WRITE setContentType NOTIFY contentTypeChanged)
+ Q_PROPERTY(QStringList availableContentTypes READ availableContentTypes NOTIFY availableContentTypesChanged)
+ Q_PROPERTY(int chunkSize READ chunkSize WRITE setChunkSize NOTIFY chunkSizeChanged)
+ Q_PROPERTY(int fetchMoreThreshold READ fetchMoreThreshold WRITE setFetchMoreThreshold NOTIFY fetchMoreThresholdChanged)
+ Q_PROPERTY(int count READ rowCount() NOTIFY countChanged)
+ Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY canGoBackChanged)
+
+ //TODO fix naming
+ Q_PROPERTY(QIviSearchAndBrowseModel::LoadingType loadingType READ loadingType WRITE setLoadingType NOTIFY loadingTypeChanged)
+
+public:
+
+ enum Roles {
+ NameRole = Qt::DisplayRole,
+ TypeRole = Qt::UserRole,
+ ItemRole,
+ CanGoForwardRole
+ };
+
+ //TODO fix naming
+ enum NavigationType {
+ InModelNavigation,
+ OutOfModelNavigation
+ };
+ Q_ENUM(NavigationType)
+
+ //TODO fix naming
+ enum LoadingType {
+ FetchMore,
+ DataChanged
+ };
+ Q_ENUM(LoadingType)
+
+ QIviSearchAndBrowseModel(QObject *parent = Q_NULLPTR);
+ virtual ~QIviSearchAndBrowseModel();
+
+ QString query() const;
+ void setQuery(const QString &query);
+
+ int chunkSize() const;
+ void setChunkSize(int chunkSize);
+
+ int fetchMoreThreshold() const;
+ void setFetchMoreThreshold(int fetchMoreThreshold);
+
+ QString contentType() const;
+ void setContentType(const QString &contentType);
+
+ QStringList availableContentTypes() const;
+
+ bool canGoBack() const;
+
+ QIviSearchAndBrowseModel::LoadingType loadingType() const;
+ void setLoadingType(QIviSearchAndBrowseModel::LoadingType loadingType);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
+ QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
+
+ bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE;
+ void fetchMore(const QModelIndex &parent) Q_DECL_OVERRIDE;
+
+ QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
+
+ Q_INVOKABLE QVariantMap get(int index) const;
+ Q_INVOKABLE void goBack();
+ Q_INVOKABLE bool canGoForward(int index) const;
+ Q_INVOKABLE QIviSearchAndBrowseModel *goForward(int index, NavigationType navigationType);
+
+ template <typename T> T at(int i) const {
+ return data(index(i,0), ItemRole).value<T>();
+ }
+
+Q_SIGNALS:
+ void queryChanged(const QString &query);
+ void chunkSizeChanged(int chunkSize);
+ void countChanged();
+ void fetchMoreThresholdChanged(int fetchMoreThreshold);
+ void fetchMoreThresholdReached() const;
+ void contentTypeChanged(const QString &contentType);
+ void availableContentTypesChanged(const QStringList &availableContentTypes);
+ void canGoBackChanged(bool canGoBack);
+ void loadingTypeChanged(QIviSearchAndBrowseModel::LoadingType loadingType);
+
+protected:
+ QIviSearchAndBrowseModel(QIviServiceObject *serviceObject, const QString &contentType, QObject *parent);
+ QIviSearchAndBrowseModel(QIviSearchAndBrowseModelPrivate &dd, QObject *parent);
+ virtual bool acceptServiceObject(QIviServiceObject *serviceObject) Q_DECL_OVERRIDE;
+ virtual void connectToServiceObject(QIviServiceObject *serviceObject) Q_DECL_OVERRIDE;
+ virtual void disconnectFromServiceObject(QIviServiceObject *serviceObject) Q_DECL_OVERRIDE;
+ virtual void clearServiceObject() Q_DECL_OVERRIDE;
+
+private:
+ Q_DECLARE_PRIVATE(QIviSearchAndBrowseModel)
+ Q_PRIVATE_SLOT(d_func(), void onDataFetched(const QUuid &identifer, const QList<QVariant> &items, int start, bool moreAvailable))
+ Q_PRIVATE_SLOT(d_func(), void onCountChanged(const QUuid &identifier, int new_length))
+ Q_PRIVATE_SLOT(d_func(), void onDataChanged(const QUuid &identifier, const QList<QVariant> &data, int start, int count))
+ Q_PRIVATE_SLOT(d_func(), void onFetchMoreThresholdReached())
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QIviSearchAndBrowseListItem)
+
+#endif // QIVISEARCHANDBROWSEMODEL_H
diff --git a/src/ivicore/qivisearchandbrowsemodel_p.h b/src/ivicore/qivisearchandbrowsemodel_p.h
new file mode 100644
index 0000000..ebbd4a3
--- /dev/null
+++ b/src/ivicore/qivisearchandbrowsemodel_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#ifndef QIVISEARCHMODEL_P_H
+#define QIVISEARCHMODEL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qiviabstractfeaturelistmodel_p.h>
+
+#include "qivisearchandbrowsemodelinterface.h"
+#include "qivisearchandbrowsemodel.h"
+#include "qiviqueryterm.h"
+
+#include <QUuid>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QTIVICORE_EXPORT QIviSearchAndBrowseModelPrivate : public QIviAbstractFeatureListModelPrivate
+{
+public:
+ QIviSearchAndBrowseModelPrivate(const QString &interface, QIviSearchAndBrowseModel *model);
+ ~QIviSearchAndBrowseModelPrivate();
+
+ void init();
+ void onDataFetched(const QUuid &identifer, const QList<QVariant> &items, int start, bool moreAvailable);
+ void onCountChanged(const QUuid &identifier, int new_length);
+ void onDataChanged(const QUuid &identifier, const QList<QVariant> &data, int start, int count);
+ void onFetchMoreThresholdReached();
+ void resetModel();
+ void parseQuery();
+ void checkType();
+ void clearToDefaults();
+ void setCanGoBack(bool canGoBack);
+ const QIviSearchAndBrowseListItem *itemAt(int i) const;
+
+ QIviSearchAndBrowseModelInterface* searchBackend() const;
+ void updateContentType(const QString &contentType);
+
+ QIviSearchAndBrowseModel * const q_ptr;
+ Q_DECLARE_PUBLIC(QIviSearchAndBrowseModel)
+
+ QString m_query;
+ int m_chunkSize;
+
+ QIviAbstractQueryTerm *m_queryTerm;
+ QList<QIviOrderTerm> m_orderTerms;
+ QList<QVariant> m_itemList;
+ bool m_moreAvailable;
+
+ QUuid m_identifier;
+ int m_fetchMoreThreshold;
+ QString m_contentType;
+ int m_fetchedDataCount;
+ QStringList m_availableContentTypes;
+ bool m_canGoBack;
+ QIviSearchAndBrowseModel::LoadingType m_loadingType;
+};
+
+QT_END_NAMESPACE
+
+#endif // QIVISEARCHMODEL_P_H
diff --git a/src/ivicore/qivisearchandbrowsemodelinterface.cpp b/src/ivicore/qivisearchandbrowsemodelinterface.cpp
new file mode 100644
index 0000000..d46d45d
--- /dev/null
+++ b/src/ivicore/qivisearchandbrowsemodelinterface.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#include "qivisearchandbrowsemodelinterface.h"
+#include "qivisearchandbrowsemodelinterface_p.h"
+
+QIviSearchAndBrowseModelInterfacePrivate::QIviSearchAndBrowseModelInterfacePrivate()
+{
+}
+
+QIviSearchAndBrowseModelInterface::QIviSearchAndBrowseModelInterface(QObject *parent)
+ : QObject(*new QIviSearchAndBrowseModelInterfacePrivate(), parent)
+{}
+
+QIviSearchAndBrowseModelInterface::~QIviSearchAndBrowseModelInterface()
+{}
+
+
+QSet<QString> QIviSearchAndBrowseModelInterface::availableContentTypes() const
+{
+ Q_D(const QIviSearchAndBrowseModelInterface);
+ return d->m_types;
+}
+
+QSet<QString> QIviSearchAndBrowseModelInterface::supportedIdentifiers(const QString &contentType) const
+{
+ Q_D(const QIviSearchAndBrowseModelInterface);
+ return d->m_identifiers.values(contentType).toSet();
+}
+
+void QIviSearchAndBrowseModelInterface::registerContentType(const QMetaObject &object, const QString &contentType)
+{
+ Q_D(QIviSearchAndBrowseModelInterface);
+ for (int i=0; i < object.propertyCount(); i++) {
+ QLatin1String propName(object.property(i).name());
+ if (propName != QLatin1String("objectName"))
+ d->m_identifiers.insert(contentType, propName);
+ }
+
+ d->m_types.insert(contentType);
+}
diff --git a/src/ivicore/qivisearchandbrowsemodelinterface.h b/src/ivicore/qivisearchandbrowsemodelinterface.h
new file mode 100644
index 0000000..bbe59d8
--- /dev/null
+++ b/src/ivicore/qivisearchandbrowsemodelinterface.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#ifndef QIVISEARCHMODELINTERFACE_H
+#define QIVISEARCHMODELINTERFACE_H
+
+#include <QObject>
+#include <QSet>
+#include <QMetaObject>
+#include <QMetaProperty>
+#include <QUuid>
+#include <QtIviCore/QIviAbstractQueryTerm>
+
+QT_BEGIN_NAMESPACE
+
+class QIviSearchAndBrowseModelInterfacePrivate;
+
+class Q_QTIVICORE_EXPORT QIviSearchAndBrowseModelInterface : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum Flag {
+ NoExtras = 0x0,
+ SupportsFiltering = 0x1,
+ SupportsSorting = 0x2,
+ SupportsAndConjunction = 0x4,
+ SupportsOrConjunction = 0x8,
+ SupportsStatelessNavigation = 0x10, // (the backend supports to have multiple models showing different contentTypes and filters at the same time)
+ SupportsGetSize = 0x20 // (the backend knows the size of the model when the query is done and the user can select a different way for loading the model content)
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+ Q_FLAG(Flags)
+
+ QIviSearchAndBrowseModelInterface(QObject *parent = Q_NULLPTR);
+ virtual ~QIviSearchAndBrowseModelInterface();
+
+ virtual QSet<QString> availableContentTypes() const;
+ virtual QSet<QString> supportedIdentifiers(const QString &contentType) const;
+ virtual Flags supportedFlags() const = 0;
+
+ virtual void fetchData(const QUuid &identifier, const QString &type, QIviAbstractQueryTerm *term, const QList<QIviOrderTerm> &orderTerms, int start, int count) = 0;
+ virtual bool canGoBack(const QUuid &identifier, const QString &type) = 0;
+ virtual QString goBack(const QUuid &identifier, const QString &type) = 0; // Only used when in-model navigation
+ virtual bool canGoForward(const QUuid &identifier, const QString &type, const QString &itemId) = 0; //Every Item has a id property which is filled by the backend implementation.
+ virtual QString goForward(const QUuid &identifier, const QString &type, const QString &itemId) = 0; //Returns the new type identifier used for the next level. The identifier will stay the same for the following calls but the type might differ.
+
+Q_SIGNALS:
+ void countChanged(const QUuid &identifier, int new_length); // Emitted by the backend if it already knows the total count of items in the model (can be used by the dataChanged display method)
+ void dataFetched(const QUuid &identifier, const QList<QVariant> &data, int start, bool moreAvailabe);
+ void dataChanged(const QUuid &identifier, const QList<QVariant> &data, int start, int count); //start and count defines which data gets replace by the new data content. If data is empty the rows will be removed, if count is 0, the data will be added.
+
+protected:
+ template <typename T>
+ void registerContentType(const QString &contentType) {
+ registerContentType(T::staticMetaObject, contentType);
+ }
+ void registerContentType(const QMetaObject &object, const QString &contentType);
+
+private:
+ Q_DECLARE_PRIVATE(QIviSearchAndBrowseModelInterface)
+};
+
+QT_END_NAMESPACE
+
+#endif // QIVISEARCHMODELINTERFACE_H
diff --git a/src/ivicore/qivisearchandbrowsemodelinterface_p.h b/src/ivicore/qivisearchandbrowsemodelinterface_p.h
new file mode 100644
index 0000000..bab9d46
--- /dev/null
+++ b/src/ivicore/qivisearchandbrowsemodelinterface_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtIvi module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: LGPL-3.0
+**
+****************************************************************************/
+
+#ifndef QIVISEARCHMODELINTERFACE_P_H
+#define QIVISEARCHMODELINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qobject_p.h>
+
+#include "qivisearchandbrowsemodelinterface.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_QTIVICORE_EXPORT QIviSearchAndBrowseModelInterfacePrivate : public QObjectPrivate
+{
+public:
+ QIviSearchAndBrowseModelInterfacePrivate();
+
+ QMultiHash<QString, QString> m_identifiers;
+ QSet<QString> m_types;
+};
+
+QT_END_NAMESPACE
+
+#endif // QIVISEARCHMODELINTERFACE_P_H