16 #include <QHeaderView>
38 setSelectionMode( QAbstractItemView::ExtendedSelection );
51 delete mFeatureSelectionModel;
52 delete mCurrentEditSelectionModel;
54 mCurrentEditSelectionModel =
new QItemSelectionModel( mModel->
masterModel(),
this );
55 if ( !mFeatureSelectionManager )
58 mFeatureSelectionManager = mOwnedFeatureSelectionManager;
62 setSelectionModel( mFeatureSelectionModel );
65 ensureEditSelection( true );
68 if ( mItemDelegate && mItemDelegate->parent() ==
this )
75 setItemDelegate( mItemDelegate );
82 connect( mCurrentEditSelectionModel, &QItemSelectionModel::selectionChanged,
this, &QgsFeatureListView::editSelectionChanged );
84 connect(
featureListModel, &QgsFeatureListModel::rowsRemoved,
this, [
this ]() { ensureEditSelection(); } );
85 connect(
featureListModel, &QgsFeatureListModel::rowsInserted,
this, [
this ]() { ensureEditSelection(); } );
86 connect(
featureListModel, &QgsFeatureListModel::modelReset,
this, [
this ]() { ensureEditSelection(); } );
115 const QModelIndexList selectedIndexes = mCurrentEditSelectionModel->selectedIndexes();
116 for (
const QModelIndex &idx : selectedIndexes )
126 viewport()->update( visualRegionForSelection( mCurrentEditSelectionModel->selection() ) );
133 QPoint pos =
event->pos();
135 QModelIndex index = indexAt( pos );
140 mEditSelectionDrag =
true;
141 if ( index.isValid() )
147 selectRow( index,
true );
153 QgsDebugMsg( QStringLiteral(
"No model assigned to this view" ) );
157 void QgsFeatureListView::editSelectionChanged(
const QItemSelection &deselected,
const QItemSelection &selected )
159 if ( isVisible() && updatesEnabled() )
163 viewport()->update( visualRegionForSelection( localDeselected ) | visualRegionForSelection( localSelected ) );
166 QItemSelection currentSelection = mCurrentEditSelectionModel->selection();
167 if ( currentSelection.size() == 1 )
169 QModelIndexList indexList = currentSelection.indexes();
170 if ( !indexList.isEmpty() )
183 QItemSelection selection;
184 selection.append( QItemSelectionRange( mModel->index( 0, 0 ), mModel->index( mModel->
rowCount() - 1, 0 ) ) );
186 mFeatureSelectionModel->
selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
191 QItemSelection selection;
192 QModelIndex firstModelIdx;
194 const auto constFids = fids;
197 QModelIndex modelIdx = mModel->
fidToIdx( fid );
199 if ( ! firstModelIdx.isValid() )
200 firstModelIdx = modelIdx;
202 selection.append( QItemSelectionRange( mModel->
mapToMaster( modelIdx ) ) );
210 mCurrentEditSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );
211 scrollTo( firstModelIdx );
221 Q_ASSERT( index.model() == mModel->
masterModel() || !index.isValid() );
225 mCurrentEditSelectionModel->select( index, command );
232 const auto constIndexes = indexes;
233 for (
const QModelIndex &index : constIndexes )
241 setDirtyRegion( viewport()->rect() );
248 QPoint pos =
event->pos();
250 QModelIndex index = indexAt( pos );
252 if ( mEditSelectionDrag )
254 if ( index.isValid() )
259 selectRow( index,
false );
264 QgsDebugMsg( QStringLiteral(
"No model assigned to this view" ) );
272 if ( mEditSelectionDrag )
274 mEditSelectionDrag =
false;
278 if ( mFeatureSelectionModel )
285 switch ( event->key() )
288 editOtherFeature( Previous );
292 editOtherFeature( Next );
296 QListView::keyPressEvent( event );
300 void QgsFeatureListView::editOtherFeature( QgsFeatureListView::PositionInList positionInList )
303 if ( 0 != mCurrentEditSelectionModel->selectedIndexes().count() )
305 QModelIndex localIndex = mModel->
mapFromMaster( mCurrentEditSelectionModel->selectedIndexes().first() );
306 currentRow = localIndex.row();
309 QModelIndex newLocalIndex;
310 QModelIndex newIndex;
312 switch ( positionInList )
315 newLocalIndex = mModel->index( 0, 0 );
319 newLocalIndex = mModel->index( currentRow - 1, 0 );
323 newLocalIndex = mModel->index( currentRow + 1, 0 );
327 newLocalIndex = mModel->index( mModel->
rowCount() - 1, 0 );
332 if ( newIndex.isValid() )
335 scrollTo( newLocalIndex );
341 QModelIndex index = indexAt( event->pos() );
343 if ( index.isValid() )
355 menu->exec( event->globalPos() );
359 void QgsFeatureListView::selectRow(
const QModelIndex &index,
bool anchor )
361 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
362 int row = index.row();
367 if ( selectionMode() != QListView::SingleSelection
368 && command.testFlag( QItemSelectionModel::Toggle ) )
371 mCtrlDragSelectionFlag = mFeatureSelectionModel->
isSelected( index )
372 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
373 command &= ~QItemSelectionModel::Toggle;
374 command |= mCtrlDragSelectionFlag;
376 command |= QItemSelectionModel::Current;
379 QModelIndex tl = model()->index( std::min( mRowAnchor, row ), 0 );
380 QModelIndex br = model()->index( std::max( mRowAnchor, row ), model()->columnCount() - 1 );
382 mFeatureSelectionModel->
selectFeatures( QItemSelection( tl, br ), command );
385 void QgsFeatureListView::ensureEditSelection(
bool inSelection )
395 const QModelIndexList selectedIndexes = mCurrentEditSelectionModel->selectedIndexes();
401 bool editSelectionUpdateRequested =
false;
404 bool validEditSelectionAvailable =
false;
406 if ( selectedIndexes.isEmpty() || !selectedIndexes.first().isValid() || mModel->
mapFromMaster( selectedIndexes.first() ).row() == -1 )
408 validEditSelectionAvailable =
false;
412 validEditSelectionAvailable =
true;
420 if ( !validEditSelectionAvailable )
422 editSelectionUpdateRequested =
true;
429 if ( !selectedFids.contains( mModel->
idxToFid( mModel->
mapFromMaster( selectedIndexes.first() ) ) ) )
431 editSelectionUpdateRequested =
true;
439 if ( !validEditSelectionAvailable )
440 editSelectionUpdateRequested =
true;
443 if ( editSelectionUpdateRequested )
445 if ( !mUpdateEditSelectionTimer.isSingleShot() )
447 mUpdateEditSelectionTimer.setSingleShot(
true );
448 connect( &mUpdateEditSelectionTimer, &QTimer::timeout,
this, [
this, inSelection, validEditSelectionAvailable ]()
455 int rowToSelect = -1;
460 const int rowCount = mModel->
rowCount();
462 for (
int i = 0; i < rowCount; i++ )
464 if ( selectedFids.contains( mModel->
idxToFid( mModel->index( i, 0 ) ) ) )
470 if ( rowToSelect == -1 && !validEditSelectionAvailable )
477 if ( rowToSelect != -1 )
482 mUpdateEditSelectionTimer.setInterval( 0 );
484 mUpdateEditSelectionTimer.start();
490 mFeatureSelectionManager = featureSelectionManager;
492 if ( mFeatureSelectionModel )
496 if ( mOwnedFeatureSelectionManager )
498 mOwnedFeatureSelectionManager->deleteLater();
499 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 id, geometry and a list of field/values...
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