as requested.
I didn't implemented any of the new filters yet, but this is the important
bit:
as soon as new filters are added they should work out of the box.

:)
From d1fdd6f88f5f90bfb35f9c88da28321c49d2669f Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 1 Oct 2014 16:23:02 -0300
Subject: [PATCH] Added Possibility to filter more than one filter at a time.

This new version of the TagFilterSortModel actually accepts
*any* new MultiFilterInterface

So, how to use it to create a new filter:

Implement a class that inherits from MultiFilterInterface

Implement the filterRow method

TagFilterSortModel::instance->add( myClass );

and you are done.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/divelistview.cpp  |  2 +-
 qt-ui/models.cpp        | 77 ++++++++++++++++++++++++++++++++++++++++---------
 qt-ui/models.h          | 17 +++++++++--
 qt-ui/simplewidgets.cpp | 12 ++++++++
 qt-ui/simplewidgets.h   |  3 +-
 5 files changed, 93 insertions(+), 18 deletions(-)

diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
index a8f718c..29a2301 100644
--- a/qt-ui/divelistview.cpp
+++ b/qt-ui/divelistview.cpp
@@ -34,7 +34,7 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
 	setItemDelegate(new DiveListDelegate(this));
 	setUniformRowHeights(true);
 	setItemDelegateForColumn(DiveTripModel::RATING, new StarWidgetsDelegate(this));
-	TagFilterSortModel *model = new TagFilterSortModel(this);
+	TagFilterSortModel *model = TagFilterSortModel::instance();
 	model->setSortRole(DiveTripModel::SORT_ROLE);
 	model->setFilterKeyColumn(-1); // filter all columns
 	model->setFilterCaseSensitivity(Qt::CaseInsensitive);
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 2cdea68..9703900 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -2193,25 +2193,22 @@ bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, in
 	return false;
 }
 
-TagFilterSortModel::TagFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent)
-{
-	connect(TagFilterModel::instance(), SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(invalidate()));
-}
+bool makeSure;
 
