patch-bomb.
Tag filtering working.
Load a dive xml file, go to log->filter by tag, filter things.
The dialog will appear between the dive list and the globe, so *maybe* it's
too small and you need to drag it a bit to be able to see.

Tomaz
From 9df5541acf46f556137790be131cb2af2d1039b6 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Tue, 16 Sep 2014 17:23:01 -0300
Subject: [PATCH 01/12] Fix compilation with C99

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 dive.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dive.h b/dive.h
index 47e893f..3c32ee8 100644
--- a/dive.h
+++ b/dive.h
@@ -362,7 +362,7 @@ static inline int get_surface_pressure_in_mbar(const struct dive *dive, bool non
 /* Pa = N/m^2 - so we determine the weight (in N) of the mass of 10m
  * of water (and use standard salt water at 1.03kg per liter if we don't know salinity)
  * and add that to the surface pressure (or to 1013 if that's unknown) */
-inline int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity)
+static inline int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity)
 {
 	double specific_weight;
 	int mbar = surface_pressure.mbar;
@@ -376,7 +376,7 @@ inline int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int s
 	return mbar;
 }
 
-inline int depth_to_mbar(int depth, struct dive *dive)
+static inline int depth_to_mbar(int depth, struct dive *dive)
 {
 	return calculate_depth_to_mbar(depth, dive->surface_pressure, dive->salinity);
 }
-- 
2.1.0

From 90b15ded9bced3dcf60e746beb87a4b84212d3a3 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 13:51:08 -0300
Subject: [PATCH 02/12] Added skeleton to the Tag Filtering.

Just the ui file and a empty class to start playing with it.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/simplewidgets.cpp |  1 +
 qt-ui/simplewidgets.h   |  7 +++++++
 qt-ui/tagfilter.ui      | 27 +++++++++++++++++++++++++++
 subsurface.pro          |  3 ++-
 4 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 qt-ui/tagfilter.ui

diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
index 772c8d1..c745887 100644
--- a/qt-ui/simplewidgets.cpp
+++ b/qt-ui/simplewidgets.cpp
@@ -455,3 +455,4 @@ void DiveComponentSelection::buttonClicked(QAbstractButton *button)
 		selective_copy_dive(&displayed_dive, targetDive, *what, true);
 	}
 }
+
diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h
index b41189f..1673055 100644
--- a/qt-ui/simplewidgets.h
+++ b/qt-ui/simplewidgets.h
@@ -12,6 +12,7 @@ class QAbstractButton;
 #include "ui_shifttimes.h"
 #include "ui_shiftimagetimes.h"
 #include "ui_divecomponentselection.h"
+#include "ui_tagfilter.h"
 #include "exif.h"
 
 class MinMaxAvgWidget : public QWidget {
@@ -126,6 +127,12 @@ private:
 	struct dive_components *what;
 };
 
+class TagFilter : public QWidget {
+	Q_OBJECT
+public:
+	TagFilter(QWidget *parent);
+};
+
 bool isGnome3Session();
 QImage grayImage(const QImage& coloredImg);
 
diff --git a/qt-ui/tagfilter.ui b/qt-ui/tagfilter.ui
new file mode 100644
index 0000000..91078ed
--- /dev/null
+++ b/qt-ui/tagfilter.ui
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TagFilter</class>
+ <widget class="QWidget" name="TagFilter">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLineEdit" name="filterTag"/>
+   </item>
+   <item>
+    <widget class="QListView" name="tagView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/subsurface.pro b/subsurface.pro
index 63024ce..1e85b11 100644
--- a/subsurface.pro
+++ b/subsurface.pro
@@ -221,7 +221,8 @@ FORMS = \
 	qt-ui/plannerSettings.ui \
 	qt-ui/usersurvey.ui \
 	qt-ui/divecomponentselection.ui \
-	qt-ui/configuredivecomputerdialog.ui
+	qt-ui/configuredivecomputerdialog.ui \
+	qt-ui/tagfilter.ui
 
 # Nether usermanual or printing is supported on android right now
 android: FORMS -= qt-ui/printoptions.ui
-- 
2.1.0

From 9cb60a6fbecd306c4a28fa9f877b7171d7555890 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 13:52:42 -0300
Subject: [PATCH 03/12] Removed unused method signature.

This was declared on a class definition, but never implemented.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/simplewidgets.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h
index 1673055..7b83834 100644
--- a/qt-ui/simplewidgets.h
+++ b/qt-ui/simplewidgets.h
@@ -77,7 +77,6 @@ public:
 	explicit ShiftImageTimesDialog(QWidget *parent);
 	time_t amount() const;
 	void setOffset(time_t offset);
