Plus some bugfixes / cleanups.
From babec5122ddc81facbfe7471dd27b446ab8b2b66 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 16:31:03 -0200 Subject: [PATCH 01/16] Move the filters code to it's own file.
We already have a bunch of filters, let's pack them together Signed-off-by: Tomaz Canabrava <[email protected]> --- CMakeLists.txt | 1 + qt-ui/divelistview.cpp | 1 + qt-ui/filtermodels.cpp | 470 ++++++++++++++++++++++++++++++++++++++++++++++++ qt-ui/filtermodels.h | 87 +++++++++ qt-ui/mainwindow.cpp | 1 + qt-ui/models.cpp | 465 ----------------------------------------------- qt-ui/models.h | 80 --------- qt-ui/simplewidgets.cpp | 1 + subsurface.pro | 6 +- 9 files changed, 565 insertions(+), 547 deletions(-) create mode 100644 qt-ui/filtermodels.cpp create mode 100644 qt-ui/filtermodels.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 868ad4f..c93b5fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,7 @@ SET(SUBSURFACE_INTERFACE qt-ui/divepicturewidget.cpp qt-ui/usersurvey.cpp qt-ui/configuredivecomputerdialog.cpp + qt-ui/filtermodels.cpp ) #the profile widget diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp index f250e90..c5ffaaa 100644 --- a/qt-ui/divelistview.cpp +++ b/qt-ui/divelistview.cpp @@ -6,6 +6,7 @@ */ #include "divelistview.h" #include "models.h" +#include "filtermodels.h" #include "modeldelegates.h" #include "mainwindow.h" #include "subsurfacewebservices.h" diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp new file mode 100644 index 0000000..3dabc80 --- /dev/null +++ b/qt-ui/filtermodels.cpp @@ -0,0 +1,470 @@ +#include "filtermodels.h" +#include "dive.h" +#include "models.h" +#include "mainwindow.h" +#include "display.h" + +TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) +{ +} + +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) { + QString tag = stringList()[index.row()]; + int count = count_dives_with_tag(tag.toUtf8().data()); + return tag + QString(" (%1)").arg(count); + } + 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; + } + qSort(list); + list << tr("Empty Tags"); + setStringList(list); + delete[] checkState; + checkState = new bool[list.count()]; + memset(checkState, false, list.count()); + checkState[list.count() - 1] = false; + anyChecked = false; +} + +bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (role == Qt::CheckStateRole) { + checkState[index.row()] = value.toBool(); + anyChecked = false; + for (int i = 0; i < rowCount(); i++) { + if (checkState[i] == true) { + anyChecked = true; + break; + } + } + dataChanged(index, index); + return true; + } + return false; +} + +bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const +{ + // If there's nothing checked, this should show everything + if (!anyChecked) { + return true; + } + 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 (filterRow(i, index0, sourceModel)) + return true; + } + return false; + } + // Checked means 'Show', Unchecked means 'Hide'. + struct tag_entry *head = d->tag_list; + + if (!head) { // last tag means "Show empty tags"; + if (rowCount() > 0) + return checkState[rowCount() - 1]; + else + return true; + } + + // have at least one tag. + 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 (checkState[index]) + return true; + head = head->next; + } + } + return false; +} + +bool TagFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const +{ + // If there's nothing checked, this should show everything + if (!anyChecked) { + return true; + } + + 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 *>(); + + bool show = doFilter(d, index0, sourceModel); + filter_dive(d, show); + return show; +} + +BuddyFilterModel::BuddyFilterModel(QObject *parent) : QStringListModel(parent) +{ +} + +BuddyFilterModel *BuddyFilterModel::instance() +{ + static BuddyFilterModel *self = new BuddyFilterModel(); + return self; +} + +bool BuddyFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const +{ + // If there's nothing checked, this should show everything + if (!anyChecked) { + return true; + } + 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 (filterRow(i, index0, sourceModel)) + return true; + } + return false; + } + + // Checked means 'Show', Unchecked means 'Hide'. + QString diveBuddy(d->buddy); + QString divemaster(d->divemaster); + // only show empty buddie dives if the user checked that. + if (diveBuddy.isEmpty() && divemaster.isEmpty()) { + if (rowCount() > 0) + return checkState[rowCount() - 1]; + else + return true; + } + + // have at least one buddy + QStringList buddyList = stringList(); + if (!buddyList.isEmpty()) { + buddyList.removeLast(); // remove the "Show Empty Tags"; + for (int i = 0; i < rowCount(); i++) { + if (checkState[i] && (diveBuddy.indexOf(stringList()[i]) != -1 || divemaster.indexOf(stringList()[i]) != -1)) { + return true; + } + } + } + return false; +} + +bool BuddyFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const +{ + // If there's nothing checked, this should show everything + if (!anyChecked) { + return true; + } + + 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 *>(); + + return doFilter(d, index0, sourceModel); +} + +Qt::ItemFlags BuddyFilterModel::flags(const QModelIndex &index) const +{ + return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; +} + +void BuddyFilterModel::repopulate() +{ + QStringList list; + struct dive *dive; + int i = 0; + for_each_dive (i, dive) { + QString persons = QString(dive->buddy) + "," + QString(dive->divemaster); + Q_FOREACH(const QString& person, persons.split(',', QString::SkipEmptyParts)){ + // Remove any leading spaces + if (!list.contains(person.trimmed())) { + list.append(person.trimmed()); + } + } + } + qSort(list); + list << tr("No buddies"); + setStringList(list); + delete[] checkState; + checkState = new bool[list.count()]; + memset(checkState, false, list.count()); + checkState[list.count() - 1] = false; + anyChecked = false; +} + +QVariant BuddyFilterModel::data(const QModelIndex &index, int role) const +{ + if (role == Qt::CheckStateRole) { + return checkState[index.row()] ? Qt::Checked : Qt::Unchecked; + } else if (role == Qt::DisplayRole) { + QString person = stringList()[index.row()]; + int count = count_dives_with_person(person.toUtf8().data()); + return person + QString(" (%1)").arg(count); + } + return QVariant(); +} + + +bool BuddyFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (role == Qt::CheckStateRole) { + checkState[index.row()] = value.toBool(); + anyChecked = false; + for (int i = 0; i < rowCount(); i++) { + if (checkState[i] == true) { + anyChecked = true; + break; + } + } + dataChanged(index, index); + return true; + } + return false; +} + +LocationFilterModel::LocationFilterModel(QObject *parent) : QStringListModel(parent) +{ +} + +QVariant LocationFilterModel::data(const QModelIndex &index, int role) const +{ + if (role == Qt::CheckStateRole) { + return checkState[index.row()] ? Qt::Checked : Qt::Unchecked; + } else if (role == Qt::DisplayRole) { + QString location = stringList()[index.row()]; + int count = count_dives_with_location(location.toUtf8().data()); + return location + QString(" (%1)").arg(count); + } + return QVariant(); +} + +bool LocationFilterModel::doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const +{ + if (!anyChecked) { + return true; + } + + 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 (filterRow(i, index0, sourceModel)) + return true; + } + return false; + } + + // Checked means 'Show', Unchecked means 'Hide'. + QString location(d->location); + // only show empty location dives if the user checked that. + if (location.isEmpty()) { + if (rowCount() > 0) + return checkState[rowCount() - 1]; + else + return true; + } + + // there is a location selected + QStringList locationList = stringList(); + if (!locationList.isEmpty()) { + locationList.removeLast(); // remove the "Show Empty Tags"; + for (int i = 0; i < rowCount(); i++) { + if (checkState[i] && (location.indexOf(stringList()[i]) != -1)) { + return true; + } + } + } + return false; +} + +bool LocationFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const +{ + + // If there's nothing checked, this should show everything + if (!anyChecked) { + return true; + } + + 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 *>(); + + return doFilter(d, index0, sourceModel); +} + +Qt::ItemFlags LocationFilterModel::flags(const QModelIndex &index) const +{ + return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; +} + +LocationFilterModel *LocationFilterModel::instance() +{ + static LocationFilterModel *self = new LocationFilterModel(); + return self; +} + +void LocationFilterModel::repopulate() +{ + QStringList list; + struct dive *dive; + int i = 0; + for_each_dive (i, dive) { + QString location(dive->location); + if (!location.isEmpty() && !list.contains(location)) { + list.append(location); + } + } + qSort(list); + list << tr("No location set"); + setStringList(list); + delete[] checkState; + checkState = new bool[list.count()]; + memset(checkState, false, list.count()); + checkState[list.count() - 1] = false; + anyChecked = false; +} + +bool LocationFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (role == Qt::CheckStateRole) { + checkState[index.row()] = value.toBool(); + anyChecked = false; + for (int i = 0; i < rowCount(); i++) { + if (checkState[i] == true) { + anyChecked = true; + break; + } + } + dataChanged(index, index); + return true; + } + return false; +} + +MultiFilterSortModel *MultiFilterSortModel::instance() +{ + static MultiFilterSortModel *self = new MultiFilterSortModel(); + return self; +} + +MultiFilterSortModel::MultiFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent), justCleared(false) +{ +} + +bool MultiFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + if (justCleared || models.isEmpty()) + return true; + + bool shouldShow = true; + 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 *>(); + + Q_FOREACH (MultiFilterInterface *model, models) { + if (!model->doFilter(d, index0, sourceModel())) + shouldShow = false; + } + // if it's a dive, mark it accordingly + filter_dive(d, shouldShow); + return shouldShow; +} + +void MultiFilterSortModel::myInvalidate() +{ + int i; + struct dive *d; + DiveListView *dlv = MainWindow::instance()->dive_list(); + + invalidate(); + // first make sure the trips are no longer shown as selected + // (but without updating the selection state of the dives... this just cleans + // up an oddity in the filter handling) + // TODO: This should go internally to DiveList, to be triggered after a filter is due. + dlv->clearTripSelection(); + + // if we have no more selected dives, clean up the display - this later triggers us + // to pick one of the dives that are shown in the list as selected dive which is the + // natural behavior + if (amount_selected == 0) { + MainWindow::instance()->cleanUpEmpty(); + } else { + // otherwise find the dives that should still be selected (the filter above unselected any + // dive that's no longer visible) and select them again + QList<int>curSelectedDives; + for_each_dive (i, d) { + if(d->selected) + curSelectedDives.append(get_divenr(d)); + } + dlv->selectDives(curSelectedDives); + } +} + +void MultiFilterSortModel::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 MultiFilterSortModel::removeFilterModel(MultiFilterInterface *model) +{ + QAbstractItemModel *itemModel = dynamic_cast<QAbstractItemModel *>(model); + Q_ASSERT(itemModel); + models.removeAll(model); + disconnect(itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(myInvalidate())); +} + +void MultiFilterSortModel::clearFilter() +{ + justCleared = true; + Q_FOREACH(MultiFilterInterface *iface, models){ + iface->clearFilter(); + } + justCleared = false; + myInvalidate(); +} + +void BuddyFilterModel::clearFilter() +{ + memset(checkState, false, rowCount()); + checkState[rowCount() - 1] = false; + anyChecked = false; + emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); +} + +void LocationFilterModel::clearFilter() +{ + memset(checkState, false, rowCount()); + checkState[rowCount() - 1] = false; + anyChecked = false; + emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); +} + +void TagFilterModel::clearFilter() +{ + memset(checkState, false, rowCount()); + checkState[rowCount() - 1] = false; + anyChecked = false; + emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); +} \ No newline at end of file diff --git a/qt-ui/filtermodels.h b/qt-ui/filtermodels.h new file mode 100644 index 0000000..353e9d0 --- /dev/null +++ b/qt-ui/filtermodels.h @@ -0,0 +1,87 @@ +#ifndef FILTERMODELS_H +#define FILTERMODELS_H + +#include <QStringListModel> +#include <QSortFilterProxyModel> + +class MultiFilterInterface { +public: + MultiFilterInterface() : checkState(NULL){}; + virtual bool filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const = 0; + virtual bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const = 0; + virtual void clearFilter() = 0; + bool *checkState; + bool anyChecked; +}; + +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 doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const; + void clearFilter(); +public +slots: + void repopulate(); + +private: + explicit TagFilterModel(QObject *parent = 0); +}; + +class BuddyFilterModel : public QStringListModel, public MultiFilterInterface{ + Q_OBJECT +public: + static BuddyFilterModel *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 doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const; + void clearFilter(); +public +slots: + void repopulate(); + +private: + explicit BuddyFilterModel(QObject *parent = 0); +}; + +class LocationFilterModel : public QStringListModel, public MultiFilterInterface{ + Q_OBJECT +public: + static LocationFilterModel *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 doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const; + void clearFilter(); +public +slots: + void repopulate(); + +private: + explicit LocationFilterModel(QObject *parent = 0); +}; + +class MultiFilterSortModel : public QSortFilterProxyModel { + Q_OBJECT +public: + static MultiFilterSortModel *instance(); + virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + void addFilterModel(MultiFilterInterface *model); + void removeFilterModel(MultiFilterInterface *model); +public slots: + void myInvalidate(); + void clearFilter(); +private: + MultiFilterSortModel(QObject *parent = 0); + QList<MultiFilterInterface*> models; + bool justCleared; +}; + +#endif \ No newline at end of file diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 858407a..9341916 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -44,6 +44,7 @@ #include "planner.h" #include "configuredivecomputerdialog.h" #include "statistics/statisticswidget.h" +#include "filtermodels.h" #ifndef NO_PRINTING #include <QPrintDialog> #include "printdialog.h" diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp index a8e5612..8bf6627 100644 --- a/qt-ui/models.cpp +++ b/qt-ui/models.cpp @@ -2252,471 +2252,6 @@ int LanguageModel::rowCount(const QModelIndex &parent) const return languages.count(); } - -TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) -{ -} - -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) { - QString tag = stringList()[index.row()]; - int count = count_dives_with_tag(tag.toUtf8().data()); - return tag + QString(" (%1)").arg(count); - } - 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; - } - qSort(list); - list << tr("Empty Tags"); - setStringList(list); - delete[] checkState; - checkState = new bool[list.count()]; - memset(checkState, false, list.count()); - checkState[list.count() - 1] = false; - anyChecked = false; -} - -bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (role == Qt::CheckStateRole) { - checkState[index.row()] = value.toBool(); - anyChecked = false; - for (int i = 0; i < rowCount(); i++) { - if (checkState[i] == true) { - anyChecked = true; - break; - } - } - dataChanged(index, index); - return true; - } - return false; -} - -bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const -{ - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - 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 (filterRow(i, index0, sourceModel)) - return true; - } - return false; - } - // Checked means 'Show', Unchecked means 'Hide'. - struct tag_entry *head = d->tag_list; - - if (!head) { // last tag means "Show empty tags"; - if (rowCount() > 0) - return checkState[rowCount() - 1]; - else - return true; - } - - // have at least one tag. - 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 (checkState[index]) - return true; - head = head->next; - } - } - return false; -} - -bool TagFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const -{ - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - - 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 *>(); - - bool show = doFilter(d, index0, sourceModel); - filter_dive(d, show); - return show; -} - -BuddyFilterModel::BuddyFilterModel(QObject *parent) : QStringListModel(parent) -{ -} - -BuddyFilterModel *BuddyFilterModel::instance() -{ - static BuddyFilterModel *self = new BuddyFilterModel(); - return self; -} - -bool BuddyFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const -{ - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - 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 (filterRow(i, index0, sourceModel)) - return true; - } - return false; - } - - // Checked means 'Show', Unchecked means 'Hide'. - QString diveBuddy(d->buddy); - QString divemaster(d->divemaster); - // only show empty buddie dives if the user checked that. - if (diveBuddy.isEmpty() && divemaster.isEmpty()) { - if (rowCount() > 0) - return checkState[rowCount() - 1]; - else - return true; - } - - // have at least one buddy - QStringList buddyList = stringList(); - if (!buddyList.isEmpty()) { - buddyList.removeLast(); // remove the "Show Empty Tags"; - for (int i = 0; i < rowCount(); i++) { - if (checkState[i] && (diveBuddy.indexOf(stringList()[i]) != -1 || divemaster.indexOf(stringList()[i]) != -1)) { - return true; - } - } - } - return false; -} - -bool BuddyFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const -{ - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - - 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 *>(); - - return doFilter(d, index0, sourceModel); -} - -Qt::ItemFlags BuddyFilterModel::flags(const QModelIndex &index) const -{ - return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; -} - -void BuddyFilterModel::repopulate() -{ - QStringList list; - struct dive *dive; - int i = 0; - for_each_dive (i, dive) { - QString persons = QString(dive->buddy) + "," + QString(dive->divemaster); - Q_FOREACH(const QString& person, persons.split(',', QString::SkipEmptyParts)){ - // Remove any leading spaces - if (!list.contains(person.trimmed())) { - list.append(person.trimmed()); - } - } - } - qSort(list); - list << tr("No buddies"); - setStringList(list); - delete[] checkState; - checkState = new bool[list.count()]; - memset(checkState, false, list.count()); - checkState[list.count() - 1] = false; - anyChecked = false; -} - -QVariant BuddyFilterModel::data(const QModelIndex &index, int role) const -{ - if (role == Qt::CheckStateRole) { - return checkState[index.row()] ? Qt::Checked : Qt::Unchecked; - } else if (role == Qt::DisplayRole) { - QString person = stringList()[index.row()]; - int count = count_dives_with_person(person.toUtf8().data()); - return person + QString(" (%1)").arg(count); - } - return QVariant(); -} - - -bool BuddyFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (role == Qt::CheckStateRole) { - checkState[index.row()] = value.toBool(); - anyChecked = false; - for (int i = 0; i < rowCount(); i++) { - if (checkState[i] == true) { - anyChecked = true; - break; - } - } - dataChanged(index, index); - return true; - } - return false; -} - -LocationFilterModel::LocationFilterModel(QObject *parent) : QStringListModel(parent) -{ -} - -QVariant LocationFilterModel::data(const QModelIndex &index, int role) const -{ - if (role == Qt::CheckStateRole) { - return checkState[index.row()] ? Qt::Checked : Qt::Unchecked; - } else if (role == Qt::DisplayRole) { - QString location = stringList()[index.row()]; - int count = count_dives_with_location(location.toUtf8().data()); - return location + QString(" (%1)").arg(count); - } - return QVariant(); -} - -bool LocationFilterModel::doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const -{ - if (!anyChecked) { - return true; - } - - 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 (filterRow(i, index0, sourceModel)) - return true; - } - return false; - } - - // Checked means 'Show', Unchecked means 'Hide'. - QString location(d->location); - // only show empty location dives if the user checked that. - if (location.isEmpty()) { - if (rowCount() > 0) - return checkState[rowCount() - 1]; - else - return true; - } - - // there is a location selected - QStringList locationList = stringList(); - if (!locationList.isEmpty()) { - locationList.removeLast(); // remove the "Show Empty Tags"; - for (int i = 0; i < rowCount(); i++) { - if (checkState[i] && (location.indexOf(stringList()[i]) != -1)) { - return true; - } - } - } - return false; -} - -bool LocationFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const -{ - - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - - 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 *>(); - - return doFilter(d, index0, sourceModel); -} - -Qt::ItemFlags LocationFilterModel::flags(const QModelIndex &index) const -{ - return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; -} - -LocationFilterModel *LocationFilterModel::instance() -{ - static LocationFilterModel *self = new LocationFilterModel(); - return self; -} - -void LocationFilterModel::repopulate() -{ - QStringList list; - struct dive *dive; - int i = 0; - for_each_dive (i, dive) { - QString location(dive->location); - if (!location.isEmpty() && !list.contains(location)) { - list.append(location); - } - } - qSort(list); - list << tr("No location set"); - setStringList(list); - delete[] checkState; - checkState = new bool[list.count()]; - memset(checkState, false, list.count()); - checkState[list.count() - 1] = false; - anyChecked = false; -} - -bool LocationFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (role == Qt::CheckStateRole) { - checkState[index.row()] = value.toBool(); - anyChecked = false; - for (int i = 0; i < rowCount(); i++) { - if (checkState[i] == true) { - anyChecked = true; - break; - } - } - dataChanged(index, index); - return true; - } - return false; -} - -MultiFilterSortModel *MultiFilterSortModel::instance() -{ - static MultiFilterSortModel *self = new MultiFilterSortModel(); - return self; -} - -MultiFilterSortModel::MultiFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent), justCleared(false) -{ -} - -bool MultiFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - if (justCleared || models.isEmpty()) - return true; - - bool shouldShow = true; - 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 *>(); - - Q_FOREACH (MultiFilterInterface *model, models) { - if (!model->doFilter(d, index0, sourceModel())) - shouldShow = false; - } - // if it's a dive, mark it accordingly - filter_dive(d, shouldShow); - return shouldShow; -} - -void MultiFilterSortModel::myInvalidate() -{ - int i; - struct dive *d; - DiveListView *dlv = MainWindow::instance()->dive_list(); - - invalidate(); - // first make sure the trips are no longer shown as selected - // (but without updating the selection state of the dives... this just cleans - // up an oddity in the filter handling) - dlv->clearTripSelection(); - - // if we have no more selected dives, clean up the display - this later triggers us - // to pick one of the dives that are shown in the list as selected dive which is the - // natural behavior - if (amount_selected == 0) { - MainWindow::instance()->cleanUpEmpty(); - } else { - // otherwise find the dives that should still be selected (the filter above unselected any - // dive that's no longer visible) and select them again - QList<int>curSelectedDives; - for_each_dive (i, d) { - if(d->selected) - curSelectedDives.append(get_divenr(d)); - } - dlv->selectDives(curSelectedDives); - } -} - -void MultiFilterSortModel::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 MultiFilterSortModel::removeFilterModel(MultiFilterInterface *model) -{ - QAbstractItemModel *itemModel = dynamic_cast<QAbstractItemModel *>(model); - Q_ASSERT(itemModel); - models.removeAll(model); - disconnect(itemModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(myInvalidate())); -} - -void MultiFilterSortModel::clearFilter() -{ - justCleared = true; - Q_FOREACH(MultiFilterInterface *iface, models){ - iface->clearFilter(); - } - justCleared = false; - myInvalidate(); -} - -void BuddyFilterModel::clearFilter() -{ - memset(checkState, false, rowCount()); - checkState[rowCount() - 1] = false; - anyChecked = false; - emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); -} - -void LocationFilterModel::clearFilter() -{ - memset(checkState, false, rowCount()); - checkState[rowCount() - 1] = false; - anyChecked = false; - emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); -} - -void TagFilterModel::clearFilter() -{ - memset(checkState, false, rowCount()); - checkState[rowCount() - 1] = false; - anyChecked = false; - emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); -} - ExtraDataModel::ExtraDataModel(QObject *parent) : CleanerTableModel(parent), rows(0) { diff --git a/qt-ui/models.h b/qt-ui/models.h index 8a2d3dc..ad0d7b7 100644 --- a/qt-ui/models.h +++ b/qt-ui/models.h @@ -438,84 +438,4 @@ private: QStringList languages; }; -class MultiFilterInterface { -public: - MultiFilterInterface() : checkState(NULL){}; - virtual bool filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const = 0; - virtual bool doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const = 0; - virtual void clearFilter() = 0; - bool *checkState; - bool anyChecked; -}; - -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 doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const; - void clearFilter(); -public -slots: - void repopulate(); - -private: - explicit TagFilterModel(QObject *parent = 0); -}; - -class BuddyFilterModel : public QStringListModel, public MultiFilterInterface{ - Q_OBJECT -public: - static BuddyFilterModel *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 doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const; - void clearFilter(); -public -slots: - void repopulate(); - -private: - explicit BuddyFilterModel(QObject *parent = 0); -}; - -class LocationFilterModel : public QStringListModel, public MultiFilterInterface{ - Q_OBJECT -public: - static LocationFilterModel *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 doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const; - void clearFilter(); -public -slots: - void repopulate(); - -private: - explicit LocationFilterModel(QObject *parent = 0); -}; - - -class MultiFilterSortModel : public QSortFilterProxyModel { - Q_OBJECT -public: - static MultiFilterSortModel *instance(); - virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; - void addFilterModel(MultiFilterInterface *model); - void removeFilterModel(MultiFilterInterface *model); -public slots: - void myInvalidate(); - void clearFilter(); -private: - MultiFilterSortModel(QObject *parent = 0); - QList<MultiFilterInterface*> models; - bool justCleared; -}; #endif // MODELS_H diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp index 850bdcf..fb9b904 100644 --- a/qt-ui/simplewidgets.cpp +++ b/qt-ui/simplewidgets.cpp @@ -1,4 +1,5 @@ #include "simplewidgets.h" +#include "filtermodels.h" #include <QLabel> #include <QProcess> diff --git a/subsurface.pro b/subsurface.pro index 07e7b29..94245fc 100644 --- a/subsurface.pro +++ b/subsurface.pro @@ -102,7 +102,8 @@ HEADERS = \ qt-ui/statistics/statisticswidget.h \ qt-ui/statistics/statisticsbar.h \ qt-ui/statistics/yearstatistics.h \ - qt-ui/diveshareexportdialog.h + qt-ui/diveshareexportdialog.h \ + qt-ui/filtermodels.h android: HEADERS -= \ qt-ui/usermanual.h \ @@ -195,7 +196,8 @@ SOURCES = \ qt-ui/statistics/yearstatistics.cpp \ qt-ui/statistics/statisticsbar.cpp \ qt-ui/statistics/monthstatistics.cpp \ - qt-ui/diveshareexportdialog.cpp + qt-ui/diveshareexportdialog.cpp \ + qt-ui/filtermodels.cpp android: SOURCES += android.cpp else: win32: SOURCES += windows.c -- 2.1.3
From 5fd2761b5b091cd39d2a552f266c2f2215f5be7b Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 16:34:55 -0200 Subject: [PATCH 02/16] Create a CREATE_INSTANCE_METHOD macro This is just to simplify the creation of more filters. more macros will be used, because I tend to abuse them. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 3dabc80..a60b2c0 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -4,14 +4,21 @@ #include "mainwindow.h" #include "display.h" -TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) -{ +#define CREATE_INSTANCE_METHOD( CLASS ) \ +CLASS *CLASS::instance() \ +{ \ + static CLASS *self = new CLASS(); \ + return self; \ } -TagFilterModel *TagFilterModel::instance() +CREATE_INSTANCE_METHOD(TagFilterModel); +CREATE_INSTANCE_METHOD(BuddyFilterModel); +CREATE_INSTANCE_METHOD(LocationFilterModel); + +#undef CREATE_INSTANCE_METHOD + +TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) { - static TagFilterModel *self = new TagFilterModel(); - return self; } QVariant TagFilterModel::data(const QModelIndex &index, int role) const @@ -126,12 +133,6 @@ BuddyFilterModel::BuddyFilterModel(QObject *parent) : QStringListModel(parent) { } -BuddyFilterModel *BuddyFilterModel::instance() -{ - static BuddyFilterModel *self = new BuddyFilterModel(); - return self; -} - bool BuddyFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { // If there's nothing checked, this should show everything @@ -316,12 +317,6 @@ Qt::ItemFlags LocationFilterModel::flags(const QModelIndex &index) const return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; } -LocationFilterModel *LocationFilterModel::instance() -{ - static LocationFilterModel *self = new LocationFilterModel(); - return self; -} - void LocationFilterModel::repopulate() { QStringList list; -- 2.1.3
From ed717e891c2b7fbf7f10fca716a1b8a39eae55d4 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 16:41:37 -0200 Subject: [PATCH 03/16] More cleanup using Macros. The setData of any filter based on a StringList with checkboxes should be the same, so let's use the same codebase for it. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 81 ++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 58 deletions(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index a60b2c0..eaf15f4 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -14,9 +14,32 @@ CLASS *CLASS::instance() \ CREATE_INSTANCE_METHOD(TagFilterModel); CREATE_INSTANCE_METHOD(BuddyFilterModel); CREATE_INSTANCE_METHOD(LocationFilterModel); +CREATE_INSTANCE_METHOD(MultiFilterSortModel); #undef CREATE_INSTANCE_METHOD +#define CREATE_MODEL_SET_DATA_METHOD( CLASS ) \ +bool CLASS::setData(const QModelIndex &index, const QVariant &value, int role) \ +{ \ + if (role == Qt::CheckStateRole) { \ + checkState[index.row()] = value.toBool(); \ + anyChecked = false; \ + for (int i = 0; i < rowCount(); i++) { \ + if (checkState[i] == true) { \ + anyChecked = true; \ + break; \ + } \ + } \ + dataChanged(index, index); \ + return true; \ + } \ + return false; \ +} + +CREATE_MODEL_SET_DATA_METHOD(TagFilterModel); +CREATE_MODEL_SET_DATA_METHOD(BuddyFilterModel); +CREATE_MODEL_SET_DATA_METHOD(LocationFilterModel); + TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) { } @@ -58,23 +81,6 @@ void TagFilterModel::repopulate() anyChecked = false; } -bool TagFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (role == Qt::CheckStateRole) { - checkState[index.row()] = value.toBool(); - anyChecked = false; - for (int i = 0; i < rowCount(); i++) { - if (checkState[i] == true) { - anyChecked = true; - break; - } - } - dataChanged(index, index); - return true; - } - return false; -} - bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { // If there's nothing checked, this should show everything @@ -226,24 +232,6 @@ QVariant BuddyFilterModel::data(const QModelIndex &index, int role) const return QVariant(); } - -bool BuddyFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (role == Qt::CheckStateRole) { - checkState[index.row()] = value.toBool(); - anyChecked = false; - for (int i = 0; i < rowCount(); i++) { - if (checkState[i] == true) { - anyChecked = true; - break; - } - } - dataChanged(index, index); - return true; - } - return false; -} - LocationFilterModel::LocationFilterModel(QObject *parent) : QStringListModel(parent) { } @@ -338,29 +326,6 @@ void LocationFilterModel::repopulate() anyChecked = false; } -bool LocationFilterModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (role == Qt::CheckStateRole) { - checkState[index.row()] = value.toBool(); - anyChecked = false; - for (int i = 0; i < rowCount(); i++) { - if (checkState[i] == true) { - anyChecked = true; - break; - } - } - dataChanged(index, index); - return true; - } - return false; -} - -MultiFilterSortModel *MultiFilterSortModel::instance() -{ - static MultiFilterSortModel *self = new MultiFilterSortModel(); - return self; -} - MultiFilterSortModel::MultiFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent), justCleared(false) { } -- 2.1.3
From 359171020adf8fdf35e22de65f599eff13fd0402 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 16:44:32 -0200 Subject: [PATCH 04/16] Clear filter is always the same for a filter based on stringlist So, let's always use the same codebasee Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index eaf15f4..8c67ca2 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -40,6 +40,23 @@ CREATE_MODEL_SET_DATA_METHOD(TagFilterModel); CREATE_MODEL_SET_DATA_METHOD(BuddyFilterModel); CREATE_MODEL_SET_DATA_METHOD(LocationFilterModel); +#undef CREATE_MODEL_SET_DATA_METHOD + +#define CREATE_CLEAR_FILTER_METHOD( CLASS ) \ +void CLASS::clearFilter() \ +{ \ + memset(checkState, false, rowCount()); \ + checkState[rowCount() - 1] = false; \ + anyChecked = false; \ + emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); \ +} + +CREATE_CLEAR_FILTER_METHOD(TagFilterModel); +CREATE_CLEAR_FILTER_METHOD(BuddyFilterModel); +CREATE_CLEAR_FILTER_METHOD(LocationFilterModel); + +#undef CREATE_CLEAR_FILTER_METHOD + TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) { } @@ -404,27 +421,3 @@ void MultiFilterSortModel::clearFilter() justCleared = false; myInvalidate(); } - -void BuddyFilterModel::clearFilter() -{ - memset(checkState, false, rowCount()); - checkState[rowCount() - 1] = false; - anyChecked = false; - emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); -} - -void LocationFilterModel::clearFilter() -{ - memset(checkState, false, rowCount()); - checkState[rowCount() - 1] = false; - anyChecked = false; - emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); -} - -void TagFilterModel::clearFilter() -{ - memset(checkState, false, rowCount()); - checkState[rowCount() - 1] = false; - anyChecked = false; - emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); -} \ No newline at end of file -- 2.1.3
From fc280737b9b013342f0af7c04dc2e78693d46f25 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 16:48:13 -0200 Subject: [PATCH 05/16] Create a common macro for flags samething as the other commits, use common code. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 8c67ca2..557460b 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -57,6 +57,16 @@ CREATE_CLEAR_FILTER_METHOD(LocationFilterModel); #undef CREATE_CLEAR_FILTER_METHOD +#define CREATE_FLAGS_METHOD( CLASS ) \ +Qt::ItemFlags CLASS::flags(const QModelIndex &index) const \ +{ \ + return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; \ +} + +CREATE_FLAGS_METHOD(TagFilterModel); +CREATE_FLAGS_METHOD(BuddyFilterModel); +CREATE_FLAGS_METHOD(LocationFilterModel); + TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) { } @@ -73,11 +83,6 @@ QVariant TagFilterModel::data(const QModelIndex &index, int role) const return QVariant(); } -Qt::ItemFlags TagFilterModel::flags(const QModelIndex &index) const -{ - return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; -} - void TagFilterModel::repopulate() { if (g_tag_list == NULL) @@ -208,11 +213,6 @@ bool BuddyFilterModel::filterRow(int source_row, const QModelIndex &source_paren return doFilter(d, index0, sourceModel); } -Qt::ItemFlags BuddyFilterModel::flags(const QModelIndex &index) const -{ - return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; -} - void BuddyFilterModel::repopulate() { QStringList list; @@ -317,11 +317,6 @@ bool LocationFilterModel::filterRow(int source_row, const QModelIndex &source_pa return doFilter(d, index0, sourceModel); } -Qt::ItemFlags LocationFilterModel::flags(const QModelIndex &index) const -{ - return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; -} - void LocationFilterModel::repopulate() { QStringList list; -- 2.1.3
From 0ee68b70f89202cef9256b25d95f3166be49a6db Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 16:51:48 -0200 Subject: [PATCH 06/16] Call all common methods once per class in an easy way. New method to simplify the creation of 4 of the common methods for each filter in an easy way. There are a few other methods that I'm also thinking on how to do this. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 557460b..71fa8f8 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -11,13 +11,6 @@ CLASS *CLASS::instance() \ return self; \ } -CREATE_INSTANCE_METHOD(TagFilterModel); -CREATE_INSTANCE_METHOD(BuddyFilterModel); -CREATE_INSTANCE_METHOD(LocationFilterModel); -CREATE_INSTANCE_METHOD(MultiFilterSortModel); - -#undef CREATE_INSTANCE_METHOD - #define CREATE_MODEL_SET_DATA_METHOD( CLASS ) \ bool CLASS::setData(const QModelIndex &index, const QVariant &value, int role) \ { \ @@ -36,12 +29,6 @@ bool CLASS::setData(const QModelIndex &index, const QVariant &value, int role) \ return false; \ } -CREATE_MODEL_SET_DATA_METHOD(TagFilterModel); -CREATE_MODEL_SET_DATA_METHOD(BuddyFilterModel); -CREATE_MODEL_SET_DATA_METHOD(LocationFilterModel); - -#undef CREATE_MODEL_SET_DATA_METHOD - #define CREATE_CLEAR_FILTER_METHOD( CLASS ) \ void CLASS::clearFilter() \ { \ @@ -51,21 +38,22 @@ void CLASS::clearFilter() \ emit dataChanged(createIndex(0,0), createIndex(rowCount()-1, 0)); \ } -CREATE_CLEAR_FILTER_METHOD(TagFilterModel); -CREATE_CLEAR_FILTER_METHOD(BuddyFilterModel); -CREATE_CLEAR_FILTER_METHOD(LocationFilterModel); - -#undef CREATE_CLEAR_FILTER_METHOD - #define CREATE_FLAGS_METHOD( CLASS ) \ Qt::ItemFlags CLASS::flags(const QModelIndex &index) const \ { \ return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; \ } -CREATE_FLAGS_METHOD(TagFilterModel); -CREATE_FLAGS_METHOD(BuddyFilterModel); -CREATE_FLAGS_METHOD(LocationFilterModel); +#define CREATE_COMMON_METHODS_FOR_FILTER( CLASS ) \ +CREATE_FLAGS_METHOD( CLASS ); \ +CREATE_CLEAR_FILTER_METHOD( CLASS ); \ +CREATE_MODEL_SET_DATA_METHOD( CLASS ); \ +CREATE_INSTANCE_METHOD( CLASS ) + +CREATE_COMMON_METHODS_FOR_FILTER(TagFilterModel); +CREATE_COMMON_METHODS_FOR_FILTER(BuddyFilterModel); +CREATE_COMMON_METHODS_FOR_FILTER(LocationFilterModel); +CREATE_INSTANCE_METHOD(MultiFilterSortModel); TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) { -- 2.1.3
From 93203e07473239fd3432f9cf1c6d564c6bd4c32f Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 16:59:00 -0200 Subject: [PATCH 07/16] Last one: Common 'data' method for StringList based Filters. This is the last of the series of Macros that I'll do to ease the creation of a QStringListModel based filter. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 60 ++++++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 71fa8f8..35f9b41 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -44,33 +44,35 @@ Qt::ItemFlags CLASS::flags(const QModelIndex &index) const \ return QStringListModel::flags(index) | Qt::ItemIsUserCheckable; \ } -#define CREATE_COMMON_METHODS_FOR_FILTER( CLASS ) \ +#define CREATE_DATA_METHOD( CLASS, COUNTER_FUNCTION ) \ +QVariant CLASS::data(const QModelIndex &index, int role) const \ +{ \ + if (role == Qt::CheckStateRole) { \ + return checkState[index.row()] ? Qt::Checked : Qt::Unchecked; \ + } else if (role == Qt::DisplayRole) { \ + QString value = stringList()[index.row()]; \ + int count = COUNTER_FUNCTION(value.toUtf8().data()); \ + return value + QString(" (%1)").arg(count); \ + } \ + return QVariant(); \ +} + +#define CREATE_COMMON_METHODS_FOR_FILTER( CLASS, COUNTER_FUNCTION ) \ CREATE_FLAGS_METHOD( CLASS ); \ CREATE_CLEAR_FILTER_METHOD( CLASS ); \ CREATE_MODEL_SET_DATA_METHOD( CLASS ); \ -CREATE_INSTANCE_METHOD( CLASS ) +CREATE_INSTANCE_METHOD( CLASS ); \ +CREATE_DATA_METHOD( CLASS, COUNTER_FUNCTION ) -CREATE_COMMON_METHODS_FOR_FILTER(TagFilterModel); -CREATE_COMMON_METHODS_FOR_FILTER(BuddyFilterModel); -CREATE_COMMON_METHODS_FOR_FILTER(LocationFilterModel); +CREATE_COMMON_METHODS_FOR_FILTER(TagFilterModel, count_dives_with_tag); +CREATE_COMMON_METHODS_FOR_FILTER(BuddyFilterModel, count_dives_with_person); +CREATE_COMMON_METHODS_FOR_FILTER(LocationFilterModel, count_dives_with_location); CREATE_INSTANCE_METHOD(MultiFilterSortModel); TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) { } -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) { - QString tag = stringList()[index.row()]; - int count = count_dives_with_tag(tag.toUtf8().data()); - return tag + QString(" (%1)").arg(count); - } - return QVariant(); -} - void TagFilterModel::repopulate() { if (g_tag_list == NULL) @@ -225,34 +227,10 @@ void BuddyFilterModel::repopulate() anyChecked = false; } -QVariant BuddyFilterModel::data(const QModelIndex &index, int role) const -{ - if (role == Qt::CheckStateRole) { - return checkState[index.row()] ? Qt::Checked : Qt::Unchecked; - } else if (role == Qt::DisplayRole) { - QString person = stringList()[index.row()]; - int count = count_dives_with_person(person.toUtf8().data()); - return person + QString(" (%1)").arg(count); - } - return QVariant(); -} - LocationFilterModel::LocationFilterModel(QObject *parent) : QStringListModel(parent) { } -QVariant LocationFilterModel::data(const QModelIndex &index, int role) const -{ - if (role == Qt::CheckStateRole) { - return checkState[index.row()] ? Qt::Checked : Qt::Unchecked; - } else if (role == Qt::DisplayRole) { - QString location = stringList()[index.row()]; - int count = count_dives_with_location(location.toUtf8().data()); - return location + QString(" (%1)").arg(count); - } - return QVariant(); -} - bool LocationFilterModel::doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { if (!anyChecked) { -- 2.1.3
From e3c01c2d324fb01ae992df86e2be49b74aef0716 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:07:05 -0200 Subject: [PATCH 08/16] Added skeleton of the Suits Filter. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 20 ++++++++++++++++++++ qt-ui/filtermodels.h | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 35f9b41..da12379 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -67,8 +67,28 @@ CREATE_DATA_METHOD( CLASS, COUNTER_FUNCTION ) CREATE_COMMON_METHODS_FOR_FILTER(TagFilterModel, count_dives_with_tag); CREATE_COMMON_METHODS_FOR_FILTER(BuddyFilterModel, count_dives_with_person); CREATE_COMMON_METHODS_FOR_FILTER(LocationFilterModel, count_dives_with_location); +CREATE_COMMON_METHODS_FOR_FILTER(SuitsFilterModel, count_dives_with_location); + CREATE_INSTANCE_METHOD(MultiFilterSortModel); +SuitsFilterModel::SuitsFilterModel(QObject *parent): QStringListModel(parent) +{ +} + +bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const +{ + return false; +} + +bool SuitsFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const +{ + return false; +} + +void SuitsFilterModel::repopulate() +{ +} + TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) { } diff --git a/qt-ui/filtermodels.h b/qt-ui/filtermodels.h index 353e9d0..3d64356 100644 --- a/qt-ui/filtermodels.h +++ b/qt-ui/filtermodels.h @@ -68,6 +68,24 @@ private: explicit LocationFilterModel(QObject *parent = 0); }; +class SuitsFilterModel : public QStringListModel, public MultiFilterInterface{ + Q_OBJECT +public: + static SuitsFilterModel *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 doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const; + void clearFilter(); +public +slots: + void repopulate(); + +private: + explicit SuitsFilterModel(QObject *parent = 0); +}; + class MultiFilterSortModel : public QSortFilterProxyModel { Q_OBJECT public: -- 2.1.3
From fffc48872573b6d315d13b0865c9912542b5fd45 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:09:54 -0200 Subject: [PATCH 09/16] Suits update method done. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index da12379..6c80ca5 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -87,6 +87,23 @@ bool SuitsFilterModel::filterRow(int source_row, const QModelIndex &source_paren void SuitsFilterModel::repopulate() { + QStringList list; + struct dive *dive; + int i = 0; + for_each_dive (i, dive) { + QString suit(dive->suit); + if (!suit.isEmpty() && !list.contains(suit)) { + list.append(suit); + } + } + qSort(list); + list << tr("No suit set"); + setStringList(list); + delete[] checkState; + checkState = new bool[list.count()]; + memset(checkState, false, list.count()); + checkState[list.count() - 1] = false; + anyChecked = false; } TagFilterModel::TagFilterModel(QObject *parent) : QStringListModel(parent) -- 2.1.3
From bf592347b2a0f82583b015e897dc356a92badf6b Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:10:33 -0200 Subject: [PATCH 10/16] Suits filterRoe method done. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 6c80ca5..4ed2948 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -82,7 +82,16 @@ bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel bool SuitsFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const { - return false; + // If there's nothing checked, this should show everything + if (!anyChecked) { + return true; + } + + 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 *>(); + + return doFilter(d, index0, sourceModel); } void SuitsFilterModel::repopulate() -- 2.1.3
From e55a07880228ff4ee4bbf7ed519ff726ede74f59 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:12:46 -0200 Subject: [PATCH 11/16] Create the doFilter for the Suits. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 4ed2948..9e3c763 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -77,6 +77,38 @@ SuitsFilterModel::SuitsFilterModel(QObject *parent): QStringListModel(parent) bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { + if (!anyChecked) { + return true; + } + + 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 (filterRow(i, index0, sourceModel)) + return true; + } + return false; + } + + // Checked means 'Show', Unchecked means 'Hide'. + QString suit(d->suit); + // only show empty suit dives if the user checked that. + if (suit.isEmpty()) { + if (rowCount() > 0) + return checkState[rowCount() - 1]; + else + return true; + } + + // there is a suit selected + QStringList suitList = stringList(); + if (!suitList.isEmpty()) { + suitList.removeLast(); // remove the "Show Empty Suits"; + for (int i = 0; i < rowCount(); i++) { + if (checkState[i] && (suit.indexOf(stringList()[i]) != -1)) { + return true; + } + } + } return false; } -- 2.1.3
From c5756eaaafd0fda8e996b8f3717c9b3b58018494 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:13:39 -0200 Subject: [PATCH 12/16] This if is already checked before. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 9e3c763..2c5ace3 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -77,10 +77,6 @@ SuitsFilterModel::SuitsFilterModel(QObject *parent): QStringListModel(parent) bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { - if (!anyChecked) { - return true; - } - 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 (filterRow(i, index0, sourceModel)) @@ -173,10 +169,6 @@ void TagFilterModel::repopulate() bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } 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 (filterRow(i, index0, sourceModel)) @@ -231,10 +223,6 @@ BuddyFilterModel::BuddyFilterModel(QObject *parent) : QStringListModel(parent) bool BuddyFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } 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 (filterRow(i, index0, sourceModel)) @@ -311,10 +299,6 @@ LocationFilterModel::LocationFilterModel(QObject *parent) : QStringListModel(par bool LocationFilterModel::doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { - if (!anyChecked) { - return true; - } - 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 (filterRow(i, index0, sourceModel)) -- 2.1.3
From 7ec76627fd7ed8d52b37e236b41496834d06386d Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:29:23 -0200 Subject: [PATCH 13/16] Uups. I removed the wrong if's before. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/filtermodels.cpp | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/qt-ui/filtermodels.cpp b/qt-ui/filtermodels.cpp index 2c5ace3..edd62cb 100644 --- a/qt-ui/filtermodels.cpp +++ b/qt-ui/filtermodels.cpp @@ -77,6 +77,10 @@ SuitsFilterModel::SuitsFilterModel(QObject *parent): QStringListModel(parent) bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { + if (!anyChecked) { + return true; + } + 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 (filterRow(i, index0, sourceModel)) @@ -110,11 +114,6 @@ bool SuitsFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel bool SuitsFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const { - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - 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 *>(); @@ -169,6 +168,10 @@ void TagFilterModel::repopulate() bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { + // If there's nothing checked, this should show everything + if (!anyChecked) { + return true; + } 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 (filterRow(i, index0, sourceModel)) @@ -203,11 +206,6 @@ bool TagFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel * bool TagFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const { - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - 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 *>(); @@ -223,6 +221,10 @@ BuddyFilterModel::BuddyFilterModel(QObject *parent) : QStringListModel(parent) bool BuddyFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { + // If there's nothing checked, this should show everything + if (!anyChecked) { + return true; + } 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 (filterRow(i, index0, sourceModel)) @@ -257,11 +259,6 @@ bool BuddyFilterModel::doFilter(dive *d, QModelIndex &index0, QAbstractItemModel bool BuddyFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const { - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - 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 *>(); @@ -299,6 +296,10 @@ LocationFilterModel::LocationFilterModel(QObject *parent) : QStringListModel(par bool LocationFilterModel::doFilter(struct dive *d, QModelIndex &index0, QAbstractItemModel *sourceModel) const { + if (!anyChecked) { + return true; + } + 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 (filterRow(i, index0, sourceModel)) @@ -332,12 +333,6 @@ bool LocationFilterModel::doFilter(struct dive *d, QModelIndex &index0, QAbstrac bool LocationFilterModel::filterRow(int source_row, const QModelIndex &source_parent, QAbstractItemModel *sourceModel) const { - - // If there's nothing checked, this should show everything - if (!anyChecked) { - return true; - } - 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 *>(); -- 2.1.3
From 659ed0aa632a6efccdf5b518589ce0d282d96e36 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:32:17 -0200 Subject: [PATCH 14/16] Suits Widget created and working. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/mainwindow.cpp | 1 + qt-ui/simplewidgets.cpp | 26 ++++++++++++++++++++++++++ qt-ui/simplewidgets.h | 11 +++++++++++ 3 files changed, 38 insertions(+) diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 9341916..66ebb61 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -185,6 +185,7 @@ void MainWindow::recreateDiveList() TagFilterModel::instance()->repopulate(); BuddyFilterModel::instance()->repopulate(); LocationFilterModel::instance()->repopulate(); + SuitsFilterModel::instance()->repopulate(); } void MainWindow::current_dive_changed(int divenr) diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp index fb9b904..161f4f1 100644 --- a/qt-ui/simplewidgets.cpp +++ b/qt-ui/simplewidgets.cpp @@ -535,6 +535,31 @@ void LocationFilter::hideEvent(QHideEvent *event) QWidget::hideEvent(event); } +SuitFilter::SuitFilter(QWidget *parent) : QWidget(parent) +{ + ui.setupUi(this); + ui.label->setText(tr("Suits: ")); +#if QT_VERSION >= 0x050000 + ui.filterInternalList->setClearButtonEnabled(true); +#endif + QSortFilterProxyModel *filter = new QSortFilterProxyModel(); + filter->setSourceModel(SuitsFilterModel::instance()); + connect(ui.filterInternalList, SIGNAL(textChanged(QString)), filter, SLOT(setFilterFixedString(QString))); + ui.filterList->setModel(filter); +} + +void SuitFilter::showEvent(QShowEvent *event) +{ + MultiFilterSortModel::instance()->addFilterModel(SuitsFilterModel::instance()); + QWidget::showEvent(event); +} + +void SuitFilter::hideEvent(QHideEvent *event) +{ + MultiFilterSortModel::instance()->removeFilterModel(SuitsFilterModel::instance()); + QWidget::hideEvent(event); +} + MultiFilter::MultiFilter(QWidget *parent) : QScrollArea(parent) { QWidget *expandedWidget = new QWidget(); @@ -575,6 +600,7 @@ MultiFilter::MultiFilter(QWidget *parent) : QScrollArea(parent) l->addWidget(tagFilter); l->addWidget(new BuddyFilter()); l->addWidget(new LocationFilter()); + l->addWidget(new SuitFilter()); l->setContentsMargins(0, 0, 0, 0); l->setSpacing(0); diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h index 385ce08..25ef654 100644 --- a/qt-ui/simplewidgets.h +++ b/qt-ui/simplewidgets.h @@ -161,6 +161,17 @@ private: Ui::FilterWidget ui; }; +class SuitFilter : public QWidget { + Q_OBJECT +public: + SuitFilter(QWidget *parent = 0); + virtual void showEvent(QShowEvent *); + virtual void hideEvent(QHideEvent *); + +private: + Ui::FilterWidget ui; +}; + class LocationFilter : public QWidget { Q_OBJECT public: -- 2.1.3
From 6f734909e2d97bee42e05e61a568b67a062d0304 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:36:49 -0200 Subject: [PATCH 15/16] Fix QString use Signed-off-by: Tomaz Canabrava <[email protected]> --- qthelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qthelper.cpp b/qthelper.cpp index 6769e8a..e165e85 100644 --- a/qthelper.cpp +++ b/qthelper.cpp @@ -308,7 +308,7 @@ extern "C" bool string_sequence_contains(const char *string_sequence, const char QString stringSequence(string_sequence); QStringList strings = stringSequence.split(",", QString::SkipEmptyParts); - Q_FOREACH (QString string, strings) { + Q_FOREACH (const QString& string, strings) { if (string.trimmed().compare(QString(text).trimmed(), Qt::CaseInsensitive) == 0) return true; } -- 2.1.3
From b0463db839aa622b32c37cfc637d3a4f34d99e0e Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Thu, 13 Nov 2014 17:37:54 -0200 Subject: [PATCH 16/16] Fix use of QString We should use references when we are not wanting to make a copy of it. Signed-off-by: Tomaz Canabrava <[email protected]> --- qthelper.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qthelper.cpp b/qthelper.cpp index e165e85..0c1c68a 100644 --- a/qthelper.cpp +++ b/qthelper.cpp @@ -324,7 +324,6 @@ void selectedDivesGasUsed(QVector<QPair<QString, int> > &gasUsedOrdered) { int i, j; struct dive *d; - QString gas; QMap<QString, int> gasUsed; for_each_dive (i, d) { if (!d->selected) @@ -337,7 +336,7 @@ void selectedDivesGasUsed(QVector<QPair<QString, int> > &gasUsedOrdered) gasUsed[gasName] += diveGases[j].mliter; } } - Q_FOREACH(gas, gasUsed.keys()) { + Q_FOREACH(const QString& gas, gasUsed.keys()) { gasUsedOrdered.append(qMakePair(gas, gasUsed[gas])); } qSort(gasUsedOrdered.begin(), gasUsedOrdered.end(), lessThan); -- 2.1.3
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
