QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsfeatureselectionmodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsfeatureselectionmodel.cpp
3 ---------------------
4 begin : April 2013
5 copyright : (C) 2013 by Matthias Kuhn
6 email : matthias at opengis dot ch
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
16#include "qgsfeaturemodel.h"
19#include "qgsvectorlayer.h"
20#include "qgslogger.h"
21
22QgsFeatureSelectionModel::QgsFeatureSelectionModel( QAbstractItemModel *model, QgsFeatureModel *featureModel, QgsIFeatureSelectionManager *featureSelectionManager, QObject *parent )
23 : QItemSelectionModel( model, parent )
24 , mFeatureModel( featureModel )
25 , mSyncEnabled( true )
26 , mClearAndSelectBuffer( false )
27{
28 setFeatureSelectionManager( featureSelectionManager );
29}
30
32{
33 mSyncEnabled = enable;
34
35 if ( mSyncEnabled )
36 {
37 if ( mClearAndSelectBuffer )
38 {
39 mFeatureSelectionManager->setSelectedFeatures( mSelectedBuffer );
40 }
41 else
42 {
43 mFeatureSelectionManager->select( mSelectedBuffer );
44 mFeatureSelectionManager->deselect( mDeselectedBuffer );
45 }
46
47 mSelectedBuffer.clear();
48 mDeselectedBuffer.clear();
49 mClearAndSelectBuffer = false;
50 }
51}
52
54{
55 if ( mSelectedBuffer.contains( fid ) )
56 return true;
57
58 if ( mDeselectedBuffer.contains( fid ) )
59 return false;
60
61 if ( !mClearAndSelectBuffer && mFeatureSelectionManager->selectedFeatureIds().contains( fid ) )
62 return true;
63
64 return false;
65}
66
67bool QgsFeatureSelectionModel::isSelected( const QModelIndex &index )
68{
69 return isSelected( index.model()->data( index, static_cast< int >( QgsAttributeTableModel::CustomRole::FeatureId ) ).toLongLong() );
70}
71
72void QgsFeatureSelectionModel::selectFeatures( const QItemSelection &selection, QItemSelectionModel::SelectionFlags command )
73{
74 QgsFeatureIds ids;
75
76 QgsDebugMsgLevel( QStringLiteral( "Index count: %1" ).arg( selection.indexes().size() ), 2 );
77
78 const auto constIndexes = selection.indexes();
79 for ( const QModelIndex &index : constIndexes )
80 {
81 const QgsFeatureId id = index.model()->data( index, static_cast< int >( QgsAttributeTableModel::CustomRole::FeatureId ) ).toLongLong();
82
83 ids << id;
84 }
85
86 disconnect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
87
88 if ( command.testFlag( QItemSelectionModel::ClearAndSelect ) )
89 {
90 if ( !mSyncEnabled )
91 {
92 mClearAndSelectBuffer = true;
93 const auto constIds = ids;
94 for ( const QgsFeatureId id : constIds )
95 {
96 if ( !mDeselectedBuffer.remove( id ) )
97 {
98 mSelectedBuffer.insert( id );
99 }
100 }
101 }
102 else
103 {
104 mFeatureSelectionManager->setSelectedFeatures( ids );
105 }
106 }
107 else if ( command.testFlag( QItemSelectionModel::Select ) )
108 {
109 if ( !mSyncEnabled )
110 {
111 const auto constIds = ids;
112 for ( const QgsFeatureId id : constIds )
113 {
114 if ( !mDeselectedBuffer.remove( id ) )
115 {
116 mSelectedBuffer.insert( id );
117 }
118 }
119 }
120 else
121 {
122 mFeatureSelectionManager->select( ids );
123 }
124 }
125 else if ( command.testFlag( QItemSelectionModel::Deselect ) )
126 {
127 if ( !mSyncEnabled )
128 {
129 const auto constIds = ids;
130 for ( const QgsFeatureId id : constIds )
131 {
132 if ( !mSelectedBuffer.remove( id ) )
133 {
134 mDeselectedBuffer.insert( id );
135 }
136 }
137 }
138 else
139 {
140 mFeatureSelectionManager->deselect( ids );
141 }
142 }
143
144 connect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
145
146 QModelIndexList updatedIndexes;
147 const auto indexes = selection.indexes();
148 for ( const QModelIndex &idx : indexes )
149 {
150 updatedIndexes.append( expandIndexToRow( idx ) );
151 }
152
153 emit requestRepaint( updatedIndexes );
154}
155
157{
158 if ( mFeatureSelectionManager )
159 disconnect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
160
161 mFeatureSelectionManager = featureSelectionManager;
162
163 connect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
164}
165
166void QgsFeatureSelectionModel::layerSelectionChanged( const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect )
167{
168 if ( clearAndSelect )
169 {
170 emit requestRepaint();
171 }
172 else
173 {
174 QModelIndexList updatedIndexes;
175 const auto constSelected = selected;
176 for ( const QgsFeatureId fid : constSelected )
177 {
178 updatedIndexes.append( expandIndexToRow( mFeatureModel->fidToIndex( fid ) ) );
179 }
180
181 const auto constDeselected = deselected;
182 for ( const QgsFeatureId fid : constDeselected )
183 {
184 updatedIndexes.append( expandIndexToRow( mFeatureModel->fidToIndex( fid ) ) );
185 }
186
187 emit requestRepaint( updatedIndexes );
188 }
189}
190
191QModelIndexList QgsFeatureSelectionModel::expandIndexToRow( const QModelIndex &index ) const
192{
193 QModelIndexList indexes;
194 const QAbstractItemModel *model = index.model();
195 const int row = index.row();
196
197 if ( !model )
198 return indexes;
199
200 const int columns = model->columnCount();
201 indexes.reserve( columns );
202 for ( int column = 0; column < columns; ++column )
203 {
204 indexes.append( model->index( row, column ) );
205 }
206
207 return indexes;
208}
@ FeatureId
Get the feature id of the feature in this row.
virtual QModelIndex fidToIndex(QgsFeatureId fid)=0
void enableSync(bool enable)
Enables or disables synchronisation to the QgsVectorLayer When synchronisation is disabled,...
virtual void selectFeatures(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
Select features on this table.
virtual bool isSelected(QgsFeatureId fid)
Returns the selection status of a given feature id.
QgsFeatureSelectionModel(QAbstractItemModel *model, QgsFeatureModel *featureModel, QgsIFeatureSelectionManager *featureSelectionHandler, QObject *parent)
virtual void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
void requestRepaint()
Request a repaint of the visible items of connected views.
Is an interface class to abstract feature selection handling.
virtual void select(const QgsFeatureIds &ids)=0
Select features by feature ids.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
virtual const QgsFeatureIds & selectedFeatureIds() const =0
Returns reference to identifiers of selected features.
virtual void deselect(const QgsFeatureIds &ids)=0
Deselect features by feature ids.
virtual void setSelectedFeatures(const QgsFeatureIds &ids)=0
Change selection to the new set of features.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39