-	time_t epochFromExiv(EXIFInfo *exif);
 private
 slots:
 	void buttonClicked(QAbstractButton *button);
-- 
2.1.0

From 87c9a59073751354d4153869849ce982bffd21f2 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 14:17:41 -0300
Subject: [PATCH 04/12] Add the Tag Widget on the MainWindow

Place the TagWidget on the correct place on the main  window.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/mainwindow.ui     | 9 ++++++++-
 qt-ui/simplewidgets.cpp | 4 ++++
 qt-ui/simplewidgets.h   | 4 +++-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/qt-ui/mainwindow.ui b/qt-ui/mainwindow.ui
index 6b27e66..c1580af 100644
--- a/qt-ui/mainwindow.ui
+++ b/qt-ui/mainwindow.ui
@@ -145,6 +145,7 @@
         </widget>
         <widget class="PlannerSettingsWidget" name="plannerSettingsWidget"/>
        </widget>
+       <widget class="TagFilter" name="tagFilter" native="true"/>
        <widget class="QStackedWidget" name="globePane">
         <property name="currentIndex">
          <number>0</number>
@@ -162,7 +163,7 @@
           </item>
          </layout>
         </widget>
-        <widget class="QWidget" name="page_5">
+	<widget class="QWidget" name="page_5">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
            <horstretch>0</horstretch>
@@ -879,6 +880,12 @@ p, li { white-space: pre-wrap; }
    <header>diveplanner.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>TagFilter</class>
+   <extends>QWidget</extends>
+   <header>simplewidgets.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources>
   <include location="../subsurface.qrc"/>
diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
index c745887..e9bfc3c 100644
--- a/qt-ui/simplewidgets.cpp
+++ b/qt-ui/simplewidgets.cpp
@@ -456,3 +456,7 @@ void DiveComponentSelection::buttonClicked(QAbstractButton *button)
 	}
 }
 
+TagFilter::TagFilter(QWidget *parent): QWidget(parent)
+{
+	ui.setupUi(this);
+}
diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h
index 7b83834..c9f5dc2 100644
--- a/qt-ui/simplewidgets.h
+++ b/qt-ui/simplewidgets.h
@@ -129,7 +129,9 @@ private:
 class TagFilter : public QWidget {
 	Q_OBJECT
 public:
-	TagFilter(QWidget *parent);
+	TagFilter(QWidget *parent = 0);
+private:
+	Ui::TagFilter ui;
 };
 
 bool isGnome3Session();
-- 
2.1.0

From bfce1f70e63bfbbcb0cb008225fe83e9bf346776 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 14:50:41 -0300
Subject: [PATCH 05/12] Trigger the log->filter by tag to open the tag filter.

You can't really close it for now.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/mainwindow.cpp | 6 ++++++
 qt-ui/mainwindow.h   | 2 +-
 qt-ui/mainwindow.ui  | 8 +++++++-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 6e3aeec..8cdf6de 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -69,6 +69,7 @@ MainWindow::MainWindow() : QMainWindow(),
 	Q_ASSERT_X(m_Instance == NULL, "MainWindow", "MainWindow recreated!");
 	m_Instance = this;
 	ui.setupUi(this);
+	ui.tagFilter->hide();
 	profileToolbarActions << ui.profCalcAllTissues << ui.profCalcCeiling << ui.profDcCeiling << ui.profEad <<
 		    ui.profHR << ui.profIncrement3m << ui.profMod << ui.profNdl_tts << ui.profNdl_tts <<
 		    ui.profPhe << ui.profPn2 << ui.profPO2 << ui.profRuler << ui.profSAC << ui.profScaled <<
@@ -1327,3 +1328,8 @@ void MainWindow::on_paste_triggered()
 	selective_copy_dive(&copyPasteDive, &displayed_dive, what, false);
 	ui.InfoWidget->showAndTriggerEditSelective(what);
 }
+
+void MainWindow::on_actionFilterTags_triggered()
+{
+	ui.tagFilter->show();
+}
diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
index 1ae717a..270d907 100644
--- a/qt-ui/mainwindow.h
+++ b/qt-ui/mainwindow.h
@@ -146,7 +146,7 @@ slots:
 	void on_actionExport_triggered();
 	void on_copy_triggered();
 	void on_paste_triggered();
-
+	void on_actionFilterTags_triggered();
 	void on_actionConfigure_Dive_Computer_triggered();
 
 protected:
diff --git a/qt-ui/mainwindow.ui b/qt-ui/mainwindow.ui
index c1580af..44bd629 100644
--- a/qt-ui/mainwindow.ui
+++ b/qt-ui/mainwindow.ui
@@ -163,7 +163,7 @@
           </item>
          </layout>
         </widget>
