mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-08 01:06:16 +00:00
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>
This commit is contained in:
parent
7d77db96e3
commit
4928c4ae04
3 changed files with 42 additions and 33 deletions
|
@ -1,4 +1,5 @@
|
||||||
Mobile: (desktop only) new switch --testqml, allows to use qml files instead of resources.
|
Mobile: (desktop only) new switch --testqml, allows to use qml files instead of resources.
|
||||||
|
Desktop: increase speed of multi-trip selection
|
||||||
Mobile: ensure that all BT/BLE flavors of the OSTC are recognized as dive computers [#2358]
|
Mobile: ensure that all BT/BLE flavors of the OSTC are recognized as dive computers [#2358]
|
||||||
Desktop: allow copy&pasting of multiple cylinders [#2386]
|
Desktop: allow copy&pasting of multiple cylinders [#2386]
|
||||||
Desktop: don't output random SAC values for cylinders without data [#2376]
|
Desktop: don't output random SAC values for cylinders without data [#2376]
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "desktop-widgets/mapwidget.h"
|
#include "desktop-widgets/mapwidget.h"
|
||||||
|
|
||||||
DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false),
|
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
|
initialColumnWidths(DiveTripModelBase::COLUMNS, 50) // Set up with default length 50
|
||||||
{
|
{
|
||||||
setItemDelegate(new DiveListDelegate(this));
|
setItemDelegate(new DiveListDelegate(this));
|
||||||
|
@ -197,10 +197,6 @@ void DiveListView::reset()
|
||||||
// If items were selected, inform the selection model
|
// If items were selected, inform the selection model
|
||||||
void DiveListView::diveSelectionChanged(const QVector<QModelIndex> &indexes)
|
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();
|
clearSelection();
|
||||||
MultiFilterSortModel *m = MultiFilterSortModel::instance();
|
MultiFilterSortModel *m = MultiFilterSortModel::instance();
|
||||||
QItemSelectionModel *s = selectionModel();
|
QItemSelectionModel *s = selectionModel();
|
||||||
|
@ -225,8 +221,7 @@ void DiveListView::diveSelectionChanged(const QVector<QModelIndex> &indexes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dontEmitDiveChangedSignal = false;
|
selectionChangeDone();
|
||||||
emit divesSelected();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiveListView::currentDiveChanged(QModelIndex index)
|
void DiveListView::currentDiveChanged(QModelIndex index)
|
||||||
|
@ -312,10 +307,9 @@ void DiveListView::tripChanged(dive_trip *trip, TripField)
|
||||||
if (selected.size() == 1 && selected[0] == trip)
|
if (selected.size() == 1 && selected[0] == trip)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dontEmitDiveChangedSignal = true;
|
|
||||||
unselectDives();
|
unselectDives();
|
||||||
dontEmitDiveChangedSignal = false;
|
|
||||||
selectTrip(trip);
|
selectTrip(trip);
|
||||||
|
selectionChangeDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiveListView::selectTrip(dive_trip_t *trip)
|
void DiveListView::selectTrip(dive_trip_t *trip)
|
||||||
|
@ -401,6 +395,7 @@ void DiveListView::selectDive(QModelIndex idx, bool scrollto, bool toggle)
|
||||||
}
|
}
|
||||||
if (scrollto)
|
if (scrollto)
|
||||||
scrollTo(idx, PositionAtCenter);
|
scrollTo(idx, PositionAtCenter);
|
||||||
|
selectionChangeDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiveListView::selectDive(int i, bool scrollto, bool toggle)
|
void DiveListView::selectDive(int i, bool scrollto, bool toggle)
|
||||||
|
@ -423,8 +418,6 @@ void DiveListView::selectDives(const QList<int> &newDiveSelection)
|
||||||
if (!newDiveSelection.count())
|
if (!newDiveSelection.count())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dontEmitDiveChangedSignal = true;
|
|
||||||
|
|
||||||
// First, clear the old selection
|
// First, clear the old selection
|
||||||
unselectDives();
|
unselectDives();
|
||||||
|
|
||||||
|
@ -478,9 +471,7 @@ void DiveListView::selectDives(const QList<int> &newDiveSelection)
|
||||||
}
|
}
|
||||||
|
|
||||||
// now that everything is up to date, update the widgets
|
// now that everything is up to date, update the widgets
|
||||||
emit divesSelected();
|
selectionChangeDone();
|
||||||
dontEmitDiveChangedSignal = false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get index of first dive. This assumes that trips without dives are never shown.
|
// 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);
|
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)
|
void DiveListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
|
||||||
{
|
{
|
||||||
if (diveListNotifier.inCommand()) {
|
if (diveListNotifier.inCommand()) {
|
||||||
|
@ -692,25 +716,6 @@ void DiveListView::selectionChanged(const QItemSelection &selected, const QItemS
|
||||||
select_dive(dive);
|
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
|
// Display the new, processed, selection
|
||||||
QTreeView::selectionChanged(selectionModel()->selection(), newDeselected);
|
QTreeView::selectionChanged(selectionModel()->selection(), newDeselected);
|
||||||
|
|
|
@ -70,6 +70,9 @@ slots:
|
||||||
void filterFinished();
|
void filterFinished();
|
||||||
void tripChanged(dive_trip *trip, TripField);
|
void tripChanged(dive_trip *trip, TripField);
|
||||||
private:
|
private:
|
||||||
|
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) override;
|
||||||
|
void selectAll() override;
|
||||||
|
void selectionChangeDone();
|
||||||
bool mouseClickSelection;
|
bool mouseClickSelection;
|
||||||
QList<int> expandedRows;
|
QList<int> expandedRows;
|
||||||
DiveTripModelBase::Layout currentLayout;
|
DiveTripModelBase::Layout currentLayout;
|
||||||
|
|
Loading…
Add table
Reference in a new issue