QGIS API Documentation  3.10.0-A Coruña (6c816b4204)
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  ***************************************************************************/
15 #include "qgsattributetablemodel.h"
16 #include "qgsfeaturemodel.h"
19 #include "qgsvectorlayer.h"
20 #include "qgslogger.h"
21 
22 QgsFeatureSelectionModel::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 
67 bool QgsFeatureSelectionModel::isSelected( const QModelIndex &index )
68 {
69  return isSelected( index.model()->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong() );
70 }
71 
72 void QgsFeatureSelectionModel::selectFeatures( const QItemSelection &selection, QItemSelectionModel::SelectionFlags command )
73 {
74  QgsFeatureIds ids;
75 
76  QgsDebugMsg( QStringLiteral( "Index count: %1" ).arg( selection.indexes().size() ) );
77 
78  const auto constIndexes = selection.indexes();
79  for ( const QModelIndex &index : constIndexes )
80  {
81  QgsFeatureId id = index.model()->data( index, QgsAttributeTableModel::FeatureIdRole ).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 ( 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 ( 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 ( 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  mFeatureSelectionManager = featureSelectionManager;
159 
160  connect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
161 }
162 
163 void QgsFeatureSelectionModel::layerSelectionChanged( const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect )
164 {
165  if ( clearAndSelect )
166  {
167  emit requestRepaint();
168  }
169  else
170  {
171  QModelIndexList updatedIndexes;
172  const auto constSelected = selected;
173  for ( QgsFeatureId fid : constSelected )
174  {
175  updatedIndexes.append( expandIndexToRow( mFeatureModel->fidToIndex( fid ) ) );
176  }
177 
178  const auto constDeselected = deselected;
179  for ( QgsFeatureId fid : constDeselected )
180  {
181  updatedIndexes.append( expandIndexToRow( mFeatureModel->fidToIndex( fid ) ) );
182  }
183 
184  emit requestRepaint( updatedIndexes );
185  }
186 }
187 
188 QModelIndexList QgsFeatureSelectionModel::expandIndexToRow( const QModelIndex &index ) const
189 {
190  QModelIndexList indexes;
191  const QAbstractItemModel *model = index.model();
192  int row = index.row();
193 
194  if ( !model )
195  return indexes;
196 
197  int columns = model->columnCount();
198  indexes.reserve( columns );
199  for ( int column = 0; column < columns; ++column )
200  {
201  indexes.append( model->index( row, column ) );
202  }
203 
204  return indexes;
205 }
virtual bool isSelected(QgsFeatureId fid)
Returns the selection status of a given feature id.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:34
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
qint64 QgsFeatureId
Definition: qgsfeatureid.h:25
virtual void selectFeatures(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
Select features on this table.
virtual void setSelectedFeatures(const QgsFeatureIds &ids)=0
Change selection to the new set of features.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
void enableSync(bool enable)
Enables or disables synchronisation to the QgsVectorLayer When synchronisation is disabled...
virtual QModelIndex fidToIndex(QgsFeatureId fid)=0
Get the feature id of the feature in this row.
virtual void deselect(const QgsFeatureIds &ids)=0
Deselect features by feature ids.
void requestRepaint()
Request a repaint of the visible items of connected views.
virtual const QgsFeatureIds & selectedFeatureIds() const =0
Returns reference to identifiers of selected features.
virtual void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
QgsFeatureSelectionModel(QAbstractItemModel *model, QgsFeatureModel *featureModel, QgsIFeatureSelectionManager *featureSelectionHandler, QObject *parent)
Is an interface class to abstract feature selection handling.
virtual void select(const QgsFeatureIds &ids)=0
Select features by feature ids.