-	<widget class="QWidget" name="page_5">
+        <widget class="QWidget" name="page_5">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
            <horstretch>0</horstretch>
@@ -296,6 +296,7 @@ p, li { white-space: pre-wrap; }
     <addaction name="actionAutoGroup"/>
     <addaction name="separator"/>
     <addaction name="actionEditDeviceNames"/>
+    <addaction name="actionFilterTags"/>
    </widget>
    <widget class="QMenu" name="menuView">
     <property name="title">
@@ -838,6 +839,11 @@ p, li { white-space: pre-wrap; }
     <string>Toggle Tank Bar</string>
    </property>
   </action>
+  <action name="actionFilterTags">
+   <property name="text">
+    <string>Filter by Tags</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
-- 
2.1.0

From 9f450b44b6e229ce9f168cd278fa291b4cdc8033 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 15:45:18 -0300
Subject: [PATCH 06/12] Implement the TagFilter model.

This model accepts check / unchedk. Now, I need to also
plug the result of the check / uncheck to the list model.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/mainwindow.cpp    |  1 +
 qt-ui/models.cpp        | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
 qt-ui/models.h          | 14 ++++++++++++++
 qt-ui/simplewidgets.cpp |  5 +++++
 4 files changed, 71 insertions(+)

diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 8cdf6de..ec5fbd0 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -181,6 +181,7 @@ void MainWindow::refreshDisplay(bool doRecreateDiveList)
 void MainWindow::recreateDiveList()
 {
 	ui.ListWidget->reload(DiveTripModel::CURRENT);
+	TagFilterModel::instance()->repopulate();
 }
 
 void MainWindow::current_dive_changed(int divenr)
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 5266130..b227027 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -2099,3 +2099,54 @@ int LanguageModel::rowCount(const QModelIndex &parent) const
 {
 	return languages.count();
 }
+
+
+TagFilterModel::TagFilterModel(QObject *parent): QStringListModel(parent), checkState(NULL)
+{
+}
+
+TagFilterModel *TagFilterModel::instance()
+{
+	static TagFilterModel *self = new TagFilterModel();
+	return self;
+}
+
+QVariant TagFilterModel::data(const QModelIndex &index, int role) const
+{
+	if(role == Qt::CheckStateRole){
+		return checkState[index.row()] ? Qt::Checked : Qt::Unchecked;
+	} else if (role == Qt::DisplayRole) {
+		return stringList()[index.row()];
+	}
+	return QVariant();
+}
+
+Qt::ItemFlags TagFilterModel::flags(const QModelIndex &index) const
+{
+	return QStringListModel::flags(index) | Qt::ItemIsUserCheckable;
+}
+
+void TagFilterModel::repopulate()
+{
+	if (g_tag_list == NULL)
+		return;
+	QStringList list;
+	struct tag_entry *current_tag_entry = g_tag_list->next;
+	while (current_tag_entry != NULL) {
+		list.append(QString(current_tag_entry->tag->name));
+		current_tag_entry = current_tag_entry->next;
+	}
+	setStringList(list);
+	delete[] checkState;
+	checkState = new bool[list.count()];
+	memset(checkState, false, list.count());
+}
+
+bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+	if(role == Qt::CheckStateRole){
+		checkState[index.row()] = value.toBool();
+		return true;
+	}
+	return false;
+}
diff --git a/qt-ui/models.h b/qt-ui/models.h
index c4a3a07..c54a765 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -417,4 +417,18 @@ private:
 
 	QStringList languages;
 };
+
+class TagFilterModel : public QStringListModel {
+	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;
+public slots:
+	void repopulate();
+private:
+	explicit TagFilterModel(QObject *parent = 0);
+	bool *checkState;
+};
 #endif // MODELS_H
diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
index e9bfc3c..2f762ba 100644
--- a/qt-ui/simplewidgets.cpp
+++ b/qt-ui/simplewidgets.cpp
@@ -7,6 +7,7 @@
 #include <QFileDialog>
 #include <QShortcut>
 #include <QCalendarWidget>
+#include <QSortFilterProxyModel>
 #include "exif.h"
 #include "dive.h"
 #include "file.h"
@@ -459,4 +460,8 @@ void DiveComponentSelection::buttonClicked(QAbstractButton *button)
 TagFilter::TagFilter(QWidget *parent): QWidget(parent)
 {
 	ui.setupUi(this);
+	QSortFilterProxyModel *filter = new QSortFilterProxyModel();
+	filter->setSourceModel(TagFilterModel::instance());
+	connect(ui.filterTag, SIGNAL(textChanged(QString)), filter, SLOT(setFilterFixedString(QString)));
+	ui.tagView->setModel(filter);
 }
