QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
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 "moc_qgsfeatureselectionmodel.cpp"
20#include "qgsvectorlayer.h"
21#include "qgslogger.h"
22
23QgsFeatureSelectionModel::QgsFeatureSelectionModel( QAbstractItemModel *model, QgsFeatureModel *featureModel, QgsIFeatureSelectionManager *featureSelectionManager, QObject *parent )
24 : QItemSelectionModel( model, parent )
25 , mFeatureModel( featureModel )
26 , mSyncEnabled( true )
27 , mClearAndSelectBuffer( false )
28{
29 setFeatureSelectionManager( featureSelectionManager );
30}
31
33{
34 mSyncEnabled = enable;
35
36 if ( mSyncEnabled )
37 {
38 if ( mClearAndSelectBuffer )
39 {
40 mFeatureSelectionManager->setSelectedFeatures( mSelectedBuffer );
41 }
42 else
43 {
44 mFeatureSelectionManager->select( mSelectedBuffer );
45 mFeatureSelectionManager->deselect( mDeselectedBuffer );
46 }
47
48 mSelectedBuffer.clear();
49 mDeselectedBuffer.clear();
50 mClearAndSelectBuffer = false;
51 }
52}
53
55{
56 if ( mSelectedBuffer.contains( fid ) )
57 return true;
58
59 if ( mDeselectedBuffer.contains( fid ) )
60 return false;
61
62 if ( !mClearAndSelectBuffer && mFeatureSelectionManager->selectedFeatureIds().contains( fid ) )
63 return true;
64
65 return false;
66}
67
68bool QgsFeatureSelectionModel::isSelected( const QModelIndex &index )
69{
70 return isSelected( index.model()->data( index, static_cast< int >( QgsAttributeTableModel::CustomRole::FeatureId ) ).toLongLong() );
71}
72
73void QgsFeatureSelectionModel::selectFeatures( const QItemSelection &selection, QItemSelectionModel::SelectionFlags command )
74{
75 QgsFeatureIds ids;
76
77 QgsDebugMsgLevel( QStringLiteral( "Index count: %1" ).arg( selection.indexes().size() ), 2 );
78
79 const auto constIndexes = selection.indexes();
80 for ( const QModelIndex &index : constIndexes )
81 {
82 const QgsFeatureId id = index.model()->data( index, static_cast< int >( QgsAttributeTableModel::CustomRole::FeatureId ) ).toLongLong();
83
84 ids << id;
85 }
86
87 disconnect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
88
89 if ( command.testFlag( QItemSelectionModel::ClearAndSelect ) )
90 {
91 if ( !mSyncEnabled )
92 {
93 mClearAndSelectBuffer = true;
94 const auto constIds = ids;
95 for ( const QgsFeatureId id : constIds )
96 {
97 if ( !mDeselectedBuffer.remove( id ) )
98 {
99 mSelectedBuffer.insert( id );
100 }
101 }
102 }
103 else
104 {
105 mFeatureSelectionManager->setSelectedFeatures( ids );
106 }
107 }
108 else if ( command.testFlag( QItemSelectionModel::Select ) )
109 {
110 if ( !mSyncEnabled )
111 {
112 const auto constIds = ids;
113 for ( const QgsFeatureId id : constIds )
114 {
115 if ( !mDeselectedBuffer.remove( id ) )
116 {
117 mSelectedBuffer.insert( id );
118 }
119 }
120 }
121 else
122 {
123 mFeatureSelectionManager->select( ids );
124 }
125 }
126 else if ( command.testFlag( QItemSelectionModel::Deselect ) )
127 {
128 if ( !mSyncEnabled )
129 {
130 const auto constIds = ids;
131 for ( const QgsFeatureId id : constIds )
132 {
133 if ( !mSelectedBuffer.remove( id ) )
134 {
135 mDeselectedBuffer.insert( id );
136 }
137 }
138 }
139 else
140 {
141 mFeatureSelectionManager->deselect( ids );
142 }
143 }
144
145 connect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
146
147 QModelIndexList updatedIndexes;
148 const auto indexes = selection.indexes();
149 for ( const QModelIndex &idx : indexes )
150 {
151 updatedIndexes.append( expandIndexToRow( idx ) );
152 }
153
154 emit requestRepaint( updatedIndexes );
155}
156
158{
159 if ( mFeatureSelectionManager )
160 disconnect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
161
162 mFeatureSelectionManager = featureSelectionManager;
163
164 connect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
165}
166
167void QgsFeatureSelectionModel::layerSelectionChanged( const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect )
168{
169 if ( clearAndSelect )
170 {
171 emit requestRepaint();
172 }
173 else
174 {
175 QModelIndexList updatedIndexes;
176 const auto constSelected = selected;
177 for ( const QgsFeatureId fid : constSelected )
178 {
179 updatedIndexes.append( expandIndexToRow( mFeatureModel->fidToIndex( fid ) ) );
180 }
181
182 const auto constDeselected = deselected;
183 for ( const QgsFeatureId fid : constDeselected )
184 {
185 updatedIndexes.append( expandIndexToRow( mFeatureModel->fidToIndex( fid ) ) );
186 }
187
188 emit requestRepaint( updatedIndexes );
189 }
190}
191
192QModelIndexList QgsFeatureSelectionModel::expandIndexToRow( const QModelIndex &index ) const
193{
194 QModelIndexList indexes;
195 const QAbstractItemModel *model = index.model();
196 const int row = index.row();
197
198 if ( !model )
199 return indexes;
200
201 const int columns = model->columnCount();
202 indexes.reserve( columns );
203 for ( int column = 0; column < columns; ++column )
204 {
205 indexes.append( model->index( row, column ) );
206 }
207
208 return indexes;
209}
@ 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
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39