17 #include <QHeaderView> 19 #include <QToolButton> 20 #include <QHBoxLayout> 40 : QTableView( parent )
45 horizontalHeader()->setHighlightSections(
false );
49 setItemDelegate( mTableDelegate );
51 setEditTriggers( QAbstractItemView::AllEditTriggers );
53 setSelectionBehavior( QAbstractItemView::SelectRows );
54 setSelectionMode( QAbstractItemView::ExtendedSelection );
55 setSortingEnabled(
true );
56 horizontalHeader()->setSortIndicatorShown(
false );
58 verticalHeader()->viewport()->installEventFilter(
this );
60 connect( verticalHeader(), &QHeaderView::sectionPressed,
this, [ = ](
int row ) {
selectRow( row,
true ); } );
62 connect( horizontalHeader(), &QHeaderView::sectionResized,
this, &QgsAttributeTableView::columnSizeChanged );
63 connect( horizontalHeader(), &QHeaderView::sortIndicatorChanged,
this, &QgsAttributeTableView::showHorizontalSortIndicator );
69 if (
object == verticalHeader()->viewport() )
71 switch ( event->type() )
73 case QEvent::MouseButtonPress:
77 case QEvent::MouseButtonRelease:
85 return QTableView::eventFilter(
object, event );
91 const auto constColumns = config.
columns();
94 if ( columnConfig.hidden )
97 if ( columnConfig.width >= 0 )
99 setColumnWidth( i, columnConfig.width );
103 setColumnWidth( i, horizontalHeader()->defaultSectionSize() );
116 QModelIndexList indexList;
119 QModelIndex index = mFilterModel->
fidToIndex(
id );
123 std::sort( indexList.begin(), indexList.end() );
124 QList<QgsFeatureId> ids;
125 for (
const QModelIndex &index : indexList )
135 mFilterModel = filterModel;
136 QTableView::setModel( mFilterModel );
140 connect( mFilterModel, &QObject::destroyed,
this, &QgsAttributeTableView::modelDeleted );
144 delete mFeatureSelectionModel;
145 mFeatureSelectionModel =
nullptr;
149 if ( !mFeatureSelectionManager )
152 mFeatureSelectionManager = mOwnedFeatureSelectionManager;
155 mFeatureSelectionModel =
new QgsFeatureSelectionModel( mFilterModel, mFilterModel, mFeatureSelectionManager, mFilterModel );
156 setSelectionModel( mFeatureSelectionModel );
171 mFeatureSelectionManager = featureSelectionManager;
173 if ( mFeatureSelectionModel )
177 if ( mOwnedFeatureSelectionManager )
179 mOwnedFeatureSelectionManager->deleteLater();
180 mOwnedFeatureSelectionManager =
nullptr;
184 QWidget *QgsAttributeTableView::createActionWidget(
QgsFeatureId fid )
188 QToolButton *toolButton =
nullptr;
189 QWidget *container =
nullptr;
193 toolButton =
new QToolButton();
194 toolButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
195 toolButton->setPopupMode( QToolButton::MenuButtonPopup );
196 container = toolButton;
200 container =
new QWidget();
201 container->setLayout(
new QHBoxLayout() );
202 container->layout()->setMargin( 0 );
205 QList< QAction * > actionList;
206 QAction *defaultAction =
nullptr;
209 QList<QgsAction> actions = mFilterModel->
layer()->
actions()->
actions( QStringLiteral(
"Feature" ) );
210 const auto constActions = actions;
211 for (
const QgsAction &action : constActions )
213 if ( !mFilterModel->
layer()->
isEditable() && action.isEnabledOnlyWhenEditable() )
216 QString actionTitle = !action.shortTitle().isEmpty() ? action.shortTitle() : action.icon().isNull() ? action.name() : QString();
217 QAction *act =
new QAction( action.icon(), actionTitle, container );
218 act->setToolTip( action.name() );
219 act->setData(
"user_action" );
220 act->setProperty(
"fid", fid );
221 act->setProperty(
"action_id", action.id() );
222 connect( act, &QAction::triggered,
this, &QgsAttributeTableView::actionTriggered );
233 QAction *action =
new QAction( mapLayerAction->icon(), mapLayerAction->text(), container );
234 action->setData(
"map_layer_action" );
235 action->setToolTip( mapLayerAction->text() );
236 action->setProperty(
"fid", fid );
237 action->setProperty(
"action", qVariantFromValue( qobject_cast<QObject *>( mapLayerAction ) ) );
238 connect( action, &QAction::triggered,
this, &QgsAttributeTableView::actionTriggered );
239 actionList << action;
241 if ( !defaultAction &&
243 defaultAction = action;
246 if ( !defaultAction && !actionList.isEmpty() )
247 defaultAction = actionList.at( 0 );
249 const auto constActionList = actionList;
250 for ( QAction *act : constActionList )
254 toolButton->addAction( act );
256 if ( act == defaultAction )
257 toolButton->setDefaultAction( act );
259 container = toolButton;
263 QToolButton *btn =
new QToolButton;
264 btn->setDefaultAction( act );
265 container->layout()->addWidget( btn );
271 static_cast< QHBoxLayout *
>( container->layout() )->addStretch();
276 if ( toolButton && !toolButton->actions().isEmpty() && actions->defaultAction() == -1 )
277 toolButton->setDefaultAction( toolButton->actions().at( 0 ) );
290 setSelectionMode( QAbstractItemView::NoSelection );
291 QTableView::mousePressEvent( event );
292 setSelectionMode( QAbstractItemView::ExtendedSelection );
297 setSelectionMode( QAbstractItemView::NoSelection );
298 QTableView::mouseReleaseEvent( event );
299 setSelectionMode( QAbstractItemView::ExtendedSelection );
304 setSelectionMode( QAbstractItemView::NoSelection );
305 QTableView::mouseMoveEvent( event );
306 setSelectionMode( QAbstractItemView::ExtendedSelection );
311 switch ( event->key() )
320 setSelectionMode( QAbstractItemView::NoSelection );
321 QTableView::keyPressEvent( event );
322 setSelectionMode( QAbstractItemView::ExtendedSelection );
326 QTableView::keyPressEvent( event );
333 const auto constIndexes = indexes;
334 for (
const QModelIndex &index : constIndexes )
342 setDirtyRegion( viewport()->rect() );
347 QItemSelection selection;
348 selection.append( QItemSelectionRange( mFilterModel->index( 0, 0 ), mFilterModel->index( mFilterModel->rowCount() - 1, 0 ) ) );
349 mFeatureSelectionModel->
selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
355 mActionPopup =
nullptr;
357 QModelIndex idx = indexAt( event->pos() );
358 if ( !idx.isValid() )
367 mActionPopup =
new QMenu(
this );
369 mActionPopup->addAction( tr(
"Select All" ),
this, SLOT(
selectAll() ), QKeySequence::SelectAll );
374 if ( !mActionPopup->actions().isEmpty() )
376 mActionPopup->popup( event->globalPos() );
390 void QgsAttributeTableView::modelDeleted()
392 mFilterModel =
nullptr;
393 mFeatureSelectionManager =
nullptr;
394 mFeatureSelectionModel =
nullptr;
399 if ( selectionBehavior() == QTableView::SelectColumns
400 || ( selectionMode() == QTableView::SingleSelection
401 && selectionBehavior() == QTableView::SelectItems ) )
404 if ( row >= 0 && row < model()->rowCount() )
406 int column = horizontalHeader()->logicalIndexAt( isRightToLeft() ? viewport()->width() : 0 );
407 QModelIndex index = model()->index( row, column );
408 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
409 selectionModel()->setCurrentIndex( index, QItemSelectionModel::NoUpdate );
410 if ( ( anchor && !( command & QItemSelectionModel::Current ) )
411 || ( selectionMode() == QTableView::SingleSelection ) )
412 mRowSectionAnchor = row;
414 if ( selectionMode() != QTableView::SingleSelection
415 && command.testFlag( QItemSelectionModel::Toggle ) )
418 mCtrlDragSelectionFlag = mFeatureSelectionModel->
isSelected( index )
419 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
420 command &= ~QItemSelectionModel::Toggle;
421 command |= mCtrlDragSelectionFlag;
423 command |= QItemSelectionModel::Current;
426 QModelIndex tl = model()->index( std::min( mRowSectionAnchor, row ), 0 );
427 QModelIndex br = model()->index( std::max( mRowSectionAnchor, row ), model()->columnCount() - 1 );
428 if ( verticalHeader()->sectionsMoved() && tl.row() != br.row() )
429 setSelection( visualRect( tl ) | visualRect( br ), command );
431 mFeatureSelectionModel->
selectFeatures( QItemSelection( tl, br ), command );
435 void QgsAttributeTableView::showHorizontalSortIndicator()
437 horizontalHeader()->setSortIndicatorShown(
true );
440 void QgsAttributeTableView::actionTriggered()
442 QAction *action = qobject_cast<QAction *>( sender() );
443 QgsFeatureId fid = action->property(
"fid" ).toLongLong();
448 if ( action->data().toString() == QLatin1String(
"user_action" ) )
452 else if ( action->data().toString() == QLatin1String(
"map_layer_action" ) )
454 QObject *
object = action->property(
"action" ).value<QObject *>();
463 void QgsAttributeTableView::columnSizeChanged(
int index,
int oldWidth,
int newWidth )
469 void QgsAttributeTableView::onActionColumnItemPainted(
const QModelIndex &index )
471 if ( !indexWidget( index ) )
474 mActionWidgets.insert( index, widget );
475 setIndexWidget( index, widget );
479 void QgsAttributeTableView::recreateActionWidgets()
481 QMap< QModelIndex, QWidget * >::const_iterator it = mActionWidgets.constBegin();
482 for ( ; it != mActionWidgets.constEnd(); ++it )
487 setIndexWidget( it.key(), nullptr );
489 mActionWidgets.clear();
QgsActionManager * actions()
Returns all layer actions defined on this layer.
QgsVectorLayer * layer() const
Returns the layer this filter acts on.
QVariant data(const QModelIndex &index, int role) const override
Provides a table view of features of a QgsVectorLayer.
virtual bool isSelected(QgsFeatureId fid)
Returns the selection status of a given feature id.
void doAction(QUuid actionId, const QgsFeature &feature, int defaultValueIndex=0, const QgsExpressionContextScope &scope=QgsExpressionContextScope())
Does the given action.
void triggerForFeature(QgsMapLayer *layer, const QgsFeature &feature)
Triggers the action with the specified layer and feature.
QSet< QgsFeatureId > QgsFeatureIds
void willShowContextMenu(QMenu *menu, const QModelIndex &atIndex)
Emitted in order to provide a hook to add additional* menu entries to the context menu...
QgsAttributeTableView(QWidget *parent=nullptr)
Constructor for QgsAttributeTableView.
void readOnlyChanged()
Emitted when the read only state of this layer is changed.
virtual void selectFeatures(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
Select features on this table.
QList< QgsAction > actions(const QString &actionScope=QString()) const
Returns a list of actions that are available in the given action scope.
void columnResized(int column, int width)
Emitted when a column in the view has been resized.
bool eventFilter(QObject *object, QEvent *event) override
This event filter is installed on the verticalHeader to intercept mouse press and release events...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static QgsGui * instance()
Returns a pointer to the singleton instance.
void selectAll() override
void actionColumnItemPainted(const QModelIndex &index) const
Emitted when an action column item is painted.
void enableSync(bool enable)
Enables or disables synchronisation to the QgsVectorLayer When synchronisation is disabled...
void setFeatureSelectionModel(QgsFeatureSelectionModel *featureSelectionModel)
void mouseReleaseEvent(QMouseEvent *event) override
Called for mouse release events on a table cell.
Get the feature id of the feature in this row.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
ActionWidgetStyle actionWidgetStyle() const
Gets the style of the action widget.
void requestRepaint()
Request a repaint of the visible items of connected views.
Utility class that encapsulates an action based on vector attributes.
virtual const QgsFeatureIds & selectedFeatureIds() const =0
Returns reference to identifiers of selected features.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
void mousePressEvent(QMouseEvent *event) override
Called for mouse press events on a table cell.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
virtual void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
void changed()
Triggered when an action is added or removed from the registry.
QgsAction defaultAction(const QString &actionScope)
Each scope can have a default action.
virtual void setModel(QgsAttributeTableFilterModel *filterModel)
void editingStarted()
Emitted when editing on this layer has started.
void mouseMoveEvent(QMouseEvent *event) override
Called for mouse move events on a table cell.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
A tool button with a drop-down to select the current action.
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
setFeatureSelectionManager
A delegate item class for QgsAttributeTable (see Qt documentation for QItemDelegate).
void setAttributeTableConfig(const QgsAttributeTableConfig &config)
Set the attribute table config which should be used to control the appearance of the attribute table...
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
QList< QgsMapLayerAction * > mapLayerActions(QgsMapLayer *layer, QgsMapLayerAction::Targets targets=QgsMapLayerAction::AllActions)
Returns the map layer actions which can run on the specified layer.
Defines the configuration of a column in the attribute table.
virtual void selectRow(int row)
QUuid id() const
Returns a unique id for this action.
virtual void _q_selectRow(int row)
bool nextFeature(QgsFeature &f)
This is a container for configuration of the attribute table.
Is an interface class to abstract feature selection handling.
void closeEvent(QCloseEvent *event) override
Saves geometry to the settings on close.
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &featureRequest=QgsFeatureRequest())
Query this VectorLayerCache for features.
static QgsMapLayerActionRegistry * mapLayerActionRegistry()
Returns the global map layer action registry, used for registering map layer actions.
An action which can run on map layers.
QList< QgsFeatureId > selectedFeaturesIds() const
Returns the selected features in the attribute table in table sorted order.
void keyPressEvent(QKeyEvent *event) override
Called for key press events Disables selection change by only pressing an arrow key.
void contextMenuEvent(QContextMenuEvent *event) override
Is called when the context menu will be shown.
QgsVectorLayerCache * layerCache() const
Returns the layerCache this filter acts on.
QModelIndex fidToIndex(QgsFeatureId fid) override