Mega Code Archive

 
Categories / C++ / Qt
 

Extends QSortFilterProxyModel to create your own filter model

/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file.  Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights.  These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file.  Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef MYSORTFILTERPROXYMODEL_H #define MYSORTFILTERPROXYMODEL_H #include <QDate> #include <QSortFilterProxyModel> class MySortFilterProxyModel : public QSortFilterProxyModel {     Q_OBJECT public:     MySortFilterProxyModel(QObject *parent = 0);     QDate filterMinimumDate() const { return minDate; }     void setFilterMinimumDate(const QDate &date);     QDate filterMaximumDate() const { return maxDate; }     void setFilterMaximumDate(const QDate &date); protected:     bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;     bool lessThan(const QModelIndex &left, const QModelIndex &right) const; private:     bool dateInRange(const QDate &date) const;     QDate minDate;     QDate maxDate; }; #endif #include <QtGui> #include "mysortfilterproxymodel.h" MySortFilterProxyModel::MySortFilterProxyModel(QObject *parent)     : QSortFilterProxyModel(parent) { } void MySortFilterProxyModel::setFilterMinimumDate(const QDate &date) {     minDate = date;     invalidateFilter(); } void MySortFilterProxyModel::setFilterMaximumDate(const QDate &date) {     maxDate = date;     invalidateFilter(); } bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,         const QModelIndex &sourceParent) const {     QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);     QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent);     QModelIndex index2 = sourceModel()->index(sourceRow, 2, sourceParent);     return (sourceModel()->data(index0).toString().contains(filterRegExp())             || sourceModel()->data(index1).toString().contains(filterRegExp()))            && dateInRange(sourceModel()->data(index2).toDate()); }   bool MySortFilterProxyModel::lessThan(const QModelIndex &left,                                       const QModelIndex &right) const {     QVariant leftData = sourceModel()->data(left);     QVariant rightData = sourceModel()->data(right);     if (leftData.type() == QVariant::DateTime) {         return leftData.toDateTime() < rightData.toDateTime();     } else {         QRegExp *emailPattern = new QRegExp("([\\w\\.]*@[\\w\\.]*)");         QString leftString = leftData.toString();         if(left.column() == 1 && emailPattern->indexIn(leftString) != -1)             leftString = emailPattern->cap(1);         QString rightString = rightData.toString();         if(right.column() == 1 && emailPattern->indexIn(rightString) != -1)             rightString = emailPattern->cap(1);         return QString::localeAwareCompare(leftString, rightString) < 0;     } }   bool MySortFilterProxyModel::dateInRange(const QDate &date) const {     return (!minDate.isValid() || date > minDate)            && (!maxDate.isValid() || date < maxDate); } #ifndef WINDOW_H #define WINDOW_H #include <QWidget> QT_BEGIN_NAMESPACE class QAbstractItemModel; class QCheckBox; class QComboBox; class QDateEdit; class QGroupBox; class QLabel; class QLineEdit; class QTreeView; QT_END_NAMESPACE class MySortFilterProxyModel; class Window : public QWidget {     Q_OBJECT public:     Window();     void setSourceModel(QAbstractItemModel *model); private slots:     void textFilterChanged();     void dateFilterChanged(); private:     MySortFilterProxyModel *proxyModel;     QGroupBox *sourceGroupBox;     QGroupBox *proxyGroupBox;     QTreeView *sourceView;     QTreeView *proxyView;     QCheckBox *filterCaseSensitivityCheckBox;     QLabel *filterPatternLabel;     QLabel *fromLabel;     QLabel *toLabel;     QLineEdit *filterPatternLineEdit;     QComboBox *filterSyntaxComboBox;     QDateEdit *fromDateEdit;     QDateEdit *toDateEdit; }; #endif #include <QtGui> #include "mysortfilterproxymodel.h" #include "window.h" Window::Window() {     proxyModel = new MySortFilterProxyModel(this);     proxyModel->setDynamicSortFilter(true);     sourceView = new QTreeView;     sourceView->setRootIsDecorated(false);     sourceView->setAlternatingRowColors(true);     QHBoxLayout *sourceLayout = new QHBoxLayout;     sourceLayout->addWidget(sourceView);     sourceGroupBox = new QGroupBox(tr("Original Model"));     sourceGroupBox->setLayout(sourceLayout);     filterCaseSensitivityCheckBox = new QCheckBox(tr("Case sensitive filter"));     filterCaseSensitivityCheckBox->setChecked(true);     filterPatternLineEdit = new QLineEdit;     filterPatternLineEdit->setText("Grace|Sports");     filterPatternLabel = new QLabel(tr("&Filter pattern:"));     filterPatternLabel->setBuddy(filterPatternLineEdit);     filterSyntaxComboBox = new QComboBox;     filterSyntaxComboBox->addItem(tr("Regular expression"), QRegExp::RegExp);     filterSyntaxComboBox->addItem(tr("Wildcard"), QRegExp::Wildcard);     filterSyntaxComboBox->addItem(tr("Fixed string"), QRegExp::FixedString);     fromDateEdit = new QDateEdit;     fromDateEdit->setDate(QDate(1970, 01, 01));     fromLabel = new QLabel(tr("F&rom:"));     fromLabel->setBuddy(fromDateEdit);     toDateEdit = new QDateEdit;     toDateEdit->setDate(QDate(2099, 12, 31));     toLabel = new QLabel(tr("&To:"));     toLabel->setBuddy(toDateEdit);     connect(filterPatternLineEdit, SIGNAL(textChanged(const QString &)),             this, SLOT(textFilterChanged()));     connect(filterSyntaxComboBox, SIGNAL(currentIndexChanged(int)),             this, SLOT(textFilterChanged()));     connect(filterCaseSensitivityCheckBox, SIGNAL(toggled(bool)),             this, SLOT(textFilterChanged()));     connect(fromDateEdit, SIGNAL(dateChanged(const QDate &)),             this, SLOT(dateFilterChanged()));     connect(toDateEdit, SIGNAL(dateChanged(const QDate &)),               this, SLOT(dateFilterChanged()));     proxyView = new QTreeView;     proxyView->setRootIsDecorated(false);     proxyView->setAlternatingRowColors(true);     proxyView->setModel(proxyModel);     proxyView->setSortingEnabled(true);     proxyView->sortByColumn(1, Qt::AscendingOrder);     QGridLayout *proxyLayout = new QGridLayout;     proxyLayout->addWidget(proxyView, 0, 0, 1, 3);     proxyLayout->addWidget(filterPatternLabel, 1, 0);     proxyLayout->addWidget(filterPatternLineEdit, 1, 1);     proxyLayout->addWidget(filterSyntaxComboBox, 1, 2);     proxyLayout->addWidget(filterCaseSensitivityCheckBox, 2, 0, 1, 3);     proxyLayout->addWidget(fromLabel, 3, 0);     proxyLayout->addWidget(fromDateEdit, 3, 1, 1, 2);     proxyLayout->addWidget(toLabel, 4, 0);     proxyLayout->addWidget(toDateEdit, 4, 1, 1, 2);     proxyGroupBox = new QGroupBox(tr("Sorted/Filtered Model"));     proxyGroupBox->setLayout(proxyLayout);     QVBoxLayout *mainLayout = new QVBoxLayout;     mainLayout->addWidget(sourceGroupBox);     mainLayout->addWidget(proxyGroupBox);     setLayout(mainLayout);     setWindowTitle(tr("Custom Sort/Filter Model"));     resize(500, 450); } void Window::setSourceModel(QAbstractItemModel *model) {     proxyModel->setSourceModel(model);     sourceView->setModel(model); } void Window::textFilterChanged() {     QRegExp::PatternSyntax syntax =             QRegExp::PatternSyntax(filterSyntaxComboBox->itemData(                     filterSyntaxComboBox->currentIndex()).toInt());     Qt::CaseSensitivity caseSensitivity =             filterCaseSensitivityCheckBox->isChecked() ? Qt::CaseSensitive                                                        : Qt::CaseInsensitive;     QRegExp regExp(filterPatternLineEdit->text(), caseSensitivity, syntax);     proxyModel->setFilterRegExp(regExp); } void Window::dateFilterChanged() {     proxyModel->setFilterMinimumDate(fromDateEdit->date());     proxyModel->setFilterMaximumDate(toDateEdit->date()); } #include <QtGui> #include "window.h" void addMail(QAbstractItemModel *model, const QString &subject,              const QString &sender, const QDateTime &date) {     model->insertRow(0);     model->setData(model->index(0, 0), subject);     model->setData(model->index(0, 1), sender);     model->setData(model->index(0, 2), date); } QAbstractItemModel *createMailModel(QObject *parent) {     QStandardItemModel *model = new QStandardItemModel(0, 3, parent);     model->setHeaderData(0, Qt::Horizontal, QObject::tr("Subject"));     model->setHeaderData(1, Qt::Horizontal, QObject::tr("Sender"));     model->setHeaderData(2, Qt::Horizontal, QObject::tr("Date"));     addMail(model, "Happy New Year!", "Grace K. <grace@software-inc.com>",             QDateTime(QDate(2006, 12, 31), QTime(17, 03)));     addMail(model, "Radically new concept", "Grace K. <grace@software-inc.com>",             QDateTime(QDate(2006, 12, 22), QTime(9, 44)));     addMail(model, "Accounts", "pascale@nospam.com",             QDateTime(QDate(2006, 12, 31), QTime(12, 50)));     addMail(model, "Expenses", "Joe Bloggs <joe@bloggs.com>",             QDateTime(QDate(2006, 12, 25), QTime(11, 39)));     addMail(model, "Re: Expenses", "Andy <andy@nospam.com>",             QDateTime(QDate(2007, 01, 02), QTime(16, 05)));     addMail(model, "Re: Accounts", "Joe Bloggs <joe@bloggs.com>",             QDateTime(QDate(2007, 01, 03), QTime(14, 18)));     addMail(model, "Re: Accounts", "Andy <andy@nospam.com>",             QDateTime(QDate(2007, 01, 03), QTime(14, 26)));     addMail(model, "Sports", "Linda Smith <linda.smith@nospam.com>",             QDateTime(QDate(2007, 01, 05), QTime(11, 33)));     addMail(model, "AW: Sports", "Rolf Newschweinstein <rolfn@nospam.com>",             QDateTime(QDate(2007, 01, 05), QTime(12, 00)));     addMail(model, "RE: Sports", "Petra Schmidt <petras@nospam.com>",             QDateTime(QDate(2007, 01, 05), QTime(12, 01)));     return model; } int main(int argc, char *argv[]) {     QApplication app(argc, argv);     Window window;     window.setSourceModel(createMailModel(&window));     window.show();     return app.exec(); }