mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	The dive-site-edit and dive-site-table tabs both put the filter into a special dive-site mode. When switching between both, it could happen that the one got its show befor the other got its hide event. Thus, the first would start dive-site filtering and the second stop it. Now the app was not in filter mode even though it should. To solve this problem, add reference counting for the filter's dive-site mode. In both tabs call the enter/exit functions on show/hide. In the dive-site-table tab, when the selection changes, use a set function that doesn't modify the reference count. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
		
			
				
	
	
		
			119 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| #include "TabDiveSite.h"
 | |
| #include "core/subsurface-qt/DiveListNotifier.h"
 | |
| #include "core/divesite.h"
 | |
| #include "qt-models/divelocationmodel.h"
 | |
| #include "qt-models/filtermodels.h"
 | |
| #include "desktop-widgets/command.h"
 | |
| 
 | |
| #include <qt-models/divecomputerextradatamodel.h>
 | |
| 
 | |
| TabDiveSite::TabDiveSite(QWidget *parent) : TabBase(parent)
 | |
| {
 | |
| 	ui.setupUi(this);
 | |
| 	ui.diveSites->setTitle(tr("Dive sites"));
 | |
| 	ui.diveSites->setModel(&model);
 | |
| 	// Default: sort by name
 | |
| 	ui.diveSites->view()->sortByColumn(LocationInformationModel::NAME, Qt::AscendingOrder);
 | |
| 	ui.diveSites->view()->setSortingEnabled(true);
 | |
| 	ui.diveSites->view()->horizontalHeader()->setSectionResizeMode(LocationInformationModel::NAME, QHeaderView::Stretch);
 | |
| 	ui.diveSites->view()->horizontalHeader()->setSectionResizeMode(LocationInformationModel::DESCRIPTION, QHeaderView::Stretch);
 | |
| 	ui.diveSites->view()->setSelectionBehavior(QAbstractItemView::SelectRows);
 | |
| 
 | |
| 	// Show only the first few columns
 | |
| 	for (int i = LocationInformationModel::LOCATION; i < LocationInformationModel::COLUMNS; ++i)
 | |
| 		ui.diveSites->view()->setColumnHidden(i, true);
 | |
| 
 | |
| 	connect(ui.diveSites, &TableView::addButtonClicked, this, &TabDiveSite::add);
 | |
| 	connect(ui.diveSites->view()->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TabDiveSite::selectionChanged);
 | |
| 
 | |
| 	// Subtle: We depend on this slot being executed after the slot in the model.
 | |
| 	// This is realized because the model was constructed as a member object and connects in the constructor.
 | |
| 	connect(&diveListNotifier, &DiveListNotifier::diveSiteChanged, this, &TabDiveSite::diveSiteChanged);
 | |
| }
 | |
| 
 | |
| void TabDiveSite::updateData()
 | |
| {
 | |
| }
 | |
| 
 | |
| void TabDiveSite::clear()
 | |
| {
 | |
| }
 | |
| 
 | |
| void TabDiveSite::add()
 | |
| {
 | |
| 	// This is mighty dirty: We hook into the "dive site added" signal and
 | |
| 	// select the name field of the added dive site when the command sends
 | |
| 	// the signal. This works only because we know that the model added the
 | |
| 	// connection first. Very subtle!
 | |
| 	// After the command has finished, the signal is disconnected so that dive
 | |
| 	// site names are not selected on regular redo / undo.
 | |
| 	connect(&diveListNotifier, &DiveListNotifier::diveSiteAdded, this, &TabDiveSite::diveSiteAdded);
 | |
| 	Command::addDiveSite(tr("New dive site"));
 | |
| 	disconnect(&diveListNotifier, &DiveListNotifier::diveSiteAdded, this, &TabDiveSite::diveSiteAdded);
 | |
| }
 | |
| 
 | |
| void TabDiveSite::diveSiteAdded(struct dive_site *, int idx)
 | |
| {
 | |
| 	if (idx < 0)
 | |
| 		return;
 | |
| 	QModelIndex globalIdx = LocationInformationModel::instance()->index(idx, LocationInformationModel::NAME);
 | |
| 	QModelIndex localIdx = model.mapFromSource(globalIdx);
 | |
| 	ui.diveSites->view()->setCurrentIndex(localIdx);
 | |
| 	ui.diveSites->view()->edit(localIdx);
 | |
| }
 | |
| 
 | |
| void TabDiveSite::diveSiteChanged(struct dive_site *ds, int field)
 | |
| {
 | |
| 	int idx = get_divesite_idx(ds, &dive_site_table);
 | |
| 	if (idx < 0)
 | |
| 		return;
 | |
| 	QModelIndex globalIdx = LocationInformationModel::instance()->index(idx, field);
 | |
| 	QModelIndex localIdx = model.mapFromSource(globalIdx);
 | |
| 	ui.diveSites->view()->scrollTo(localIdx);
 | |
| }
 | |
| 
 | |
| void TabDiveSite::on_purgeUnused_clicked()
 | |
| {
 | |
| 	Command::purgeUnusedDiveSites();
 | |
| }
 | |
| 
 | |
| void TabDiveSite::on_filterText_textChanged(const QString &text)
 | |
| {
 | |
| 	model.setFilter(text);
 | |
| }
 | |
| 
 | |
| QVector<dive_site *> TabDiveSite::selectedDiveSites()
 | |
| {
 | |
| 	const QModelIndexList indexes = ui.diveSites->view()->selectionModel()->selectedIndexes();
 | |
| 	QVector<dive_site *> sites;
 | |
| 	sites.reserve(indexes.size());
 | |
| 	for (const QModelIndex &idx: indexes) {
 | |
| 		struct dive_site *ds = model.getDiveSite(idx);
 | |
| 		sites.append(ds);
 | |
| 	}
 | |
| 	return sites;
 | |
| }
 | |
| 
 | |
| void TabDiveSite::updateFilter()
 | |
| {
 | |
| 	MultiFilterSortModel::instance()->setFilterDiveSite(selectedDiveSites());
 | |
| }
 | |
| 
 | |
| void TabDiveSite::selectionChanged(const QItemSelection &, const QItemSelection &)
 | |
| {
 | |
| 	updateFilter();
 | |
| }
 | |
| 
 | |
| void TabDiveSite::showEvent(QShowEvent *)
 | |
| {
 | |
| 	// If the user switches to the dive site tab and there was already a selection,
 | |
| 	// filter on that selection.
 | |
| 	MultiFilterSortModel::instance()->startFilterDiveSites(selectedDiveSites());
 | |
| }
 | |
| 
 | |
| void TabDiveSite::hideEvent(QHideEvent *)
 | |
| {
 | |
| 	// If the user switches to a different tab, stop the dive site filtering
 | |
| 	MultiFilterSortModel::instance()->stopFilterDiveSites();
 | |
| }
 |