selection: replace selectedTrips() by singleSelectedTrip() function

To check wether the tab widgets should show the trip view, they called
the selectedTrips() function. The trip view was shown if that contained
only one trip. However, the selectedTrips() function was very slow,
because it has to query to core models.

Change the function to singleSelectedTrip(), which returns a trip
if there is exactly one trip selected. The function returns early
if there is more than one trip selected. This makes the select-all
case much faster.

There are two cases which are still very slow:
- List mode, because here all top-level items are queried.
- Dive log with many only top-level items.

Ultimately, we will have to cache the trip selection because
querying the model is too slow.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2020-04-26 22:05:28 +02:00 committed by Dirk Hohndel
parent 6e83135fba
commit 2021035cfc
3 changed files with 15 additions and 12 deletions

View file

@ -265,8 +265,7 @@ void DiveListView::tripChanged(dive_trip *trip, TripField)
{
// First check if the trip is already selected (and only
// this trip, as only then is it displayed). Is so, then do nothing.
QList<dive_trip *> selected = selectedTrips();
if (selected.size() == 1 && selected[0] == trip)
if (singleSelectedTrip() == trip)
return;
unselectDives();
@ -309,16 +308,21 @@ void DiveListView::unselectDives()
}
}
QList<dive_trip_t *> DiveListView::selectedTrips()
// This function returns a trip if there is one selected trip or NULL.
// Returning all selected trips turned out to be too slow.
dive_trip_t *DiveListView::singleSelectedTrip()
{
QList<dive_trip_t *> ret;
Q_FOREACH (const QModelIndex &index, selectionModel()->selectedRows()) {
dive_trip_t *trip = index.data(DiveTripModelBase::TRIP_ROLE).value<dive_trip *>();
if (!trip)
dive_trip_t *res = nullptr;
for (const QModelIndex &index: selectionModel()->selectedRows()) {
if (index.parent().isValid())
continue;
ret.push_back(trip);
if (dive_trip_t *trip = index.data(DiveTripModelBase::TRIP_ROLE).value<dive_trip *>()) {
if (res)
return nullptr; // More than one
res = trip;
}
return ret;
}
return res;
}
bool DiveListView::eventFilter(QObject *, QEvent *event)

View file

@ -25,7 +25,7 @@ public:
~DiveListView();
void setSortOrder(int i, Qt::SortOrder order); // Call to set sort order
void reload(); // Call to reload model data
QList<dive_trip *> selectedTrips();
dive_trip *singleSelectedTrip();
static QString lastUsedImageDir();
static void updateLastUsedImageDir(const QString &s);
void loadImages();

View file

@ -365,8 +365,7 @@ void MainTab::updateDiveInfo()
// 2) the filter is reset, potentially erasing the current trip under our feet.
// TODO: Don't hard code tab location!
bool onDiveSiteTab = ui.tabWidget->currentIndex() == 6;
if (MainWindow::instance() && MainWindow::instance()->diveList->selectedTrips().count() == 1) {
currentTrip = MainWindow::instance()->diveList->selectedTrips().front();
if (dive_trip *currentTrip = MainWindow::instance()->diveList->singleSelectedTrip()) {
// Remember the tab selected for last dive but only if we're not on the dive site tab
if (lastSelectedDive && !onDiveSiteTab)
lastTabSelectedDive = ui.tabWidget->currentIndex();