-bool TagFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
+bool TagFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const
 {
 	// If there's nothing checked, this should show everythin.
-	if (!TagFilterModel::instance()->anyChecked) {
+	if (!anyChecked) {
 		return true;
 	}
 
-	QModelIndex index0 = sourceModel()->index(source_row, 0, source_parent);
-	QVariant diveVariant = sourceModel()->data(index0, DiveTripModel::DIVE_ROLE);
+	QModelIndex index0 = sourceModel->index(source_row, 0, source_parent);
+	QVariant diveVariant = sourceModel->data(index0, DiveTripModel::DIVE_ROLE);
 	struct dive *d = (struct dive *)diveVariant.value<void *>();
 
 	if (!d) { // It's a trip, only show the ones that have dives to be shown.
-		for (int i = 0; i < sourceModel()->rowCount(index0); i++) {
-			if (filterAcceptsRow(i, index0))
+		for (int i = 0; i < sourceModel->rowCount(index0); i++) {
+			if (filterRow(i, index0, sourceModel))
 				return true;
 		}
 		return false;
@@ -2220,23 +2217,75 @@ bool TagFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &sou
 	struct tag_entry *head = d->tag_list;
 
 	if (!head) { // last tag means "Show empty tags";
-		if (TagFilterModel::instance()->rowCount() > 0)
-			return TagFilterModel::instance()->checkState[TagFilterModel::instance()->rowCount() - 1];
+		if (rowCount() > 0)
+			return checkState[rowCount() - 1];
 		else
 			return true;
 	}
 
 	// have at least one tag.
-	QStringList tagList = TagFilterModel::instance()->stringList();
+	QStringList tagList = stringList();
 	if (!tagList.isEmpty()) {
 		tagList.removeLast(); // remove the "Show Empty Tags";
 		while (head) {
 			QString tagName(head->tag->name);
 			int index = tagList.indexOf(tagName);
-			if (TagFilterModel::instance()->checkState[index])
+			if (checkState[index])
 				return true;
 			head = head->next;
 		}
 	}
 	return false;
 }
+
+TagFilterSortModel *TagFilterSortModel::instance()
+{
+	static TagFilterSortModel *self = new TagFilterSortModel();
+	return self;
+}
+
+TagFilterSortModel::TagFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent)
+{
+}
+
+bool TagFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
+{
+	if(makeSure){
+		makeSure = false;
+		qDebug() << "Called";
+	}
+
+	if (models.isEmpty()){
+		return true;
+	}
+
+	Q_FOREACH(MultiFilterInterface *model, models) {
+		if (model->filterRow(source_row, source_parent, sourceModel())){
+			return true;
+		}
+	}
+
+	return false;
+}
+
+void TagFilterSortModel::myInvalidate()
+{
+	qDebug() << "Just making sure..."; makeSure = true;
+	invalidate();
+}
+
+void TagFilterSortModel::addFilterModel(MultiFilterInterface *model)
+{
+	QAbstractItemModel *itemModel = dynamic_cast<QAbstractItemModel*>(model);
+	Q_ASSERT(itemModel);
+	models.append(model);
+	connect(itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(myInvalidate()));
+}
+
+void TagFilterSortModel::removeFilterModel(MultiFilterInterface *model)
+{
+	QAbstractItemModel *itemModel = dynamic_cast<QAbstractItemModel*>(model);
+	Q_ASSERT(itemModel);
+	models.removeAll(model);
+	disconnect(itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(myInvalidate()));
+}
diff --git a/qt-ui/models.h b/qt-ui/models.h
index 18c26df..bf13063 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -417,13 +417,19 @@ private:
 	QStringList languages;
 };
 
-class TagFilterModel : public QStringListModel {
+class MultiFilterInterface {
+public:
+	virtual bool filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const = 0;
+};
+
+class TagFilterModel : public QStringListModel, public MultiFilterInterface{
 	Q_OBJECT
 public:
 	static TagFilterModel *instance();
 	virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
 	virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
 	virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+	virtual bool filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const;
 	bool *checkState;
 	bool anyChecked;
 public
@@ -437,7 +443,14 @@ private:
 class TagFilterSortModel : public QSortFilterProxyModel {
 	Q_OBJECT
 public:
-	TagFilterSortModel(QObject *parent = 0);
+	static TagFilterSortModel *instance();
 	virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
+	void addFilterModel(MultiFilterInterface *model);
+	void removeFilterModel(MultiFilterInterface *model);
+public slots:
+	void myInvalidate();
+private:
+	TagFilterSortModel(QObject *parent = 0);
+	QList<MultiFilterInterface*> models;
 };
 #endif // MODELS_H
diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
index 05532f8..b312615 100644
--- a/qt-ui/simplewidgets.cpp
+++ b/qt-ui/simplewidgets.cpp
@@ -464,3 +464,15 @@ TagFilter::TagFilter(QWidget *parent) : QWidget(parent)
 	connect(ui.filterTag, SIGNAL(textChanged(QString)), filter, SLOT(setFilterFixedString(QString)));
 	ui.tagView->setModel(filter);
 }
+
+void TagFilter::showEvent(QShowEvent *event)
+{
+	TagFilterSortModel::instance()->addFilterModel(TagFilterModel::instance());
+	QWidget::showEvent(event);
+}
+
+void TagFilter::hideEvent(QHideEvent *event)
+{
+	TagFilterSortModel::instance()->removeFilterModel(TagFilterModel::instance());
+	QWidget::hideEvent(event);
+}
diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h
index d665f13..d3e27c0 100644
--- a/qt-ui/simplewidgets.h
+++ b/qt-ui/simplewidgets.h
@@ -134,7 +134,8 @@ class TagFilter : public QWidget {
 	Q_OBJECT
 public:
 	TagFilter(QWidget *parent = 0);
-
+	virtual void showEvent(QShowEvent *);
+	virtual void hideEvent(QHideEvent *);
 private:
 	Ui::TagFilter ui;
 };
-- 
2.1.2

_______________________________________________
subsurface mailing list
[email protected]
http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to