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() ) );
132 if ( event->button() != Qt::LeftButton )
134 QListView::mousePressEvent( event );
140 const QPoint pos =
event->pos();
142 const QModelIndex index = indexAt( pos );
146 mDragMode = DragMode::MoveSelection;
147 if ( index.isValid() )
152 mDragMode = DragMode::ExpandSelection;
154 selectRow( index,
true );
160 QgsDebugMsg( QStringLiteral(
"No model assigned to this view" ) );
164void QgsFeatureListView::editSelectionChanged(
const QItemSelection &deselected,
const QItemSelection &selected )
166 if ( isVisible() && updatesEnabled() )
170 viewport()->update( visualRegionForSelection( localDeselected ) | visualRegionForSelection( localSelected ) );
173 const QItemSelection currentSelection = mCurrentEditSelectionModel->selection();
174 if ( currentSelection.size() == 1 )
176 QModelIndexList indexList = currentSelection.indexes();
177 if ( !indexList.isEmpty() )
194 QItemSelection selection;
195 selection.append( QItemSelectionRange( mModel->index( 0, 0 ), mModel->index( mModel->
rowCount() - 1, 0 ) ) );
197 mFeatureSelectionModel->
selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
202 QItemSelection selection;
203 QModelIndex firstModelIdx;
205 const auto constFids = fids;
208 const QModelIndex modelIdx = mModel->
fidToIdx( fid );
210 if ( ! firstModelIdx.isValid() )
211 firstModelIdx = modelIdx;
213 selection.append( QItemSelectionRange( mModel->
mapToMaster( modelIdx ) ) );
221 mCurrentEditSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );
222 scrollTo( firstModelIdx );
232 Q_ASSERT( index.model() == mModel->
masterModel() || !index.isValid() );
236 mCurrentEditSelectionModel->select( index, command );
243 const auto constIndexes = indexes;
244 for (
const QModelIndex &index : constIndexes )
252 setDirtyRegion( viewport()->rect() );
259 const QPoint pos =
event->pos();
260 const QModelIndex index = indexAt( pos );
264 case QgsFeatureListView::DragMode::Inactive:
267 case QgsFeatureListView::DragMode::ExpandSelection:
269 selectRow( index,
false );
273 case QgsFeatureListView::DragMode::MoveSelection:
275 if ( index.isValid() )
283 QgsDebugMsg( QStringLiteral(
"No model assigned to this view" ) );
289 if ( event->button() != Qt::LeftButton )
291 QListView::mouseReleaseEvent( event );
297 case QgsFeatureListView::DragMode::ExpandSelection:
298 if ( mFeatureSelectionModel )
301 case QgsFeatureListView::DragMode::Inactive:
302 case QgsFeatureListView::DragMode::MoveSelection:
306 mDragMode = DragMode::Inactive;
311 switch ( event->key() )
314 editOtherFeature( Previous );
318 editOtherFeature( Next );
322 QListView::keyPressEvent( event );
326void QgsFeatureListView::editOtherFeature( QgsFeatureListView::PositionInList positionInList )
329 if ( 0 != mCurrentEditSelectionModel->selectedIndexes().count() )
331 const QModelIndex localIndex = mModel->
mapFromMaster( mCurrentEditSelectionModel->selectedIndexes().first() );
332 currentRow = localIndex.row();
335 QModelIndex newLocalIndex;
336 QModelIndex newIndex;
338 switch ( positionInList )
341 newLocalIndex = mModel->index( 0, 0 );
345 newLocalIndex = mModel->index( currentRow - 1, 0 );
349 newLocalIndex = mModel->index( currentRow + 1, 0 );
353 newLocalIndex = mModel->index( mModel->
rowCount() - 1, 0 );
358 if ( newIndex.isValid() )
361 scrollTo( newLocalIndex );
367 const QModelIndex index = indexAt( event->pos() );
369 if ( index.isValid() )
381 menu->exec( event->globalPos() );
385void QgsFeatureListView::selectRow(
const QModelIndex &index,
bool anchor )
387 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
388 const int row = index.row();
393 if ( selectionMode() != QListView::SingleSelection
394 && command.testFlag( QItemSelectionModel::Toggle ) )
397 mCtrlDragSelectionFlag = mFeatureSelectionModel->
isSelected( index )
398 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
399 command &= ~QItemSelectionModel::Toggle;
400 command |= mCtrlDragSelectionFlag;
402 command |= QItemSelectionModel::Current;
405 const QModelIndex tl = model()->index( std::min( mRowAnchor, row ), 0 );
406 const QModelIndex br = model()->index( std::max( mRowAnchor, row ), model()->columnCount() - 1 );
408 mFeatureSelectionModel->
selectFeatures( QItemSelection( tl, br ), command );
411void QgsFeatureListView::ensureEditSelection(
bool inSelection )
421 const QModelIndexList selectedIndexes = mCurrentEditSelectionModel->selectedIndexes();
427 bool editSelectionUpdateRequested =
false;
430 bool validEditSelectionAvailable =
false;
432 if ( selectedIndexes.isEmpty() || !selectedIndexes.first().isValid() || mModel->
mapFromMaster( selectedIndexes.first() ).row() == -1 )
434 validEditSelectionAvailable =
false;
438 validEditSelectionAvailable =
true;
446 if ( !validEditSelectionAvailable )
448 editSelectionUpdateRequested =
true;
455 if ( !selectedFids.contains( mModel->
idxToFid( mModel->
mapFromMaster( selectedIndexes.first() ) ) ) )
457 editSelectionUpdateRequested =
true;
465 if ( !validEditSelectionAvailable )
466 editSelectionUpdateRequested =
true;
469 if ( editSelectionUpdateRequested )
471 if ( !mUpdateEditSelectionTimer.isSingleShot() )
473 mUpdateEditSelectionTimer.setSingleShot(
true );
474 connect( &mUpdateEditSelectionTimer, &QTimer::timeout,
this, [
this, inSelection, validEditSelectionAvailable ]()
481 int rowToSelect = -1;
486 const int rowCount = mModel->
rowCount();
488 for (
int i = 0; i < rowCount; i++ )
490 if ( selectedFids.contains( mModel->
idxToFid( mModel->index( i, 0 ) ) ) )
496 if ( rowToSelect == -1 && !validEditSelectionAvailable )
503 if ( rowToSelect != -1 )
508 mUpdateEditSelectionTimer.setInterval( 0 );
510 mUpdateEditSelectionTimer.start();
516 mFeatureSelectionManager = featureSelectionManager;
518 if ( mFeatureSelectionModel )
522 if ( mOwnedFeatureSelectionManager )
524 mOwnedFeatureSelectionManager->deleteLater();
525 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.
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.
QgsFeatureListModel * featureListModel()
Gets the featureListModel used by this view.
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