26#include "moc_qgsfeaturelistview.cpp"
37 setSelectionMode( QAbstractItemView::ExtendedSelection );
39 mUpdateEditSelectionTimerWithSelection.setSingleShot(
true );
40 connect( &mUpdateEditSelectionTimerWithSelection, &QTimer::timeout,
this, [
this ]()
42 updateEditSelection(
true );
45 mUpdateEditSelectionTimerWithSelection.setInterval( 0 );
47 mUpdateEditSelectionTimerWithoutSelection.setSingleShot(
true );
48 connect( &mUpdateEditSelectionTimerWithoutSelection, &QTimer::timeout,
this, [
this ]()
50 updateEditSelection(
false );
53 mUpdateEditSelectionTimerWithoutSelection.setInterval( 0 );
66 delete mFeatureSelectionModel;
67 delete mCurrentEditSelectionModel;
69 mCurrentEditSelectionModel =
new QItemSelectionModel( mModel->
masterModel(),
this );
70 if ( !mFeatureSelectionManager )
73 mFeatureSelectionManager = mOwnedFeatureSelectionManager;
77 setSelectionModel( mFeatureSelectionModel );
80 ensureEditSelection( true );
83 if ( mItemDelegate && mItemDelegate->parent() ==
this )
90 setItemDelegate( mItemDelegate );
97 connect( mCurrentEditSelectionModel, &QItemSelectionModel::selectionChanged,
this, &QgsFeatureListView::editSelectionChanged );
99 connect(
featureListModel, &QgsFeatureListModel::rowsRemoved,
this, [
this ]() { ensureEditSelection(); } );
100 connect(
featureListModel, &QgsFeatureListModel::rowsInserted,
this, [
this ]() { ensureEditSelection(); } );
101 connect(
featureListModel, &QgsFeatureListModel::modelReset,
this, [
this ]() { ensureEditSelection(); } );
130 const QModelIndexList selectedIndexes = mCurrentEditSelectionModel->selectedIndexes();
131 for (
const QModelIndex &idx : selectedIndexes )
141 viewport()->update( visualRegionForSelection( mCurrentEditSelectionModel->selection() ) );
146 if ( event->button() != Qt::LeftButton )
148 QListView::mousePressEvent( event );
154 const QPoint pos =
event->pos();
156 const QModelIndex index = indexAt( pos );
160 mDragMode = DragMode::MoveSelection;
161 if ( index.isValid() )
166 mDragMode = DragMode::ExpandSelection;
168 selectRow( index,
true );
174 QgsDebugError( QStringLiteral(
"No model assigned to this view" ) );
178void QgsFeatureListView::editSelectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected )
180 if ( isVisible() && updatesEnabled() )
184 viewport()->update( visualRegionForSelection( localDeselected ) | visualRegionForSelection( localSelected ) );
188 if ( !selected.isEmpty() )
190 const QModelIndexList indexList = selected.indexes();
191 if ( !indexList.isEmpty() )
195 mLastEditSelectionFid = selectedFeature.
id();
199 const QItemSelection currentSelection = mCurrentEditSelectionModel->selection();
200 if ( currentSelection.size() == 1 )
202 QModelIndexList indexList = currentSelection.indexes();
203 if ( !indexList.isEmpty() )
220 QItemSelection selection;
221 selection.append( QItemSelectionRange( mModel->index( 0, 0 ), mModel->index( mModel->
rowCount() - 1, 0 ) ) );
223 mFeatureSelectionModel->
selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
228 QItemSelection selection;
229 QModelIndex firstModelIdx;
231 const auto constFids = fids;
234 const QModelIndex modelIdx = mModel->
fidToIdx( fid );
236 if ( ! firstModelIdx.isValid() )
237 firstModelIdx = modelIdx;
239 selection.append( QItemSelectionRange( mModel->
mapToMaster( modelIdx ) ) );
247 mCurrentEditSelectionModel->select( selection, QItemSelectionModel::ClearAndSelect );
248 scrollTo( firstModelIdx );
258 Q_ASSERT( index.model() == mModel->
masterModel() || !index.isValid() );
262 mCurrentEditSelectionModel->select( index, command );
269 const auto constIndexes = indexes;
270 for (
const QModelIndex &index : constIndexes )
278 setDirtyRegion( viewport()->rect() );
285 const QPoint pos =
event->pos();
286 const QModelIndex index = indexAt( pos );
290 case QgsFeatureListView::DragMode::Inactive:
293 case QgsFeatureListView::DragMode::ExpandSelection:
295 selectRow( index,
false );
299 case QgsFeatureListView::DragMode::MoveSelection:
301 if ( index.isValid() )
309 QgsDebugError( QStringLiteral(
"No model assigned to this view" ) );
315 if ( event->button() != Qt::LeftButton )
317 QListView::mouseReleaseEvent( event );
323 case QgsFeatureListView::DragMode::ExpandSelection:
324 if ( mFeatureSelectionModel )
327 case QgsFeatureListView::DragMode::Inactive:
328 case QgsFeatureListView::DragMode::MoveSelection:
332 mDragMode = DragMode::Inactive;
337 switch ( event->key() )
340 editOtherFeature( Previous );
344 editOtherFeature( Next );
348 QListView::keyPressEvent( event );
352void QgsFeatureListView::editOtherFeature( QgsFeatureListView::PositionInList positionInList )
355 if ( 0 != mCurrentEditSelectionModel->selectedIndexes().count() )
357 const QModelIndex localIndex = mModel->
mapFromMaster( mCurrentEditSelectionModel->selectedIndexes().first() );
358 currentRow = localIndex.row();
361 QModelIndex newLocalIndex;
362 QModelIndex newIndex;
364 switch ( positionInList )
367 newLocalIndex = mModel->index( 0, 0 );
371 newLocalIndex = mModel->index( currentRow - 1, 0 );
375 newLocalIndex = mModel->index( currentRow + 1, 0 );
379 newLocalIndex = mModel->index( mModel->
rowCount() - 1, 0 );
384 if ( newIndex.isValid() )
387 scrollTo( newLocalIndex );
393 const QModelIndex index = indexAt( event->pos() );
395 if ( index.isValid() )
407 menu->exec( event->globalPos() );
411void QgsFeatureListView::selectRow(
const QModelIndex &index,
bool anchor )
413 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
414 const int row = index.row();
419 if ( selectionMode() != QListView::SingleSelection
420 && command.testFlag( QItemSelectionModel::Toggle ) )
423 mCtrlDragSelectionFlag = mFeatureSelectionModel->
isSelected( index )
424 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
425 command &= ~QItemSelectionModel::Toggle;
426 command |= mCtrlDragSelectionFlag;
428 command |= QItemSelectionModel::Current;
431 const QModelIndex tl = model()->index( std::min( mRowAnchor, row ), 0 );
432 const QModelIndex br = model()->index( std::max( mRowAnchor, row ), model()->columnCount() - 1 );
434 mFeatureSelectionModel->
selectFeatures( QItemSelection( tl, br ), command );
437void QgsFeatureListView::ensureEditSelection(
bool inSelection )
442 mUpdateEditSelectionTimerWithSelection.start();
446 mUpdateEditSelectionTimerWithoutSelection.start();
450void QgsFeatureListView::updateEditSelection(
bool inSelection )
460 const QModelIndexList selectedIndexes = mCurrentEditSelectionModel->selectedIndexes();
466 bool editSelectionUpdateRequested =
false;
469 bool validEditSelectionAvailable =
false;
471 if ( selectedIndexes.isEmpty() || !selectedIndexes.first().isValid() || mModel->
mapFromMaster( selectedIndexes.first() ).row() == -1 )
473 validEditSelectionAvailable =
false;
477 validEditSelectionAvailable =
true;
485 if ( !validEditSelectionAvailable )
487 editSelectionUpdateRequested =
true;
494 if ( !selectedFids.contains( mModel->
idxToFid( mModel->
mapFromMaster( selectedIndexes.first() ) ) ) )
496 editSelectionUpdateRequested =
true;
504 if ( !validEditSelectionAvailable )
505 editSelectionUpdateRequested =
true;
508 if ( editSelectionUpdateRequested )
515 int rowToSelect = -1;
525 if ( selectedFids.isEmpty() )
531 const int rowCount = mModel->
rowCount();
532 for (
int i = 0; i < rowCount; i++ )
534 if ( selectedFids.contains( mModel->
idxToFid( mModel->index( i, 0 ) ) ) )
541 if ( rowToSelect == -1 && !validEditSelectionAvailable )
547 if ( rowToSelect != -1 )
556 mFeatureSelectionManager = featureSelectionManager;
558 if ( mFeatureSelectionModel )
562 if ( mOwnedFeatureSelectionManager )
564 mOwnedFeatureSelectionManager->deleteLater();
565 mOwnedFeatureSelectionManager =
nullptr;
@ FeatureId
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
#define QgsDebugError(str)