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     QPoint pos = 
event->pos();
 
  136     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   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     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     QPoint pos = 
event->pos();
 
  255     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     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   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   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   QModelIndex tl = model()->index( std::min( mRowAnchor, row ), 0 );
 
  385   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