Commit 1c72e166 authored by Karel Slaný's avatar Karel Slaný

Added experimental support for message list filtering.

parent 3dcc95c7
......@@ -93,6 +93,7 @@ SOURCES += \
src/messages.cpp \
src/models/accountmodel.cpp \
src/models/filemodel.cpp \
src/models/list_sort_filter_proxy_model.cpp \
src/models/messagemodel.cpp \
src/qml_interaction/interaction_zfo_file.cpp \
src/qml_interaction/message_info.cpp \
......@@ -124,6 +125,7 @@ HEADERS += \
src/messages.h \
src/models/accountmodel.h \
src/models/filemodel.h \
src/models/list_sort_filter_proxy_model.h \
src/models/messagemodel.h \
src/qml_interaction/interaction_zfo_file.h \
src/qml_interaction/message_info.h \
......
......@@ -27,6 +27,7 @@ import QtQuick.Window 2.1
import QtQuick.Dialogs 1.2
import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.messages 1.0
import cz.nic.mobileDatovka.models 1.0
/*
* Roles are defined in MessageListModel::roleNames() and are accessed directly
......@@ -51,7 +52,18 @@ Component {
emptyList.visible = true
settingsButton.visible = false
}
proxyMessageModel.setSourceModel(messageListModel)
}
ListSortFilterProxyModel {
id: proxyMessageModel
Component.onCompleted: {
setFilterRoles([MessageListModel.ROLE_MSG_ID, MessageListModel.ROLE_ANNOTATION])
}
}
Rectangle {
id: header
anchors.top: parent.top
......@@ -111,7 +123,10 @@ Component {
id: filterPhraseText
placeholderText: qsTr("Filter phrase")
inputMethodHints: Qt.ImhNoPredictiveText
onTextChanged: console.log(filterPhraseText.text) /* TODO */
onTextChanged: {
console.log(filterPhraseText.text) /* TODO */
proxyMessageModel.setFilterRegExpStr(filterPhraseText.text)
}
}
Image {
id: settingsButton
......@@ -151,7 +166,7 @@ Component {
visible: true
width: parent.width
interactive: true
model: messageListModel
model: proxyMessageModel
onCountChanged: {
if (messageList.count == 0) {
......
......@@ -37,6 +37,7 @@
#include "src/net/isds_wrapper.h"
#include "src/models/accountmodel.h"
#include "src/models/filemodel.h"
#include "src/models/list_sort_filter_proxy_model.h"
#include "src/models/messagemodel.h"
#if defined(Q_OS_ANDROID)
#include "src/os_android.h"
......@@ -247,6 +248,7 @@ int main(int argc, char *argv[])
/* Register types into QML. */
FileListModel::declareQML();
ListSortFilterProxyModel::declareQML();
MessageListModel::declareQML();
Messages::declareQML();
MsgInfo::declareQML();
......
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#include <QQmlEngine> /* qmlRegisterType */
#include "src/models/list_sort_filter_proxy_model.h"
void ListSortFilterProxyModel::declareQML(void)
{
qmlRegisterType<ListSortFilterProxyModel>("cz.nic.mobileDatovka.models", 1, 0, "ListSortFilterProxyModel");
qRegisterMetaType<ListSortFilterProxyModel>();
}
ListSortFilterProxyModel::ListSortFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent),
m_filterRoles()
{
}
ListSortFilterProxyModel::ListSortFilterProxyModel(
const ListSortFilterProxyModel &model, QObject *parent)
: QSortFilterProxyModel(parent),
m_filterRoles(model.m_filterRoles)
{
Q_UNUSED(model);
Q_ASSERT(0);
}
void ListSortFilterProxyModel::setFilterRole(int role)
{
m_filterRoles.clear();
m_filterRoles.append(role);
}
void ListSortFilterProxyModel::setFilterRoles(const QList<int> &roles)
{
if (roles.contains(-1)) {
m_filterRoles.clear();
m_filterRoles.append(-1);
} else {
m_filterRoles = roles;
}
}
const QList<int> &ListSortFilterProxyModel::filterRoles(void) const
{
return m_filterRoles;
}
void ListSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
QSortFilterProxyModel::setSourceModel(sourceModel);
}
void ListSortFilterProxyModel::setFilterRegExpStr(const QString &patternCore)
{
setFilterRegExp(QRegExp(patternCore,
Qt::CaseInsensitive, QRegExp::FixedString));
}
bool ListSortFilterProxyModel::filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const
{
/*
* Adapted from
* qtbase/src/corelib/itemmodels/qsortfilterproxymodel.cpp .
*/
if (filterRegExp().isEmpty()) {
return true;
}
QModelIndex sourceIndex(
sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent));
/* The column may not exist. */
return filterAcceptsItem(sourceIndex);
}
bool ListSortFilterProxyModel::filterAcceptsItem(
const QModelIndex &sourceIdx) const
{
if (!sourceIdx.isValid()) {
return false;
}
const QAbstractItemModel *model = sourceModel();
if (m_filterRoles.contains(-1)) {
const QHash<int, QByteArray> roleNames(model->roleNames());
QHash<int, QByteArray>::const_iterator it;
for (it = roleNames.constBegin(); it != roleNames.constEnd(); ++it) {
const QString key(model->data(sourceIdx, it.key()).toString());
if (key.contains(filterRegExp())) {
return true;
}
}
} else {
foreach (int role, m_filterRoles) {
const QString key(model->data(sourceIdx, role).toString());
if (key.contains(filterRegExp())) {
return true;
}
}
}
return false;
}
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#ifndef _LIST_SORT_FILTER_PROXY_MODEL_H_
#define _LIST_SORT_FILTER_PROXY_MODEL_H_
#include <QList>
#include <QSortFilterProxyModel>
class ListSortFilterProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
/* Don't forget to declare various properties to the QML system. */
static
void declareQML(void);
/*!
* @brief Constructor.
*
* @param[in] parent Parent object.
*/
explicit ListSortFilterProxyModel(QObject *parent = Q_NULLPTR);
/*!
* @brief Copy constructor.
*
* @note Needed for QVariant conversion.
* @note This is a dummy function. Calling this constructor causes an
* assertion failure.
*
* @param[in] model Model to be copied.
* @param[in] parent Pointer to parent object.
*/
explicit ListSortFilterProxyModel(const ListSortFilterProxyModel &model,
QObject *parent = Q_NULLPTR);
/*!
* @brief Set the role where the key is used for filtering.
*
* @param[in] role Role number, -1 for all roles.
*/
void setFilterRole(int role);
/*!
* @brief Set roles which are used for filtering.
*
* @param[in] roles Role list. If list contains -1 or is empty
* then all roles are used for filtering.
*/
Q_INVOKABLE
void setFilterRoles(const QList<int> &roles);
/*!
* @brief Return roles which are used for filtering.
*
* @return List of role numbers, may be empty.
*/
const QList<int> &filterRoles(void) const;
/*!
* @brief Set source model.
*
* @param[in] sourceModel Source model to be used.
*/
Q_INVOKABLE virtual
void setSourceModel(QAbstractItemModel *sourceModel) Q_DECL_OVERRIDE;
public slots:
/*!
* @brief Sets regular expression according to expression core.
*
* @param[in] patternCore Regular expression core.
*/
Q_INVOKABLE
void setFilterRegExpStr(const QString &patternCore);
protected:
/*!
* @brief Returns true if the item in the row indicated by the
* given source row and source parent should be included in the
* model; otherwise returns false.
*
* @param[in] sourceRow Row number.
* @param[in] sourceParent Parent index.
* @return Whether the row indicated should be included in the model.
*/
virtual
bool filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const Q_DECL_OVERRIDE;
private:
/*!
* @brief Return the role where the key is used to filter the content.
*
* @note The method is private so it cannot be used.
*
* @return Role number.
*/
int filterRole(void) const;
/*!
* @brief Returns true if the item should be included in the model.
*
* @param[in] sourceIdx Source index.
* @return Whether the item meets the criteria.
*/
bool filterAcceptsItem(const QModelIndex &sourceIdx) const;
QList<int> m_filterRoles; /*!< Roles used for filtering. */
};
/* QML passes its arguments via QVariant. */
Q_DECLARE_METATYPE(ListSortFilterProxyModel)
#endif /* _LIST_SORT_FILTER_PROXY_MODEL_H_ */
......@@ -160,6 +160,7 @@ void MessageListModel::declareQML(void)
{
qmlRegisterType<MessageListModel>("cz.nic.mobileDatovka.models", 1, 0, "MessageListModel");
qRegisterMetaType<MessageListModel>();
qRegisterMetaType<MessageListModel::Roles>();
}
MessageListModel::MessageListModel(QObject *parent)
......
......@@ -88,6 +88,7 @@ public:
ROLE_ATTACHMENTS_DOWNLOADED,
ROLE_MSG_TYPE
};
Q_ENUM(Roles)
/* Don't forget to declare various properties to the QML system. */
static
......@@ -98,7 +99,7 @@ public:
*
* @param[in] parent Pointer to parent object.
*/
MessageListModel(QObject *parent = Q_NULLPTR);
explicit MessageListModel(QObject *parent = Q_NULLPTR);
/*!
* @brief Copy constructor.
......@@ -239,6 +240,7 @@ private:
/* QML passes its arguments via QVariant. */
Q_DECLARE_METATYPE(MessageListModel)
Q_DECLARE_METATYPE(MessageListModel::Roles)
extern MessageListModel globMessagesModel;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment