QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
18#include "qgsfeaturemodel.h"
20#include "qgslogger.h"
21#include "qgsvectorlayer.h"
22
23#include "moc_qgsfeatureselectionmodel.cpp"
24
25QgsFeatureSelectionModel::QgsFeatureSelectionModel( QAbstractItemModel *model, QgsFeatureModel *featureModel, QgsIFeatureSelectionManager *featureSelectionManager, QObject *parent )
26 : QItemSelectionModel( model, parent )
27 , mFeatureModel( featureModel )
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.
Base class for feature models.
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.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
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:61