diff options
-rw-r--r-- | desktop-widgets/divelistview.cpp | 75 | ||||
-rw-r--r-- | desktop-widgets/divelistview.h | 4 | ||||
-rw-r--r-- | qt-models/filtermodels.cpp | 30 |
3 files changed, 62 insertions, 47 deletions
diff --git a/desktop-widgets/divelistview.cpp b/desktop-widgets/divelistview.cpp index eb65e9e6e..5a1741a7f 100644 --- a/desktop-widgets/divelistview.cpp +++ b/desktop-widgets/divelistview.cpp @@ -47,6 +47,9 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec connect(DiveTripModel::instance(), &DiveTripModel::selectionChanged, this, &DiveListView::diveSelectionChanged); connect(DiveTripModel::instance(), &DiveTripModel::newCurrentDive, this, &DiveListView::currentDiveChanged); + // Update selection if all selected dives were hidden by filter + connect(MultiFilterSortModel::instance(), &MultiFilterSortModel::filterFinished, this, &DiveListView::filterFinished); + header()->setStretchLastSection(true); installEventFilter(this); @@ -349,17 +352,11 @@ QList<dive_trip_t *> DiveListView::selectedTrips() return ret; } -void DiveListView::selectDive(int i, bool scrollto, bool toggle) +void DiveListView::selectDive(QModelIndex idx, bool scrollto, bool toggle) { - if (i == -1) + if (!idx.isValid()) return; - QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model()); - QModelIndexList match = m->match(m->index(0, 0), DiveTripModel::DIVE_IDX, i, 2, Qt::MatchRecursive); - QItemSelectionModel::SelectionFlags flags; - if (match.isEmpty()) - return; - QModelIndex idx = match.first(); - flags = toggle ? QItemSelectionModel::Toggle : QItemSelectionModel::Select; + QItemSelectionModel::SelectionFlags flags = toggle ? QItemSelectionModel::Toggle : QItemSelectionModel::Select; flags |= QItemSelectionModel::Rows; selectionModel()->setCurrentIndex(idx, flags); if (idx.parent().isValid()) { @@ -373,6 +370,18 @@ void DiveListView::selectDive(int i, bool scrollto, bool toggle) scrollTo(idx, PositionAtCenter); } +void DiveListView::selectDive(int i, bool scrollto, bool toggle) +{ + if (i == -1) + return; + QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model()); + QModelIndexList match = m->match(m->index(0, 0), DiveTripModel::DIVE_IDX, i, 2, Qt::MatchRecursive); + if (match.isEmpty()) + return; + QModelIndex idx = match.first(); + selectDive(idx, scrollto, toggle); +} + void DiveListView::selectDives(const QList<int> &newDiveSelection) { int firstInList, newSelection; @@ -416,6 +425,28 @@ void DiveListView::selectDives(const QList<int> &newDiveSelection) return; } +// Get index of first dive. This assumes that trips without dives are never shown. +// May return an invalid index if no dive is found. +QModelIndex DiveListView::indexOfFirstDive() +{ + // Fetch the first top-level item. If this is a trip, it is supposed to have at least + // one child. In that case return the child. Otherwise return the top-level item, which + // should be a dive. + QAbstractItemModel *m = model(); + QModelIndex firstDiveOrTrip = m->index(0, 0); + if (!firstDiveOrTrip.isValid()) + return QModelIndex(); + QModelIndex child = m->index(0, 0, firstDiveOrTrip); + return child.isValid() ? child : firstDiveOrTrip; +} + +void DiveListView::selectFirstDive() +{ + QModelIndex first = indexOfFirstDive(); + if (first.isValid()) + setCurrentIndex(first); +} + bool DiveListView::eventFilter(QObject *, QEvent *event) { if (event->type() != QEvent::KeyPress) @@ -476,19 +507,11 @@ void DiveListView::reload(DiveTripModel::Layout layout, bool forceSort) if (!forceSort) return; - QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model()); sortByColumn(sortColumn, currentOrder); - if (amount_selected && current_dive != NULL) { + if (amount_selected && current_dive != NULL) selectDive(get_divenr(current_dive), true); - } else { - QModelIndex firstDiveOrTrip = m->index(0, 0); - if (firstDiveOrTrip.isValid()) { - if (m->index(0, 0, firstDiveOrTrip).isValid()) - setCurrentIndex(m->index(0, 0, firstDiveOrTrip)); - else - setCurrentIndex(firstDiveOrTrip); - } - } + else + selectFirstDive(); if (selectedIndexes().count()) { QModelIndex curr = selectedIndexes().first(); curr = curr.parent().isValid() ? curr.parent() : curr; @@ -1029,6 +1052,18 @@ void DiveListView::loadImageFromURL(QUrl url) } } +void DiveListView::filterFinished() +{ + // 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) + clearTripSelection(); + + // If there are no more selected dives, select the first visible dive + if (!selectionModel()->hasSelection()) + selectFirstDive(); +} + QString DiveListView::lastUsedImageDir() { QSettings settings; diff --git a/desktop-widgets/divelistview.h b/desktop-widgets/divelistview.h index 5c9ac2f25..c53e2aa01 100644 --- a/desktop-widgets/divelistview.h +++ b/desktop-widgets/divelistview.h @@ -29,8 +29,11 @@ public: bool eventFilter(QObject *, QEvent *); void unselectDives(); void clearTripSelection(); + void selectDive(QModelIndex index, bool scrollto = false, bool toggle = false); void selectDive(int dive_table_idx, bool scrollto = false, bool toggle = false); void selectDives(const QList<int> &newDiveSelection); + void selectFirstDive(); + QModelIndex indexOfFirstDive(); void rememberSelection(); void restoreSelection(); void contextMenuEvent(QContextMenuEvent *event); @@ -60,6 +63,7 @@ slots: void loadWebImages(); void diveSelectionChanged(const QVector<QModelIndex> &indexes, bool select); void currentDiveChanged(QModelIndex index); + void filterFinished(); private: bool mouseClickSelection; QList<int> expandedRows; diff --git a/qt-models/filtermodels.cpp b/qt-models/filtermodels.cpp index fb513f250..58d0277bd 100644 --- a/qt-models/filtermodels.cpp +++ b/qt-models/filtermodels.cpp @@ -641,10 +641,8 @@ void MultiFilterSortModel::filterChanged(const QModelIndex &from, const QModelIn void MultiFilterSortModel::myInvalidate() { -#if !defined(SUBSURFACE_MOBILE) int i; struct dive *d; - DiveListView *dlv = MainWindow::instance()->diveList; divesDisplayed = 0; @@ -658,33 +656,11 @@ void MultiFilterSortModel::myInvalidate() invalidateFilter(); - // 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); - } - emit filterFinished(); - if (curr_dive_site) { - dlv->expandAll(); - } +#if !defined(SUBSURFACE_MOBILE) + if (curr_dive_site) + MainWindow::instance()->diveList->expandAll(); #endif } |