mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	Dive list: move dive-selection code from filter to list
After invalidating the filter, the dive-selection was modified to ensure that at least one dive is selected. This was done in the filter code, but it seems preferrable to do this in the dive-list code, which has direct access to the selection-model. Therefore, move the code from MultiFilterSortModel to DiveListView. While doing so, split the code in DiveListView into more functions to: 1) Get the index of the first dive (if any). 2) Select the first dive (if any). This allows a distinct size reduction of conditional compilation in MultiFilterSortModel (accesses to MainWindow are not possible in mobile code). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
		
							parent
							
								
									2f81890f49
								
							
						
					
					
						commit
						9829e49815
					
				
					 3 changed files with 62 additions and 47 deletions
				
			
		|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue