QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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  Q_FOREACH ( const QModelIndex &index, selection.indexes() )
79  {
80  QgsFeatureId id = index.model()->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong();
81 
82  ids << id;
83  }
84 
85  disconnect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
86 
87  if ( command.testFlag( QItemSelectionModel::ClearAndSelect ) )
88  {
89  if ( !mSyncEnabled )
90  {
91  mClearAndSelectBuffer = true;
92  Q_FOREACH ( QgsFeatureId id, ids )
93  {
94  if ( !mDeselectedBuffer.remove( id ) )
95  {
96  mSelectedBuffer.insert( id );
97  }
98  }
99  }
100  else
101  {
102  mFeatureSelectionManager->setSelectedFeatures( ids );
103  }
104  }
105  else if ( command.testFlag( QItemSelectionModel::Select ) )
106  {
107  if ( !mSyncEnabled )
108  {
109  Q_FOREACH ( QgsFeatureId id, ids )
110  {
111  if ( !mDeselectedBuffer.remove( id ) )
112  {
113  mSelectedBuffer.insert( id );
114  }
115  }
116  }
117  else
118  {
119  mFeatureSelectionManager->select( ids );
120  }
121  }
122  else if ( command.testFlag( QItemSelectionModel::Deselect ) )
123  {
124  if ( !mSyncEnabled )
125  {
126  Q_FOREACH ( QgsFeatureId id, ids )
127  {
128  if ( !mSelectedBuffer.remove( id ) )
129  {
130  mDeselectedBuffer.insert( id );
131  }
132  }
133  }
134  else
135  {
136  mFeatureSelectionManager->deselect( ids );
137  }
138  }
139 
140  connect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
141 
142  QModelIndexList updatedIndexes;
143  Q_FOREACH ( const QModelIndex &idx, selection.indexes() )
144  {
145  updatedIndexes.append( expandIndexToRow( idx ) );
146  }
147 
148  emit requestRepaint( updatedIndexes );
149 }
150 
152 {
153  mFeatureSelectionManager = featureSelectionManager;
154 
155  connect( mFeatureSelectionManager, &QgsIFeatureSelectionManager::selectionChanged, this, &QgsFeatureSelectionModel::layerSelectionChanged );
156 }
157 
158 void QgsFeatureSelectionModel::layerSelectionChanged( const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect )
159 {
160  if ( clearAndSelect )
161  {
162  emit requestRepaint();
163  }
164  else
165  {
166  QModelIndexList updatedIndexes;
167  Q_FOREACH ( QgsFeatureId fid, selected )
168  {
169  updatedIndexes.append( expandIndexToRow( mFeatureModel->fidToIndex( fid ) ) );
170  }
171 
172  Q_FOREACH ( QgsFeatureId fid, deselected )
173  {
174  updatedIndexes.append( expandIndexToRow( mFeatureModel->fidToIndex( fid ) ) );
175  }
176 
177  emit requestRepaint( updatedIndexes );
178  }
179 }
180 
181 QModelIndexList QgsFeatureSelectionModel::expandIndexToRow( const QModelIndex &index ) const
182 {
183  QModelIndexList indexes;
184  const QAbstractItemModel *model = index.model();
185  int row = index.row();
186 
187  if ( !model )
188  return indexes;
189 
190  int columns = model->columnCount();
191  indexes.reserve( columns );
192  for ( int column = 0; column < columns; ++column )
193  {
194  indexes.append( model->index( row, column ) );
195  }
196 
197  return indexes;
198 }
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)
This signal is 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.