diff options
author | Tomaz Canabrava <tcanabrava@kde.org> | 2018-10-21 18:00:02 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-12-14 01:05:18 +0800 |
commit | e0f473fcb49c8121a0a9c52bf0536049b0f342ed (patch) | |
tree | f95b2228ddfcb9926319fb236b896f24043e7846 | |
parent | 43178be1f23dca936b177b79245818e971bedde3 (diff) | |
download | subsurface-e0f473fcb49c8121a0a9c52bf0536049b0f342ed.tar.gz |
Drop old filter code
Drop tons of now-unused-code.
Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
-rw-r--r-- | desktop-widgets/CMakeLists.txt | 1 | ||||
-rw-r--r-- | desktop-widgets/command_divelist.cpp | 6 | ||||
-rw-r--r-- | desktop-widgets/divelistview.cpp | 1 | ||||
-rw-r--r-- | desktop-widgets/divelogimportdialog.cpp | 1 | ||||
-rw-r--r-- | desktop-widgets/filterwidget.ui | 140 | ||||
-rw-r--r-- | desktop-widgets/locationinformation.cpp | 2 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 7 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.h | 1 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.ui | 60 | ||||
-rw-r--r-- | desktop-widgets/modeldelegates.cpp | 5 | ||||
-rw-r--r-- | desktop-widgets/printdialog.cpp | 1 | ||||
-rw-r--r-- | desktop-widgets/simplewidgets.cpp | 111 | ||||
-rw-r--r-- | desktop-widgets/simplewidgets.h | 54 | ||||
-rw-r--r-- | desktop-widgets/tab-widgets/maintab.cpp | 2 | ||||
-rw-r--r-- | qt-models/filtermodels.cpp | 588 | ||||
-rw-r--r-- | qt-models/filtermodels.h | 109 |
16 files changed, 44 insertions, 1045 deletions
diff --git a/desktop-widgets/CMakeLists.txt b/desktop-widgets/CMakeLists.txt index 149ba32c0..629c0507e 100644 --- a/desktop-widgets/CMakeLists.txt +++ b/desktop-widgets/CMakeLists.txt @@ -33,7 +33,6 @@ set (SUBSURFACE_UI diveplanner.ui diveshareexportdialog.ui downloadfromdivecomputer.ui - filterwidget.ui filterwidget2.ui findmovedimagesdialog.ui listfilter.ui diff --git a/desktop-widgets/command_divelist.cpp b/desktop-widgets/command_divelist.cpp index 91adb3725..5fb52a809 100644 --- a/desktop-widgets/command_divelist.cpp +++ b/desktop-widgets/command_divelist.cpp @@ -110,11 +110,6 @@ std::vector<DiveToAdd> DiveListBase::removeDives(std::vector<dive *> &divesToDel std::vector<DiveToAdd> res; res.reserve(divesToDelete.size()); - // First, tell the filters that dives are removed. This could - // be done later using the emitted signals, but we do this here - // for symmetry with addDives() - MultiFilterSortModel::instance()->divesDeleted(QVector<dive *>::fromStdVector(divesToDelete)); - for (dive *d: divesToDelete) res.push_back(removeDive(d)); divesToDelete.clear(); @@ -154,7 +149,6 @@ std::vector<dive *> DiveListBase::addDives(std::vector<DiveToAdd> &divesToAdd) QVector<dive *> divesForFilter; for (const DiveToAdd &entry: divesToAdd) divesForFilter.push_back(entry.dive.get()); - MultiFilterSortModel::instance()->divesAdded(divesForFilter); // At the end of the function, to send the proper dives-added signals, // we the the list of added trips. Create this list now. diff --git a/desktop-widgets/divelistview.cpp b/desktop-widgets/divelistview.cpp index 9a9330473..c340b556b 100644 --- a/desktop-widgets/divelistview.cpp +++ b/desktop-widgets/divelistview.cpp @@ -25,6 +25,7 @@ #include "qt-models/divepicturemodel.h" #include "core/metrics.h" #include "core/subsurface-qt/DiveListNotifier.h" +#include "desktop-widgets/simplewidgets.h" DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), currentLayout(DiveTripModel::TREE), dontEmitDiveChangedSignal(false), selectionSaved(false), diff --git a/desktop-widgets/divelogimportdialog.cpp b/desktop-widgets/divelogimportdialog.cpp index 668b230a8..f4f9311ff 100644 --- a/desktop-widgets/divelogimportdialog.cpp +++ b/desktop-widgets/divelogimportdialog.cpp @@ -9,6 +9,7 @@ #include <QMimeData> #include <QRegExp> #include <QUndoStack> +#include <QPainter> #include "core/qthelper.h" #include "core/import-csv.h" diff --git a/desktop-widgets/filterwidget.ui b/desktop-widgets/filterwidget.ui deleted file mode 100644 index 6a8b8e863..000000000 --- a/desktop-widgets/filterwidget.ui +++ /dev/null @@ -1,140 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>FilterWidget</class> - <widget class="QWidget" name="FilterWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>594</width> - <height>362</height> - </rect> - </property> - <property name="windowTitle"> - <string/> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="spacing"> - <number>0</number> - </property> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <property name="spacing"> - <number>0</number> - </property> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="filterText"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QToolButton" name="clear"> - <property name="toolTip"> - <string>Reset filters</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:edit-clear-icon</normaloff>:edit-clear-icon</iconset> - </property> - <property name="autoRaise"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="maximize"> - <property name="toolTip"> - <string>Show/hide filters</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:hide-icon</normaloff>:hide-icon</iconset> - </property> - <property name="autoRaise"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="close"> - <property name="toolTip"> - <string>Close and reset filters</string> - </property> - <property name="icon"> - <iconset> - <normaloff>:filter-close</normaloff>:filter-close</iconset> - </property> - <property name="autoRaise"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QScrollArea" name="scrollArea"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="widgetResizable"> - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>594</width> - <height>332</height> - </rect> - </property> - </widget> - </widget> - </item> - </layout> - </widget> - <resources> - <include location="../subsurface.qrc"/> - </resources> - <connections/> -</ui> diff --git a/desktop-widgets/locationinformation.cpp b/desktop-widgets/locationinformation.cpp index 2d0807474..7356f8370 100644 --- a/desktop-widgets/locationinformation.cpp +++ b/desktop-widgets/locationinformation.cpp @@ -34,8 +34,6 @@ LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBo ui.diveSiteMessage->addAction(rejectAction); connect(ui.geoCodeButton, SIGNAL(clicked()), this, SLOT(reverseGeocode())); - connect(this, SIGNAL(nameChanged(const QString &, const QString &)), - LocationFilterModel::instance(), SLOT(changeName(const QString &, const QString &))); connect(ui.updateLocationButton, SIGNAL(clicked()), this, SLOT(updateLocationOnMap())); connect(ui.diveSiteCoordinates, SIGNAL(returnPressed()), this, SLOT(updateLocationOnMap())); ui.diveSiteCoordinates->installEventFilter(this); diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index 12c33566b..6c0b42c9d 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -54,6 +54,7 @@ #include "desktop-widgets/updatemanager.h" #include "desktop-widgets/usersurvey.h" #include "desktop-widgets/filterwidget2.h" +#include "desktop-widgets/simplewidgets.h" #include "profile-widget/profilewidget2.h" @@ -205,8 +206,6 @@ MainWindow::MainWindow() : QMainWindow(), setStateProperties("FilterDive", enabledList, enabledList, enabledList, enabledList); setApplicationState("Default"); - ui.multiFilter->hide(); - setWindowIcon(QIcon(":subsurface-icon")); if (!QIcon::hasThemeIcon("window-close")) { QIcon::setThemeName("subsurface"); @@ -497,10 +496,6 @@ void MainWindow::refreshDisplay(bool doRecreateDiveList) void MainWindow::recreateDiveList() { diveList->reload(); - TagFilterModel::instance()->repopulate(); - BuddyFilterModel::instance()->repopulate(); - LocationFilterModel::instance()->repopulate(); - SuitsFilterModel::instance()->repopulate(); MultiFilterSortModel::instance()->myInvalidate(); } diff --git a/desktop-widgets/mainwindow.h b/desktop-widgets/mainwindow.h index 03f87ab7b..a18738de4 100644 --- a/desktop-widgets/mainwindow.h +++ b/desktop-widgets/mainwindow.h @@ -18,6 +18,7 @@ #include "ui_plannerDetails.h" #include "desktop-widgets/notificationwidget.h" #include "core/gpslocation.h" +#include "core/dive.h" #define NUM_RECENT_FILES 4 diff --git a/desktop-widgets/mainwindow.ui b/desktop-widgets/mainwindow.ui index 1263b4093..2dcd3e8a6 100644 --- a/desktop-widgets/mainwindow.ui +++ b/desktop-widgets/mainwindow.ui @@ -15,12 +15,18 @@ <property name="spacing"> <number>0</number> </property> - <property name="margin"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> <number>0</number> </property> - <item> - <widget class="MultiFilter" name="multiFilter" native="true"/> - </item> <item> <widget class="QSplitter" name="mainSplitter"> <property name="orientation"> @@ -53,7 +59,7 @@ <x>0</x> <y>0</y> <width>861</width> - <height>23</height> + <height>29</height> </rect> </property> <widget class="QMenu" name="menuFile"> @@ -133,7 +139,7 @@ </widget> <widget class="QMenu" name="menuShare_on"> <property name="title"> - <string>Share on</string> + <string>Share o&n</string> </property> <addaction name="separator"/> </widget> @@ -438,7 +444,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:pp-o2-icon</normaloff>:pp-o2-icon</iconset> </property> <property name="text"> @@ -450,7 +456,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:pp-n2-icon</normaloff>:pp-n2-icon</iconset> </property> <property name="text"> @@ -462,7 +468,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:pp-he-icon</normaloff>:pp-he-icon</iconset> </property> <property name="text"> @@ -474,7 +480,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:ceiling-dc-icon</normaloff>:ceiling-dc-icon</iconset> </property> <property name="text"> @@ -486,7 +492,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:ceiling-calculated-icon</normaloff>:ceiling-calculated-icon</iconset> </property> <property name="text"> @@ -498,7 +504,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:ceiling-tissues-icon</normaloff>:ceiling-tissues-icon</iconset> </property> <property name="text"> @@ -510,7 +516,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:ceiling-increments-icon</normaloff>:ceiling-increments-icon</iconset> </property> <property name="text"> @@ -522,7 +528,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:rate-heart-icon</normaloff>:rate-heart-icon</iconset> </property> <property name="text"> @@ -534,7 +540,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:depth-mod-icon</normaloff>:depth-mod-icon</iconset> </property> <property name="text"> @@ -546,7 +552,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:depth-ead-icon</normaloff>:depth-ead-icon</iconset> </property> <property name="text"> @@ -558,7 +564,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:depth-ndl-icon</normaloff>:depth-ndl-icon</iconset> </property> <property name="text"> @@ -570,7 +576,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:rate-sac-icon</normaloff>:rate-sac-icon</iconset> </property> <property name="text"> @@ -582,7 +588,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:ruler-icon</normaloff>:ruler-icon</iconset> </property> <property name="text"> @@ -594,7 +600,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:scale-graph-icon</normaloff>:scale-graph-icon</iconset> </property> <property name="text"> @@ -606,7 +612,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:photo-icon</normaloff>:photo-icon</iconset> </property> <property name="text"> @@ -618,7 +624,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:gaschange-icon</normaloff>:gaschange-icon</iconset> </property> <property name="text"> @@ -641,7 +647,7 @@ <bool>true</bool> </property> <property name="icon"> - <iconset resource="../subsurface.qrc"> + <iconset> <normaloff>:heatmap-icon</normaloff>:heatmap-icon</iconset> </property> <property name="text"> @@ -704,7 +710,7 @@ <bool>true</bool> </property> <property name="text"> - <string>Cloud storage online</string> + <string>Cloud stora&ge online</string> </property> </action> </widget> @@ -715,12 +721,6 @@ <header>desktop-widgets/notificationwidget.h</header> <container>1</container> </customwidget> - <customwidget> - <class>MultiFilter</class> - <extends>QWidget</extends> - <header>desktop-widgets/simplewidgets.h</header> - <container>1</container> - </customwidget> </customwidgets> <resources> <include location="../subsurface.qrc"/> diff --git a/desktop-widgets/modeldelegates.cpp b/desktop-widgets/modeldelegates.cpp index f008f4bc2..41fe1c083 100644 --- a/desktop-widgets/modeldelegates.cpp +++ b/desktop-widgets/modeldelegates.cpp @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 + #include "desktop-widgets/modeldelegates.h" #include "core/subsurface-string.h" #include "core/gettextfromc.h" @@ -13,6 +14,7 @@ #include "qt-models/divetripmodel.h" #include "qt-models/divelocationmodel.h" #include "core/qthelper.h" +#include "desktop-widgets/simplewidgets.h" #include <QCompleter> #include <QKeyEvent> @@ -22,6 +24,9 @@ #include <QBrush> #include <QColor> #include <QAbstractProxyModel> +#include <QLineEdit> +#include <QAbstractItemView> +#include <QSpinBox> QSize DiveListDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const { diff --git a/desktop-widgets/printdialog.cpp b/desktop-widgets/printdialog.cpp index bbbade2e4..4c863fbea 100644 --- a/desktop-widgets/printdialog.cpp +++ b/desktop-widgets/printdialog.cpp @@ -10,6 +10,7 @@ #include <QShortcut> #include <QSettings> #include <QMessageBox> +#include <QDialogButtonBox> #define SETTINGS_GROUP "PrintDialog" diff --git a/desktop-widgets/simplewidgets.cpp b/desktop-widgets/simplewidgets.cpp index 8cfb63100..42569a270 100644 --- a/desktop-widgets/simplewidgets.cpp +++ b/desktop-widgets/simplewidgets.cpp @@ -493,117 +493,6 @@ void DiveComponentSelection::buttonClicked(QAbstractButton *button) } } -void FilterBase::addContextMenuEntry(const QString &s, void (FilterModelBase::*fn)()) -{ - QAction *act = new QAction(s, this); - connect(act, &QAction::triggered, model, fn); - ui.filterList->addAction(act); -} - -FilterBase::FilterBase(FilterModelBase *model_, QWidget *parent) : QWidget(parent), - model(model_) -{ - ui.setupUi(this); -#if QT_VERSION >= 0x050200 - ui.filterInternalList->setClearButtonEnabled(true); -#endif - QSortFilterProxyModel *filter = new QSortFilterProxyModel(); - filter->setSourceModel(model); - filter->setFilterCaseSensitivity(Qt::CaseInsensitive); - connect(ui.filterInternalList, SIGNAL(textChanged(QString)), filter, SLOT(setFilterFixedString(QString))); - connect(ui.notButton, &QToolButton::toggled, model, &FilterModelBase::setNegate); - ui.filterList->setModel(filter); - - addContextMenuEntry(tr("Select All"), &FilterModelBase::selectAll); - addContextMenuEntry(tr("Unselect All"), &FilterModelBase::clearFilter); - addContextMenuEntry(tr("Invert Selection"), &FilterModelBase::invertSelection); - ui.filterList->setContextMenuPolicy(Qt::ActionsContextMenu); -} - -void FilterBase::showEvent(QShowEvent *event) -{ - MultiFilterSortModel::instance()->addFilterModel(model); - QWidget::showEvent(event); -} - -void FilterBase::hideEvent(QHideEvent *event) -{ - MultiFilterSortModel::instance()->removeFilterModel(model); - QWidget::hideEvent(event); -} - -TagFilter::TagFilter(QWidget *parent) : FilterBase(TagFilterModel::instance(), parent) -{ - ui.label->setText(tr("Tags") + QStringLiteral(": ")); -} - -BuddyFilter::BuddyFilter(QWidget *parent) : FilterBase(BuddyFilterModel::instance(), parent) -{ - ui.label->setText(tr("Person") + QStringLiteral(": ")); - ui.label->setToolTip(tr("Searches for buddies and divemasters")); -} - -LocationFilter::LocationFilter(QWidget *parent) : FilterBase(LocationFilterModel::instance(), parent) -{ - ui.label->setText(tr("Location") + QStringLiteral(": ")); -} - -SuitFilter::SuitFilter(QWidget *parent) : FilterBase(SuitsFilterModel::instance(), parent) -{ - ui.label->setText(tr("Suits") + QStringLiteral(": ")); -} - -MultiFilter::MultiFilter(QWidget *parent) : QWidget(parent) -{ - ui.setupUi(this); - - QWidget *expandedWidget = new QWidget(); - QHBoxLayout *l = new QHBoxLayout(); - - TagFilter *tagFilter = new TagFilter(this); - int minimumHeight = tagFilter->ui.filterInternalList->height() + - tagFilter->ui.verticalLayout->spacing() * tagFilter->ui.verticalLayout->count(); - - QListView *dummyList = new QListView(); - QStringListModel *dummy = new QStringListModel(QStringList() << "Dummy Text"); - dummyList->setModel(dummy); - - connect(ui.close, SIGNAL(clicked(bool)), this, SLOT(closeFilter())); - connect(ui.clear, SIGNAL(clicked(bool)), MultiFilterSortModel::instance(), SLOT(clearFilter())); - connect(ui.maximize, SIGNAL(clicked(bool)), this, SLOT(adjustHeight())); - - l->addWidget(tagFilter); - l->addWidget(new BuddyFilter()); - l->addWidget(new LocationFilter()); - l->addWidget(new SuitFilter()); - l->setContentsMargins(0, 0, 0, 0); - l->setSpacing(0); - expandedWidget->setLayout(l); - - ui.scrollArea->setWidget(expandedWidget); - expandedWidget->resize(expandedWidget->width(), minimumHeight + dummyList->sizeHintForRow(0) * 5); - ui.scrollArea->setMinimumHeight(expandedWidget->height() + 5); - - connect(MultiFilterSortModel::instance(), SIGNAL(filterFinished()), this, SLOT(filterFinished())); -} - -void MultiFilter::filterFinished() -{ - ui.filterText->setText(tr("Filter shows %1 (of %2) dives").arg(MultiFilterSortModel::instance()->divesDisplayed).arg(dive_table.nr)); -} - -void MultiFilter::adjustHeight() -{ - ui.scrollArea->setVisible(!ui.scrollArea->isVisible()); -} - -void MultiFilter::closeFilter() -{ - MultiFilterSortModel::instance()->clearFilter(); - hide(); - MainWindow::instance()->setCheckedActionFilterTags(false); -} - TextHyperlinkEventFilter::TextHyperlinkEventFilter(QTextEdit *txtEdit) : QObject(txtEdit), textEdit(txtEdit), scrollView(textEdit->viewport()) diff --git a/desktop-widgets/simplewidgets.h b/desktop-widgets/simplewidgets.h index 040754a98..a814519c4 100644 --- a/desktop-widgets/simplewidgets.h +++ b/desktop-widgets/simplewidgets.h @@ -20,7 +20,6 @@ class FilterModelBase; #include "ui_urldialog.h" #include "ui_divecomponentselection.h" #include "ui_listfilter.h" -#include "ui_filterwidget.h" #include "core/exif.h" #include "core/dive.h" @@ -150,59 +149,6 @@ private: struct dive_components *what; }; -namespace Ui{ - class FilterWidget; -}; - -class MultiFilter : public QWidget { - Q_OBJECT -public -slots: - void closeFilter(); - void adjustHeight(); - void filterFinished(); - -public: - MultiFilter(QWidget *parent); - Ui::FilterWidget ui; -}; - -class FilterBase : public QWidget { - Q_OBJECT - void addContextMenuEntry(const QString &s, void (FilterModelBase::*)()); -protected: - FilterBase(FilterModelBase *model, QWidget *parent = 0); - FilterModelBase *model; - Ui::ListFilter ui; - void showEvent(QShowEvent *) override; - void hideEvent(QHideEvent *) override; - friend class MultiFilter; -}; - -class TagFilter : public FilterBase { - Q_OBJECT -public: - TagFilter(QWidget *parent = 0); -}; - -class BuddyFilter : public FilterBase { - Q_OBJECT -public: - BuddyFilter(QWidget *parent = 0); -}; - -class SuitFilter : public FilterBase { - Q_OBJECT -public: - SuitFilter(QWidget *parent = 0); -}; - -class LocationFilter : public FilterBase { - Q_OBJECT -public: - LocationFilter(QWidget *parent = 0); -}; - class TextHyperlinkEventFilter : public QObject { Q_OBJECT public: diff --git a/desktop-widgets/tab-widgets/maintab.cpp b/desktop-widgets/tab-widgets/maintab.cpp index 567e1737f..f22b7cf1e 100644 --- a/desktop-widgets/tab-widgets/maintab.cpp +++ b/desktop-widgets/tab-widgets/maintab.cpp @@ -27,6 +27,7 @@ #include "core/gettextfromc.h" #include "desktop-widgets/locationinformation.h" #include "desktop-widgets/command.h" +#include "desktop-widgets/simplewidgets.h" #include "TabDiveExtraInfo.h" #include "TabDiveInformation.h" @@ -688,7 +689,6 @@ struct dive_site *MainTab::updateDiveSite(struct dive_site *pickedDs, dive *d) QString name = ui.location->text().isEmpty() ? tr("New dive site") : ui.location->text(); pickedDs = create_dive_site(qPrintable(name), displayed_dive.when); createdNewDive = true; - LocationFilterModel::instance()->addName(name); } if (origDs) { diff --git a/qt-models/filtermodels.cpp b/qt-models/filtermodels.cpp index a6e80aa8f..31c6fe0af 100644 --- a/qt-models/filtermodels.cpp +++ b/qt-models/filtermodels.cpp @@ -15,547 +15,10 @@ #include <QDebug> #include <algorithm> -#define CREATE_INSTANCE_METHOD(CLASS) \ - CLASS *CLASS::instance() \ - { \ - static CLASS *self = new CLASS(); \ - return self; \ - } - -CREATE_INSTANCE_METHOD(TagFilterModel) -CREATE_INSTANCE_METHOD(BuddyFilterModel) -CREATE_INSTANCE_METHOD(LocationFilterModel) -CREATE_INSTANCE_METHOD(SuitsFilterModel) -CREATE_INSTANCE_METHOD(MultiFilterSortModel) - -FilterModelBase::FilterModelBase(QObject *parent) : QAbstractListModel(parent), - anyChecked(false), - negate(false) -{ -} - -// Get index of item with given name, but ignore last item, as this -// is the "Show Empty Tags" item. Return -1 for not found. -int FilterModelBase::indexOf(const QString &name) const -{ - for (int i = 0; i < rowCount() - 1; i++) { - if (name == items[i].name) - return i; - } - return -1; -} - -int FilterModelBase::findInsertionIndex(const QString &name) -{ - // Find insertion position. Note: we search only up to the last - // item, because the last item is the "Show Empty Tags" item. - // N.B: We might do a binary search using std::lower_bound() - int i; - for (i = 0; i < rowCount() - 1; i++) { - if (name < items[i].name) - return i; - } - return i; -} - -void FilterModelBase::addItem(const QString &name, bool checked, int count) -{ - int idx = findInsertionIndex(name); - beginInsertRows(QModelIndex(), idx, idx); - items.insert(items.begin() + idx, { name, checked, count }); - endInsertRows(); -} - -void FilterModelBase::changeName(const QString &oldName, const QString &newName) -{ - if (oldName.isEmpty() || newName.isEmpty() || oldName == newName) - return; - int oldIndex = indexOf(oldName); - if (oldIndex < 0) - return; - int newIndex = indexOf(newName); - - if (newIndex >= 0) { - // If there was already an entry with the new name, we are merging entries. - // Thus, if the old entry was selected, also select the new entry. - if (items[oldIndex].checked && !items[newIndex].checked) { - items[newIndex].checked = true; - dataChanged(createIndex(newIndex, 0), createIndex(newIndex, 0)); - } - // Now, delete the old item - beginRemoveRows(QModelIndex(), oldIndex, oldIndex); - items.erase(items.begin() + oldIndex); - endRemoveRows(); - } else { - // There was no entry of the same name. We might have to move the item. - newIndex = findInsertionIndex(newName); - if (oldIndex != newIndex && oldIndex + 1 != newIndex) { - beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex); - moveInVector(items, oldIndex, oldIndex + 1, newIndex); - endMoveRows(); - } - - // The item was moved, but the name still has to be modified - items[newIndex].name = newName; - dataChanged(createIndex(newIndex, 0), createIndex(newIndex, 0)); - } -} - -// Update the the items array. -// The last item is supposed to be the "Show Empty Tags" entry. -// All other items will be sorted alphabetically. Attention: the passed-in list is modified! -void FilterModelBase::updateList(QStringList &newList) -{ - // Sort list, but leave out last element by using std::prev() - if (!newList.empty()) - std::sort(newList.begin(), std::prev(newList.end())); - - beginResetModel(); - - // Keep copy of the old items array to reimport the checked state later. - // Note that by using std::move(), this is an essentially free operation: - // The data is moved from the old array to the new one and the old array - // is reset to zero size. - std::vector<Item> oldItems = std::move(items); - - // Resize the cleared array to the new size. This leaves the checked - // flag in an undefined state (since we didn't define a default constructor). - items.resize(newList.count()); - - // First, reset all checked states to false and set the names - anyChecked = false; - for (int i = 0; i < rowCount(); ++i) { - items[i].name = newList[i]; - items[i].checked = false; - } - - // Then, restore the checked state. Ignore the last item, since - // this is the "Show Empty Tags" entry. - for (int i = 0; i < (int)oldItems.size() - 1; i++) { - if (oldItems[i].checked) { - int ind = newList.indexOf(oldItems[i].name); - if (ind >= 0 && ind < newList.count() - 1) { - items[ind].checked = true; - anyChecked = true; - } - } - } - - // Reset the state of the "Show Empty Tags" entry. But be careful: - // on program startup, the old list is empty. - if (!oldItems.empty() && !items.empty() && oldItems.back().checked) { - items.back().checked = true; - anyChecked = true; - } - - // Finally, calculate and cache the counts. Ignore the last item, since - // this is the "Show Empty Tags" entry. - for (int i = 0; i < (int)newList.size() - 1; i++) - items[i].count = countDives(qPrintable(newList[i])); - - // Calculate count of "Empty Tags". - if (!items.empty()) - items.back().count = countDives(""); - - endResetModel(); -} - -// Decrease count of entry with given name. Remove if count reaches zero. -// Exception: Don't remove the "Show Empty Tags" entry. -void FilterModelBase::decreaseCount(const QString &name) -{ - if (name.isEmpty()) { - // Decrease the "Show Empty Tags" entry. Keep it even if count reaches 0. - if (items.empty() || items.back().count <= 0) - return; // Shouldn't happen! - --items.back().count; - int idx = items.size() - 1; - dataChanged(createIndex(idx, 0), createIndex(idx, 0)); - return; - } - - int idx = indexOf(name); - if (idx < 0 || items[idx].count <= 0) - return; // Shouldn't happen - - if(--items[idx].count == 0) { - beginRemoveRows(QModelIndex(), idx, idx); - items.erase(items.begin() + idx); - endRemoveRows(); - } else { - dataChanged(createIndex(idx, 0), createIndex(idx, 0)); - } -} - -// Increase count of entry with given name. If entry doesn't yet exist, add it. -void FilterModelBase::increaseCount(const QString &name) -{ - if (name.isEmpty()) { - // Increase the "Show Empty Tags" entry. Keep it even if count reaches 0. - if (items.empty()) - return; // Shouldn't happen! - ++items.back().count; - int idx = items.size() - 1; - dataChanged(createIndex(idx, 0), createIndex(idx, 0)); - return; - } - - int idx = indexOf(name); - if (idx < 0) { - idx = findInsertionIndex(name); - beginInsertRows(QModelIndex(), idx, idx); - items.insert(items.begin() + idx, { name, anyChecked, 1 }); - endInsertRows(); - } else { - ++items[idx].count; - dataChanged(createIndex(idx, 0), createIndex(idx, 0)); - } -} - -Qt::ItemFlags FilterModelBase::flags(const QModelIndex &index) const -{ - return QAbstractListModel::flags(index) | Qt::ItemIsUserCheckable; -} - -bool FilterModelBase::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (role == Qt::CheckStateRole) { - items[index.row()].checked = value.toBool(); - anyChecked = false; - for (const Item &item: items) { - if (item.checked) { - anyChecked = true; - break; - } - } - dataChanged(index, index, { role }); - return true; - } - return false; -} - -int FilterModelBase::rowCount(const QModelIndex &) const -{ - return items.size(); -} - -QVariant FilterModelBase::data(const QModelIndex &index, int role) const -{ - if (role == Qt::CheckStateRole) { - return items[index.row()].checked ? Qt::Checked : Qt::Unchecked; - } else if (role == Qt::DisplayRole) { - const Item &item = items[index.row()]; - return QStringLiteral("%1 (%2)").arg(item.name, QString::number(item.count)); - } - return QVariant(); -} - -void FilterModelBase::clearFilter() -{ - for (Item &item: items) - item.checked = false; - anyChecked = false; - emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0)); -} - -void FilterModelBase::selectAll() -{ - for (Item &item: items) - item.checked = true; - anyChecked = true; - emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0)); -} - -void FilterModelBase::invertSelection() -{ - for (Item &item: items) - item.checked = !item.checked; - anyChecked = std::any_of(items.begin(), items.end(), [](Item &item) { return !!item.checked; }); - emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0)); -} - -void FilterModelBase::setNegate(bool negateParam) -{ - negate = negateParam; - emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0)); -} - -SuitsFilterModel::SuitsFilterModel(QObject *parent) : FilterModelBase(parent) -{ -} - -int SuitsFilterModel::countDives(const char *s) const -{ - return count_dives_with_suit(s); -} - -bool SuitsFilterModel::doFilter(const dive *d) const -{ - // rowCount() == 0 should never happen, because we have the "no suits" row - // let's handle it gracefully anyway. - if (!anyChecked || rowCount() == 0) - return true; - - // Checked means 'Show', Unchecked means 'Hide'. - QString suit(d->suit); - // only show empty suit dives if the user checked that. - if (suit.isEmpty()) - return items[rowCount() - 1].checked != negate; - - // there is a suit selected - // Ignore last item, since this is the "Show Empty Tags" entry - for (int i = 0; i < rowCount() - 1; i++) { - if (items[i].checked && suit == items[i].name) - return !negate; - } - return negate; -} - -void SuitsFilterModel::diveAdded(const dive *d) -{ - increaseCount(QString(d->suit)); -} - -void SuitsFilterModel::diveDeleted(const dive *d) -{ - decreaseCount(QString(d->suit)); -} - -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); - } - } - list << tr("No suit set"); - updateList(list); -} - -TagFilterModel::TagFilterModel(QObject *parent) : FilterModelBase(parent) -{ -} - -int TagFilterModel::countDives(const char *s) const -{ - return count_dives_with_tag(s); -} - -void TagFilterModel::repopulate() -{ - if (g_tag_list == NULL) - return; - QStringList list; - struct tag_entry *current_tag_entry = g_tag_list; - while (current_tag_entry != NULL) { - if (count_dives_with_tag(current_tag_entry->tag->name) > 0) - list.append(QString(current_tag_entry->tag->name)); - current_tag_entry = current_tag_entry->next; - } - list << tr("Empty tags"); - updateList(list); -} - -bool TagFilterModel::doFilter(const dive *d) const -{ - // If there's nothing checked, this should show everything - // rowCount() == 0 should never happen, because we have the "no tags" row - // let's handle it gracefully anyway. - if (!anyChecked || rowCount() == 0) - return true; - - // Checked means 'Show', Unchecked means 'Hide'. - struct tag_entry *head = d->tag_list; - - if (!head) // last tag means "Show empty tags"; - return items[rowCount() - 1].checked != negate; - - // have at least one tag. - while (head) { - QString tagName(head->tag->name); - int index = indexOf(tagName); - if (index >= 0 && items[index].checked) - return !negate; - head = head->next; - } - return negate; -} - -void TagFilterModel::diveAdded(const dive *d) -{ - struct tag_entry *head = d->tag_list; - if (!head) { - increaseCount(QString()); - return; - } - while (head) { - increaseCount(QString()); - increaseCount(QString(head->tag->name)); - head = head->next; - } -} - -void TagFilterModel::diveDeleted(const dive *d) -{ - struct tag_entry *head = d->tag_list; - if (!head) { - decreaseCount(QString()); - return; - } - while (head) { - decreaseCount(QString(head->tag->name)); - head = head->next; - } -} - -BuddyFilterModel::BuddyFilterModel(QObject *parent) : FilterModelBase(parent) -{ -} - -int BuddyFilterModel::countDives(const char *s) const -{ - return count_dives_with_person(s); -} - -static QStringList getDiveBuddies(const dive *d) -{ - QString persons = QString(d->buddy) + "," + QString(d->divemaster); - QStringList personsList = persons.split(',', QString::SkipEmptyParts); - for (QString &s: personsList) - s = s.trimmed(); - return personsList; -} - -bool BuddyFilterModel::doFilter(const dive *d) const -{ - // If there's nothing checked, this should show everything - // rowCount() == 0 should never happen, because we have the "no tags" row - // let's handle it gracefully anyway. - if (!anyChecked || rowCount() == 0) - return true; - - QStringList personsList = getDiveBuddies(d); - // only show empty buddie dives if the user checked that. - if (personsList.isEmpty()) - return items[rowCount() - 1].checked != negate; - - // have at least one buddy - // Ignore last item, since this is the "Show Empty Tags" entry - for (int i = 0; i < rowCount() - 1; i++) { - if (items[i].checked && personsList.contains(items[i].name, Qt::CaseInsensitive)) - return !negate; - } - return negate; -} - -void BuddyFilterModel::diveAdded(const dive *d) -{ - QStringList buddies = getDiveBuddies(d); - if (buddies.empty()) { - increaseCount(QString()); - return; - } - for(const QString &buddy: buddies) - increaseCount(buddy); -} - -void BuddyFilterModel::diveDeleted(const dive *d) +MultiFilterSortModel *MultiFilterSortModel::instance() { - QStringList buddies = getDiveBuddies(d); - if (buddies.empty()) { - decreaseCount(QString()); - return; - } - for(const QString &buddy: buddies) - decreaseCount(buddy); -} - -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()); - } - } - } - list << tr("No buddies"); - updateList(list); -} - -LocationFilterModel::LocationFilterModel(QObject *parent) : FilterModelBase(parent) -{ -} - -int LocationFilterModel::countDives(const char *s) const -{ - return count_dives_with_location(s); -} - -bool LocationFilterModel::doFilter(const dive *d) const -{ - // rowCount() == 0 should never happen, because we have the "no location" row - // let's handle it gracefully anyway. - if (!anyChecked || rowCount() == 0) - return true; - - // Checked means 'Show', Unchecked means 'Hide'. - QString location(get_dive_location(d)); - // only show empty location dives if the user checked that. - if (location.isEmpty()) - return items[rowCount() - 1].checked != negate; - - // There is a location selected - // Ignore last item, since this is the "Show Empty Tags" entry - for (int i = 0; i < rowCount() - 1; i++) { - if (items[i].checked && location == items[i].name) - return !negate; - } - return negate; -} - -void LocationFilterModel::diveAdded(const dive *d) -{ - increaseCount(get_dive_location(d)); -} - -void LocationFilterModel::diveDeleted(const dive *d) -{ - decreaseCount(get_dive_location(d)); -} - -void LocationFilterModel::repopulate() -{ - QStringList list; - struct dive *dive; - int i = 0; - for_each_dive (i, dive) { - QString location(get_dive_location(dive)); - if (!location.isEmpty() && !list.contains(location)) { - list.append(location); - } - } - list << tr("No location set"); - updateList(list); -} - -void LocationFilterModel::addName(const QString &newName) -{ - if (newName.isEmpty() || indexOf(newName) >= 0) - return; - int count = countDives(qPrintable(newName)); - // If any old item was checked, also check the new one so that - // dives with the added dive site are shown. - addItem(newName, anyChecked, count); + static MultiFilterSortModel self; + return &self; } MultiFilterSortModel::MultiFilterSortModel(QObject *parent) : QSortFilterProxyModel(parent), @@ -574,28 +37,6 @@ void MultiFilterSortModel::setLayout(DiveTripModel::Layout layout) tripModel->setLayout(layout); // Note: setLayout() resets the whole model } -void MultiFilterSortModel::divesAdded(const QVector<dive *> &dives) -{ - // TODO: We call diveAdded for every dive and model. - // If multiple dives are added (e.g. import dive) this will lead to a large - // number of model changes and might be a pessimization compared to a full - // model reload. Instead, the models should take the vector, calculate the - // new fields and add them at once. - for (FilterModelBase *model: models) { - for (const dive *d: dives) - model->diveAdded(d); - } -} - -void MultiFilterSortModel::divesDeleted(const QVector<dive *> &dives) -{ - // TODO: See comment for divesDeleted - for (FilterModelBase *model: models) { - for (const dive *d: dives) - model->diveDeleted(d); - } -} - bool MultiFilterSortModel::showDive(const struct dive *d) const { if (curr_dive_site) { @@ -605,14 +46,6 @@ bool MultiFilterSortModel::showDive(const struct dive *d) const return ds == curr_dive_site || same_string(ds->name, curr_dive_site->name); } - if (models.isEmpty()) - return true; - - for (const FilterModelBase *model: models) { - if (!model->doFilter(d)) - return false; - } - return true; } @@ -674,23 +107,8 @@ void MultiFilterSortModel::myInvalidate() #endif } -void MultiFilterSortModel::addFilterModel(FilterModelBase *model) -{ - models.append(model); - connect(model, &FilterModelBase::dataChanged, this, &MultiFilterSortModel::filterChanged); -} - -void MultiFilterSortModel::removeFilterModel(FilterModelBase *model) -{ - models.removeAll(model); - disconnect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(myInvalidate())); -} - void MultiFilterSortModel::clearFilter() { - Q_FOREACH (FilterModelBase *iface, models) { - iface->clearFilter(); - } myInvalidate(); } diff --git a/qt-models/filtermodels.h b/qt-models/filtermodels.h index 6956146e1..61b82be33 100644 --- a/qt-models/filtermodels.h +++ b/qt-models/filtermodels.h @@ -34,119 +34,11 @@ struct FilterData { bool invertFilter; }; -class FilterModelBase : public QAbstractListModel { - Q_OBJECT -private: - int findInsertionIndex(const QString &name); -protected: - struct Item { - QString name; - bool checked; - int count; - }; - std::vector<Item> items; - int indexOf(const QString &name) const; - void addItem(const QString &name, bool checked, int count); - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - void decreaseCount(const QString &d); - void increaseCount(const QString &d); -public: - virtual bool doFilter(const dive *d) const = 0; - virtual void diveAdded(const dive *d) = 0; - virtual void diveDeleted(const dive *d) = 0; - void clearFilter(); - void selectAll(); - void invertSelection(); - bool anyChecked; - bool negate; -public -slots: - void setNegate(bool negate); - void changeName(const QString &oldName, const QString &newName); -protected: - explicit FilterModelBase(QObject *parent = 0); - void updateList(QStringList &new_list); - virtual int countDives(const char *) const = 0; -private: - Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); -}; - -class TagFilterModel : public FilterModelBase { - Q_OBJECT -public: - static TagFilterModel *instance(); - bool doFilter(const dive *d) const; -public -slots: - void repopulate(); - -private: - explicit TagFilterModel(QObject *parent = 0); - int countDives(const char *) const; - void diveAdded(const dive *d); - void diveDeleted(const dive *d); -}; - -class BuddyFilterModel : public FilterModelBase { - Q_OBJECT -public: - static BuddyFilterModel *instance(); - bool doFilter(const dive *d) const; -public -slots: - void repopulate(); - -private: - explicit BuddyFilterModel(QObject *parent = 0); - int countDives(const char *) const; - void diveAdded(const dive *d); - void diveDeleted(const dive *d); -}; - -class LocationFilterModel : public FilterModelBase { - Q_OBJECT -public: - static LocationFilterModel *instance(); - bool doFilter(const dive *d) const; -public -slots: - void repopulate(); - void addName(const QString &newName); - -private: - explicit LocationFilterModel(QObject *parent = 0); - int countDives(const char *) const; - void diveAdded(const dive *d); - void diveDeleted(const dive *d); -}; - -class SuitsFilterModel : public FilterModelBase { - Q_OBJECT -public: - static SuitsFilterModel *instance(); - bool doFilter(const dive *d) const; -public -slots: - void repopulate(); - -private: - explicit SuitsFilterModel(QObject *parent = 0); - int countDives(const char *) const; - void diveAdded(const dive *d); - void diveDeleted(const dive *d); -}; - class MultiFilterSortModel : public QSortFilterProxyModel { Q_OBJECT public: static MultiFilterSortModel *instance(); bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; - void addFilterModel(FilterModelBase *model); - void removeFilterModel(FilterModelBase *model); - void divesAdded(const QVector<dive *> &dives); - void divesDeleted(const QVector<dive *> &dives); bool showDive(const struct dive *d) const; int divesDisplayed; bool lessThan(const QModelIndex &, const QModelIndex &) const override; @@ -165,7 +57,6 @@ signals: private: MultiFilterSortModel(QObject *parent = 0); - QList<FilterModelBase *> models; struct dive_site *curr_dive_site; DiveTripModel *model; FilterData filterData; |