summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--desktop-widgets/divelistview.cpp75
-rw-r--r--desktop-widgets/divelistview.h4
-rw-r--r--qt-models/filtermodels.cpp30
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
}