diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-11-28 00:14:14 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-11-28 12:15:24 -0800 |
commit | 4928c4ae0421193bbd371cb0924091a970489611 (patch) | |
tree | cd4795c6e0273126faa56e3063fea70ff12fe2bc /desktop-widgets | |
parent | 7d77db96e30fc238aee9f229e583429a6883bf34 (diff) | |
download | subsurface-4928c4ae0421193bbd371cb0924091a970489611.tar.gz |
Desktop: Improve speed of selecting multiple (or all) dives
When selecting all dives via CTRL-A or manually and the trips
were not expanded, the QSelectionModel sends a single
selectionChanged signal per trip. We are reloading the map
in every call, making this very slow.
I couldn't figure out how to make QSelectionModel behave more
nicely, therefore I chose the nuclear option: Remove the map
reloading from selectionChanged() and hook into all functions
that do selection changes. In these functions, first call the
original code and then do the selection-changed operations.
This will certainly need some tuning.
Reported-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'desktop-widgets')
-rw-r--r-- | desktop-widgets/divelistview.cpp | 71 | ||||
-rw-r--r-- | desktop-widgets/divelistview.h | 3 |
2 files changed, 41 insertions, 33 deletions
diff --git a/desktop-widgets/divelistview.cpp b/desktop-widgets/divelistview.cpp index 860e3bc95..55bcb4906 100644 --- a/desktop-widgets/divelistview.cpp +++ b/desktop-widgets/divelistview.cpp @@ -31,7 +31,7 @@ #include "desktop-widgets/mapwidget.h" DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), - currentLayout(DiveTripModelBase::TREE), dontEmitDiveChangedSignal(false), selectionSaved(false), + currentLayout(DiveTripModelBase::TREE), selectionSaved(false), initialColumnWidths(DiveTripModelBase::COLUMNS, 50) // Set up with default length 50 { setItemDelegate(new DiveListDelegate(this)); @@ -197,10 +197,6 @@ void DiveListView::reset() // If items were selected, inform the selection model void DiveListView::diveSelectionChanged(const QVector<QModelIndex> &indexes) { - // Since dives are selected dive-by-dive, send only a single signal at the - // end, not one for every dive. - dontEmitDiveChangedSignal = true; - clearSelection(); MultiFilterSortModel *m = MultiFilterSortModel::instance(); QItemSelectionModel *s = selectionModel(); @@ -225,8 +221,7 @@ void DiveListView::diveSelectionChanged(const QVector<QModelIndex> &indexes) } } - dontEmitDiveChangedSignal = false; - emit divesSelected(); + selectionChangeDone(); } void DiveListView::currentDiveChanged(QModelIndex index) @@ -312,10 +307,9 @@ void DiveListView::tripChanged(dive_trip *trip, TripField) if (selected.size() == 1 && selected[0] == trip) return; - dontEmitDiveChangedSignal = true; unselectDives(); - dontEmitDiveChangedSignal = false; selectTrip(trip); + selectionChangeDone(); } void DiveListView::selectTrip(dive_trip_t *trip) @@ -401,6 +395,7 @@ void DiveListView::selectDive(QModelIndex idx, bool scrollto, bool toggle) } if (scrollto) scrollTo(idx, PositionAtCenter); + selectionChangeDone(); } void DiveListView::selectDive(int i, bool scrollto, bool toggle) @@ -423,8 +418,6 @@ void DiveListView::selectDives(const QList<int> &newDiveSelection) if (!newDiveSelection.count()) return; - dontEmitDiveChangedSignal = true; - // First, clear the old selection unselectDives(); @@ -478,9 +471,7 @@ void DiveListView::selectDives(const QList<int> &newDiveSelection) } // now that everything is up to date, update the widgets - emit divesSelected(); - dontEmitDiveChangedSignal = false; - return; + selectionChangeDone(); } // Get index of first dive. This assumes that trips without dives are never shown. @@ -645,6 +636,39 @@ void DiveListView::currentChanged(const QModelIndex ¤t, const QModelIndex& scrollTo(current); } +void DiveListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) +{ + QTreeView::setSelection(rect, flags); + selectionChangeDone(); +} + +void DiveListView::selectAll() +{ + QTreeView::selectAll(); + selectionChangeDone(); +} + +void DiveListView::selectionChangeDone() +{ + // When receiving the divesSelected signal the main window will + // instruct the map to update the flags. Thus, make sure that + // the selected maps are registered correctly. + // But don't do this if we are in divesite mode, because then + // the dive-site selection is controlled by the filter not + // by the selected dives. + if (!DiveFilter::instance()->diveSiteMode()) { + QVector<dive_site *> selectedSites; + for (QModelIndex index: selectionModel()->selection().indexes()) { + const QAbstractItemModel *model = index.model(); + struct dive *dive = model->data(index, DiveTripModelBase::DIVE_ROLE).value<struct dive *>(); + if (dive && dive->dive_site) + selectedSites.push_back(dive->dive_site); + } + MapWidget::instance()->setSelected(selectedSites); + } + emit divesSelected(); +} + void DiveListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { if (diveListNotifier.inCommand()) { @@ -692,25 +716,6 @@ void DiveListView::selectionChanged(const QItemSelection &selected, const QItemS select_dive(dive); } } - if (!dontEmitDiveChangedSignal) { - // When receiving the divesSelected signal the main window will - // instruct the map to update the flags. Thus, make sure that - // the selected maps are registered correctly. - // But don't do this if we are in divesite mode, because then - // the dive-site selection is controlled by the filter not - // by the selected dives. - if (!DiveFilter::instance()->diveSiteMode()) { - QVector<dive_site *> selectedSites; - for (QModelIndex index: selectionModel()->selection().indexes()) { - const QAbstractItemModel *model = index.model(); - struct dive *dive = model->data(index, DiveTripModelBase::DIVE_ROLE).value<struct dive *>(); - if (dive && dive->dive_site) - selectedSites.push_back(dive->dive_site); - } - MapWidget::instance()->setSelected(selectedSites); - } - emit divesSelected(); - } // Display the new, processed, selection QTreeView::selectionChanged(selectionModel()->selection(), newDeselected); diff --git a/desktop-widgets/divelistview.h b/desktop-widgets/divelistview.h index 0d5117ca3..67b1b269b 100644 --- a/desktop-widgets/divelistview.h +++ b/desktop-widgets/divelistview.h @@ -70,6 +70,9 @@ slots: void filterFinished(); void tripChanged(dive_trip *trip, TripField); private: + void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) override; + void selectAll() override; + void selectionChangeDone(); bool mouseClickSelection; QList<int> expandedRows; DiveTripModelBase::Layout currentLayout; |