-- 
2.1.0

From c5e29ea1598ed10fdc50ca2aad113e06a75e4227 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 16:18:37 -0300
Subject: [PATCH 07/12] Create the sorting method.

This method should remove a row on the dive list model
visualization if none of the tags that it have are marked
as 'visible'.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/models.cpp | 25 +++++++++++++++++++++++++
 qt-ui/models.h   | 11 +++++++++--
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index b227027..def258a 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -2150,3 +2150,28 @@ bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, in
 	}
 	return false;
 }
+
+TagFilterSortModel::TagFilterSortModel(QObject *parent): QSortFilterProxyModel(parent)
+{
+
+}
+
+bool TagFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
+{
+	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)
+		return false; // it's a trip.
+
+	// Checked means 'Show', Unchecked means 'Hide'.
+	struct tag_entry *head = d->tag_list;
+
+	while(head) {
+		QString tagName(head->tag->name);
+		int index = TagFilterModel::instance()->stringList().indexOf(tagName);
+		if (TagFilterModel::instance()->checkState[index] == false )
+			return true;
+	}
+	return false;
+}
diff --git a/qt-ui/models.h b/qt-ui/models.h
index c54a765..446ae90 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -11,6 +11,7 @@
 #include <QCoreApplication>
 #include <QStringList>
 #include <QStringListModel>
+#include <QSortFilterProxyModel>
 
 #include "../dive.h"
 #include "../divelist.h"
@@ -217,7 +218,6 @@ struct TripItem;
 
 class TreeModel : public QAbstractItemModel {
 	Q_OBJECT
-
 public:
 	TreeModel(QObject *parent = 0);
 	virtual ~TreeModel();
@@ -425,10 +425,17 @@ public:
 	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;
+	bool *checkState;
 public slots:
 	void repopulate();
 private:
 	explicit TagFilterModel(QObject *parent = 0);
-	bool *checkState;
+};
+
+class TagFilterSortModel : public QSortFilterProxyModel {
+	Q_OBJECT
+public:
+	TagFilterSortModel(QObject *parent = 0);
+	virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
 };
 #endif // MODELS_H
-- 
2.1.0

From 2b8a576b70ca4efb711baedfcae8663535adb052 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 17:15:37 -0300
Subject: [PATCH 08/12] Correctly filter dives. (trips are always shown)

This patch correctly filter dives based on tags, but it will
also keep showing all the empty trips.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/divelistview.cpp |  6 +++---
 qt-ui/models.cpp       | 18 ++++++++++++++----
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
index d7b48ce..273517f 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));
-	QSortFilterProxyModel *model = new QSortFilterProxyModel(this);
+	TagFilterSortModel *model = new TagFilterSortModel(this);
 	model->setSortRole(DiveTripModel::SORT_ROLE);
 	model->setFilterKeyColumn(-1); // filter all columns
 	model->setFilterCaseSensitivity(Qt::CaseInsensitive);
@@ -57,8 +57,8 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
 
 	searchBox.installEventFilter(this);
 	searchBox.hide();
-	connect(showSearchBox, SIGNAL(triggered(bool)), this, SLOT(showSearchEdit()));
-	connect(&searchBox, SIGNAL(textChanged(QString)), model, SLOT(setFilterFixedString(QString)));
+//	connect(showSearchBox, SIGNAL(triggered(bool)), this, SLOT(showSearchEdit()));
+//	connect(&searchBox, SIGNAL(textChanged(QString)), model, SLOT(setFilterFixedString(QString)));
 }
 
 //                                #  Date  Rtg Dpth  Dur  Tmp Wght Suit  Cyl  Gas  SAC  OTU  CNS  Loc
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index def258a..f1f1f63 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -2146,6 +2146,7 @@ bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, in
 {
 	if(role == Qt::CheckStateRole){
 		checkState[index.row()] = value.toBool();
+		dataChanged(index,index);
 		return true;
 	}
 	return false;
@@ -2153,7 +2154,7 @@ bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, in
 
 TagFilterSortModel::TagFilterSortModel(QObject *parent): QSortFilterProxyModel(parent)
 {
-
+	connect(TagFilterModel::instance(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(invalidate()));
 }
 
 bool TagFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
@@ -2162,16 +2163,25 @@ bool TagFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &sou
 	QVariant diveVariant = sourceModel()->data(index0, DiveTripModel::DIVE_ROLE);
 	struct dive* d = (struct dive* ) diveVariant.value<void*>();
 	if(!d)
-		return false; // it's a trip.
-
+		return false;
 	// Checked means 'Show', Unchecked means 'Hide'.
 	struct tag_entry *head = d->tag_list;
 
+	if (!head){ // doesn't have tags, only show if no tags are selected.
+		for(int i = 0; i < TagFilterModel::instance()->stringList().count(); i++){
+			if (TagFilterModel::instance()->checkState[i])
+				return false;
+		}
+		return true;
+	}
+
+	// have at least one tag.
 	while(head) {
 		QString tagName(head->tag->name);
 		int index = TagFilterModel::instance()->stringList().indexOf(tagName);
-		if (TagFilterModel::instance()->checkState[index] == false )
+		if (TagFilterModel::instance()->checkState[index])
 			return true;
+		head = head->next;
 	}
 	return false;
 }
-- 
2.1.0

From f4bd5c506336ce46cbd813e875e74dbfd54aaaa3 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 17:31:09 -0300
Subject: [PATCH 09/12] Implement trip-filtering.

Trips will be filtered if it doesn't find any tags for
dives.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/models.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index f1f1f63..e170c4d 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -2162,8 +2162,14 @@ bool TagFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &sou
 	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)
