16 #include <QHeaderView>
39 setSelectionMode( QAbstractItemView::ExtendedSelection );
52 delete mFeatureSelectionModel;
53 delete mCurrentEditSelectionModel;
55 mCurrentEditSelectionModel =
new QItemSelectionModel( mModel->
masterModel(),
this );
56 if ( !mFeatureSelectionManager )
59 mFeatureSelectionManager = mOwnedFeatureSelectionManager;
63 setSelectionModel( mFeatureSelectionModel );
66 ensureEditSelection( true );
69 if ( mItemDelegate && mItemDelegate->parent() ==
this )
76 setItemDelegate( mItemDelegate );
83 connect( mCurrentEditSelectionModel, &QItemSelectionModel::selectionChanged,
this, &QgsFeatureListView::editSelectionChanged );
85 connect(
featureListModel, &QgsFeatureListModel::rowsRemoved,
this, [
this ]() { ensureEditSelection(); } );
86 connect(
featureListModel, &QgsFeatureListModel::rowsInserted,
this, [
this ]() { ensureEditSelection(); } );
87 connect(
featureListModel, &QgsFeatureListModel::modelReset,
this, [
this ]() { ensureEditSelection(); } );
116 const QModelIndexList selectedIndexes = mCurrentEditSelectionModel->selectedIndexes();
117 for (
const QModelIndex &idx : selectedIndexes )
127 viewport()->update( visualRegionForSelection( mCurrentEditSelectionModel->selection() ) );
134 const QPoint pos =
event->pos();
136 const QModelIndex index = indexAt( pos );
141 mEditSelectionDrag =
true;
142 if ( index.isValid() )
148 selectRow( index,
true );
154 QgsDebugMsg( QStringLiteral(
"No model assigned to this view" ) );
158 void QgsFeatureListView::editSelectionChanged(
const QItemSelection &deselected,
const QItemSelection &selected )
160 if ( isVisible() && updatesEnabled() )
164 viewport()->update( visualRegionForSelection( localDeselected ) | visualRegionForSelection( localSelected ) );
167 const QItemSelection currentSelection = mCurrentEditSelectionModel->selection();
168 if ( currentSelection.size() == 1 )
170 QModelIndexList indexList = currentSelection.indexes();
171 if ( !indexList.isEmpty() )
188 QItemSelection selection;
189 selection.append( QItemSelectionRange( mModel->index( 0, 0 ), mModel->index( mModel->
rowCount() - 1, 0 ) ) );
191 mFeatureSelectionModel->
selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
196 QItemSelection selection;
197 QModelIndex firstModelIdx;
199 const auto constFids = fids;
202 const QModelIndex modelIdx = mModel->
fidToIdx( fid );
204 if ( ! firstModelIdx.isValid() )
205 firstModelIdx = modelIdx;
207 selection.append( QItemSelectionRange( mModel->
mapToMaster( modelIdx ) ) );
215 mCurrentEditSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );
216 scrollTo( firstModelIdx );
226 Q_ASSERT( index.model() == mModel->
masterModel() || !index.isValid() );
230 mCurrentEditSelectionModel->select( index, command );
237 const auto constIndexes = indexes;
238 for (
const QModelIndex &index : constIndexes )
246 setDirtyRegion( viewport()->rect() );
253 const QPoint pos =
event->pos();
255 const QModelIndex index = indexAt( pos );
257 if ( mEditSelectionDrag )
259 if ( index.isValid() )
264 selectRow( index,
false );
269 QgsDebugMsg( QStringLiteral(
"No model assigned to this view" ) );
277 if ( mEditSelectionDrag )
279 mEditSelectionDrag =
false;
283 if ( mFeatureSelectionModel )
290 switch ( event->key() )
293 editOtherFeature( Previous );
297 editOtherFeature( Next );
301 QListView::keyPressEvent( event );
305 void QgsFeatureListView::editOtherFeature( QgsFeatureListView::PositionInList positionInList )
308 if ( 0 != mCurrentEditSelectionModel->selectedIndexes().count() )
310 const QModelIndex localIndex = mModel->
mapFromMaster( mCurrentEditSelectionModel->selectedIndexes().first() );
311 currentRow = localIndex.row();
314 QModelIndex newLocalIndex;
315 QModelIndex newIndex;
317 switch ( positionInList )
320 newLocalIndex = mModel->index( 0, 0 );
324 newLocalIndex = mModel->index( currentRow - 1, 0 );
328 newLocalIndex = mModel->index( currentRow + 1, 0 );
332 newLocalIndex = mModel->index( mModel->
rowCount() - 1, 0 );
337 if ( newIndex.isValid() )
340 scrollTo( newLocalIndex );
346 const QModelIndex index = indexAt( event->pos() );
348 if ( index.isValid() )
360 menu->exec( event->globalPos() );
364 void QgsFeatureListView::selectRow(
const QModelIndex &index,
bool anchor )
366 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
367 const int row = index.row();
372 if ( selectionMode() != QListView::SingleSelection
373 && command.testFlag( QItemSelectionModel::Toggle ) )
376 mCtrlDragSelectionFlag = mFeatureSelectionModel->
isSelected( index )
377 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
378 command &= ~QItemSelectionModel::Toggle;
379 command |= mCtrlDragSelectionFlag;
381 command |= QItemSelectionModel::Current;
384 const QModelIndex tl = model()->index( std::min( mRowAnchor, row ), 0 );
385 const QModelIndex br = model()->index( std::max( mRowAnchor, row ), model()->columnCount() - 1 );
387 mFeatureSelectionModel->
selectFeatures( QItemSelection( tl, br ), command );
390 void QgsFeatureListView::ensureEditSelection(
bool inSelection )
400 const QModelIndexList selectedIndexes = mCurrentEditSelectionModel->selectedIndexes();
406 bool editSelectionUpdateRequested =
false;
409 bool validEditSelectionAvailable =
false;
411 if ( selectedIndexes.isEmpty() || !selectedIndexes.first().isValid() || mModel->
mapFromMaster( selectedIndexes.first() ).row() == -1 )
413 validEditSelectionAvailable =
false;
417 validEditSelectionAvailable =
true;
425 if ( !validEditSelectionAvailable )
427 editSelectionUpdateRequested =
true;
434 if ( !selectedFids.contains( mModel->
idxToFid( mModel->
mapFromMaster( selectedIndexes.first() ) ) ) )
436 editSelectionUpdateRequested =
true;
444 if ( !validEditSelectionAvailable )
445 editSelectionUpdateRequested =
true;
448 if ( editSelectionUpdateRequested )
450 if ( !mUpdateEditSelectionTimer.isSingleShot() )
452 mUpdateEditSelectionTimer.setSingleShot(
true );
453 connect( &mUpdateEditSelectionTimer, &QTimer::timeout,
this, [
this, inSelection, validEditSelectionAvailable ]()
460 int rowToSelect = -1;
465 const int rowCount = mModel->
rowCount();
467 for (
int i = 0; i < rowCount; i++ )
469 if ( selectedFids.contains( mModel->
idxToFid( mModel->index( i, 0 ) ) ) )
475 if ( rowToSelect == -1 && !validEditSelectionAvailable )
482 if ( rowToSelect != -1 )
487 mUpdateEditSelectionTimer.setInterval( 0 );
489 mUpdateEditSelectionTimer.start();
495 mFeatureSelectionManager = featureSelectionManager;
497 if ( mFeatureSelectionModel )
501 if ( mOwnedFeatureSelectionManager )
503 mOwnedFeatureSelectionManager->deleteLater();
504 mOwnedFeatureSelectionManager =
nullptr;
@ FeatureIdRole
Get the feature id of the feature in this row.
QgsFeatureId idxToFid(const QModelIndex &index) const
Returns the feature ID corresponding to an index from the model.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
bool featureByIndex(const QModelIndex &index, QgsFeature &feat)
virtual QModelIndex mapToMaster(const QModelIndex &proxyIndex) const
QModelIndex fidToIdx(QgsFeatureId fid) const
Returns the model index corresponding to a feature ID.
QString parserErrorString()
Returns a detailed message about errors while parsing a QgsExpression.
QVariant data(const QModelIndex &index, int role) const override
bool setDisplayExpression(const QString &expression)
virtual QModelIndex mapFromMaster(const QModelIndex &sourceIndex) const
QString displayExpression() const
QgsVectorLayerCache * layerCache()
Returns the vector layer cache which is being used to populate the model.
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
virtual QItemSelection mapSelectionFromMaster(const QItemSelection &selection) const
QgsAttributeTableModel * masterModel()
void setEditSelectionModel(QItemSelectionModel *editSelectionModel)
void setCurrentFeatureEdited(bool state)
void setFeatureSelectionModel(QgsFeatureSelectionModel *featureSelectionModel)
Element positionToElement(QPoint pos)
Shows a list of features and renders a edit button next to each feature.
QgsFeatureListModel * featureListModel()
Gets the featureListModel used by this view.
void currentEditSelectionProgressChanged(int progress, int count)
Emitted whenever the current edit selection has been changed.
const QString displayExpression() const
Returns the expression which is currently used to render the features.
void keyPressEvent(QKeyEvent *event) override
void contextMenuEvent(QContextMenuEvent *event) override
void setCurrentFeatureEdited(bool state)
Sets if the currently shown form has received any edit events so far.
void displayExpressionChanged(const QString &expression)
Emitted whenever the display expression is successfully changed.
void mouseMoveEvent(QMouseEvent *event) override
void setEditSelection(const QgsFeatureIds &fids)
Set the feature(s) to be edited.
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
setFeatureSelectionManager
QgsFeatureIds currentEditSelection()
Gets the currentEditSelection.
void mousePressEvent(QMouseEvent *event) override
bool setDisplayExpression(const QString &displayExpression)
The display expression is an expression used to render the fields into a single string which is displ...
void selectAll() override
Select all currently visible features.
QgsVectorLayerCache * layerCache()
Returns the layer cache.
QString parserErrorString()
Returns a detailed message about errors while parsing a QgsExpression.
void mouseReleaseEvent(QMouseEvent *event) override
void willShowContextMenu(QgsActionMenu *menu, const QModelIndex &atIndex)
Emitted when the context menu is created to add the specific actions to it.
QgsFeatureListView(QWidget *parent=nullptr)
Creates a feature list view.
virtual void setModel(QgsFeatureListModel *featureListModel)
Set the QgsFeatureListModel which is used to retrieve information.
void currentEditSelectionChanged(QgsFeature &feat)
Emitted whenever the current edit selection has been changed.
void aboutToChangeEditSelection(bool &ok)
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.
virtual void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
void requestRepaint()
Request a repaint of the visible items of connected views.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Is an interface class to abstract feature selection handling.
This class caches features of a given QgsVectorLayer.
QgsVectorLayer * layer()
Returns the layer to which this cache belongs.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Emitted whenever an attribute value change is done in the edit buffer.
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