+
+	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))
+				return true;
+		}
 		return false;
+	}
 	// Checked means 'Show', Unchecked means 'Hide'.
 	struct tag_entry *head = d->tag_list;
 
-- 
2.1.0

From b01ca48bd4301b5bff9dc98a20e7299eda178b00 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 17:47:35 -0300
Subject: [PATCH 10/12] Better filtering of dives with no tags.

New rules for them, a new item on the model with the text
"Empty Tags" should be marked if the user wants it to be
displayed.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/models.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index e170c4d..8b52e65 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -2136,10 +2136,12 @@ void TagFilterModel::repopulate()
 		list.append(QString(current_tag_entry->tag->name));
 		current_tag_entry = current_tag_entry->next;
 	}
+	list << tr("Empty Tags");
 	setStringList(list);
 	delete[] checkState;
 	checkState = new bool[list.count()];
 	memset(checkState, false, list.count());
+	checkState[list.count()-1] = true;
 }
 
 bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, int role)
@@ -2173,18 +2175,16 @@ bool TagFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &sou
 	// Checked means 'Show', Unchecked means 'Hide'.
 	struct tag_entry *head = d->tag_list;
 
-	if (!head){ // doesn't have tags, only show if no tags are selected.
-		for(int i = 0; i < TagFilterModel::instance()->stringList().count(); i++){
-			if (TagFilterModel::instance()->checkState[i])
-				return false;
-		}
-		return true;
+	if (!head){ // last tag means "Show empty tags";
+		return TagFilterModel::instance()->checkState[TagFilterModel::instance()->rowCount()-1];
 	}
 
 	// have at least one tag.
+	QStringList tagList = TagFilterModel::instance()->stringList();
+	tagList.removeLast(); // remove the "Show Empty Tags";
 	while(head) {
 		QString tagName(head->tag->name);
-		int index = TagFilterModel::instance()->stringList().indexOf(tagName);
+		int index = tagList.indexOf(tagName);
 		if (TagFilterModel::instance()->checkState[index])
 			return true;
 		head = head->next;
-- 
2.1.0

From 05d8ad198d80337c1796c41c904e1cb0e9340b90 Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 17:52:29 -0300
Subject: [PATCH 11/12] Show everything by default.

We should show all dives by default.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/models.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index 8b52e65..3f6bdaa 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -2140,7 +2140,7 @@ void TagFilterModel::repopulate()
 	setStringList(list);
 	delete[] checkState;
 	checkState = new bool[list.count()];
-	memset(checkState, false, list.count());
+	memset(checkState, true, list.count());
 	checkState[list.count()-1] = true;
 }
 
-- 
2.1.0

From b2ddc7a83cd626d313baef1b36684f767a065bec Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <[email protected]>
Date: Wed, 17 Sep 2014 17:58:50 -0300
Subject: [PATCH 12/12] Unused signature removed.

Signed-off-by: Tomaz Canabrava <[email protected]>
---
 qt-ui/models.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/qt-ui/models.h b/qt-ui/models.h
index 446ae90..3e156a8 100644
--- a/qt-ui/models.h
+++ b/qt-ui/models.h
@@ -382,7 +382,6 @@ class ProfilePrintModel : public QAbstractTableModel {
 private:
 	int diveId;
 	double fontSize;
-	QString truncateString(char *str, const int maxlen) const;
 
 public:
 	ProfilePrintModel(QObject *parent = 0);
-- 
2.1.0

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

Reply via email to