17 #include <QHeaderView> 19 #include <QToolButton> 20 #include <QHBoxLayout> 40 : QTableView( parent )
43 restoreGeometry( settings.
value( QStringLiteral(
"BetterAttributeTable/geometry" ) ).toByteArray() );
46 horizontalHeader()->setHighlightSections(
false );
50 setItemDelegate( mTableDelegate );
52 setEditTriggers( QAbstractItemView::AllEditTriggers );
54 setSelectionBehavior( QAbstractItemView::SelectRows );
55 setSelectionMode( QAbstractItemView::ExtendedSelection );
56 setSortingEnabled(
true );
57 horizontalHeader()->setSortIndicatorShown(
false );
59 verticalHeader()->viewport()->installEventFilter(
this );
61 connect( verticalHeader(), &QHeaderView::sectionPressed,
this, [ = ](
int row ) {
selectRow( row,
true ); } );
63 connect( horizontalHeader(), &QHeaderView::sectionResized,
this, &QgsAttributeTableView::columnSizeChanged );
64 connect( horizontalHeader(), &QHeaderView::sortIndicatorChanged,
this, &QgsAttributeTableView::showHorizontalSortIndicator );
70 if (
object == verticalHeader()->viewport() )
72 switch ( event->type() )
74 case QEvent::MouseButtonPress:
78 case QEvent::MouseButtonRelease:
86 return QTableView::eventFilter(
object, event );
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 )
154 mFeatureSelectionModel =
new QgsFeatureSelectionModel( mFilterModel, mFilterModel, mFeatureSelectionManager, mFilterModel );
155 setSelectionModel( mFeatureSelectionModel );
170 delete mFeatureSelectionManager;
172 mFeatureSelectionManager = featureSelectionManager;
174 if ( mFeatureSelectionModel )
178 QWidget *QgsAttributeTableView::createActionWidget(
QgsFeatureId fid )
182 QToolButton *toolButton =
nullptr;
183 QWidget *container =
nullptr;
187 toolButton =
new QToolButton();
188 toolButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
189 toolButton->setPopupMode( QToolButton::MenuButtonPopup );
190 container = toolButton;
194 container =
new QWidget();
195 container->setLayout(
new QHBoxLayout() );
196 container->layout()->setMargin( 0 );
199 QList< QAction * > actionList;
200 QAction *defaultAction =
nullptr;
203 QList<QgsAction> actions = mFilterModel->
layer()->
actions()->
actions( QStringLiteral(
"Feature" ) );
204 Q_FOREACH (
const QgsAction &action, actions )
210 QAction *act =
new QAction( action.
icon(), actionTitle, container );
211 act->setToolTip( action.
name() );
212 act->setData(
"user_action" );
213 act->setProperty(
"fid", fid );
214 act->setProperty(
"action_id", action.
id() );
215 connect( act, &QAction::triggered,
this, &QgsAttributeTableView::actionTriggered );
227 QAction *action =
new QAction( mapLayerAction->icon(), mapLayerAction->text(), container );
228 action->setData(
"map_layer_action" );
229 action->setToolTip( mapLayerAction->text() );
230 action->setProperty(
"fid", fid );
231 action->setProperty(
"action", qVariantFromValue( qobject_cast<QObject *>( mapLayerAction ) ) );
232 connect( action, &QAction::triggered,
this, &QgsAttributeTableView::actionTriggered );
233 actionList << action;
235 if ( !defaultAction &&
237 defaultAction = action;
240 if ( !defaultAction && !actionList.isEmpty() )
241 defaultAction = actionList.at( 0 );
243 Q_FOREACH ( QAction *act, actionList )
247 toolButton->addAction( act );
249 if ( act == defaultAction )
250 toolButton->setDefaultAction( act );
252 container = toolButton;
256 QToolButton *btn =
new QToolButton;
257 btn->setDefaultAction( act );
258 container->layout()->addWidget( btn );
264 static_cast< QHBoxLayout *
>( container->layout() )->addStretch();
269 if ( toolButton && !toolButton->actions().isEmpty() && actions->defaultAction() == -1 )
270 toolButton->setDefaultAction( toolButton->actions().at( 0 ) );
280 settings.
setValue( QStringLiteral(
"BetterAttributeTable/geometry" ), QVariant(
saveGeometry() ) );
285 setSelectionMode( QAbstractItemView::NoSelection );
286 QTableView::mousePressEvent( event );
287 setSelectionMode( QAbstractItemView::ExtendedSelection );
292 setSelectionMode( QAbstractItemView::NoSelection );
293 QTableView::mouseReleaseEvent( event );
294 setSelectionMode( QAbstractItemView::ExtendedSelection );
299 setSelectionMode( QAbstractItemView::NoSelection );
300 QTableView::mouseMoveEvent( event );
301 setSelectionMode( QAbstractItemView::ExtendedSelection );
306 switch ( event->key() )
315 setSelectionMode( QAbstractItemView::NoSelection );
316 QTableView::keyPressEvent( event );
317 setSelectionMode( QAbstractItemView::ExtendedSelection );
321 QTableView::keyPressEvent( event );
328 Q_FOREACH (
const QModelIndex &index, indexes )
336 setDirtyRegion( viewport()->rect() );
341 QItemSelection selection;
342 selection.append( QItemSelectionRange( mFilterModel->index( 0, 0 ), mFilterModel->index( mFilterModel->rowCount() - 1, 0 ) ) );
343 mFeatureSelectionModel->
selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
349 mActionPopup =
nullptr;
351 QModelIndex idx = indexAt( event->pos() );
352 if ( !idx.isValid() )
361 mActionPopup =
new QMenu(
this );
363 mActionPopup->addAction( tr(
"Select All" ),
this, SLOT(
selectAll() ), QKeySequence::SelectAll );
368 if ( !mActionPopup->actions().isEmpty() )
370 mActionPopup->popup( event->globalPos() );
384 void QgsAttributeTableView::modelDeleted()
386 mFilterModel =
nullptr;
387 mFeatureSelectionManager =
nullptr;
388 mFeatureSelectionModel =
nullptr;
393 if ( selectionBehavior() == QTableView::SelectColumns
394 || ( selectionMode() == QTableView::SingleSelection
395 && selectionBehavior() == QTableView::SelectItems ) )
398 if ( row >= 0 && row < model()->rowCount() )
400 int column = horizontalHeader()->logicalIndexAt( isRightToLeft() ? viewport()->width() : 0 );
401 QModelIndex index = model()->index( row, column );
402 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
403 selectionModel()->setCurrentIndex( index, QItemSelectionModel::NoUpdate );
404 if ( ( anchor && !( command & QItemSelectionModel::Current ) )
405 || ( selectionMode() == QTableView::SingleSelection ) )
406 mRowSectionAnchor = row;
408 if ( selectionMode() != QTableView::SingleSelection
409 && command.testFlag( QItemSelectionModel::Toggle ) )
412 mCtrlDragSelectionFlag = mFeatureSelectionModel->
isSelected( index )
413 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
414 command &= ~QItemSelectionModel::Toggle;
415 command |= mCtrlDragSelectionFlag;
417 command |= QItemSelectionModel::Current;
420 QModelIndex tl = model()->index( std::min( mRowSectionAnchor, row ), 0 );
421 QModelIndex br = model()->index( std::max( mRowSectionAnchor, row ), model()->columnCount() - 1 );
422 if ( verticalHeader()->sectionsMoved() && tl.row() != br.row() )
423 setSelection( visualRect( tl ) | visualRect( br ), command );
425 mFeatureSelectionModel->
selectFeatures( QItemSelection( tl, br ), command );
429 void QgsAttributeTableView::showHorizontalSortIndicator()
431 horizontalHeader()->setSortIndicatorShown(
true );
434 void QgsAttributeTableView::actionTriggered()
436 QAction *action = qobject_cast<QAction *>( sender() );
437 QgsFeatureId fid = action->property(
"fid" ).toLongLong();
442 if ( action->data().toString() == QLatin1String(
"user_action" ) )
446 else if ( action->data().toString() == QLatin1String(
"map_layer_action" ) )
448 QObject *
object = action->property(
"action" ).value<QObject *>();
457 void QgsAttributeTableView::columnSizeChanged(
int index,
int oldWidth,
int newWidth )
463 void QgsAttributeTableView::onActionColumnItemPainted(
const QModelIndex &index )
465 if ( !indexWidget( index ) )
468 mActionWidgets.insert( index, widget );
469 setIndexWidget( index, widget );
473 void QgsAttributeTableView::recreateActionWidgets()
475 QMap< QModelIndex, QWidget * >::const_iterator it = mActionWidgets.constBegin();
476 for ( ; it != mActionWidgets.constEnd(); ++it )
481 setIndexWidget( it.key(), nullptr );
483 mActionWidgets.clear();
QgsActionManager * actions()
Returns all layer actions defined on this layer.
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.
QSet< QgsFeatureId > QgsFeatureIds
void willShowContextMenu(QMenu *menu, const QModelIndex &atIndex)
Is emitted, in order to provide a hook to add additional* menu entries to the context menu...
QgsAttributeTableView(QWidget *parent=nullptr)
Constructor for QgsAttributeTableView.
This class is a composition of two QSettings instances:
void readOnlyChanged()
Emitted when the read only state of this layer is changed.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
virtual void selectFeatures(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
Select features on this table.
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...
ActionWidgetStyle actionWidgetStyle() const
Gets the style of the action widget.
void selectAll() override
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.
void saveGeometry(QWidget *widget, const QString &keyName)
Save the wigget geometry into settings.
Get the feature id of the feature in this row.
QgsVectorLayer * layer() const
Returns the layer this filter acts on.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
bool restoreGeometry(QWidget *widget, const QString &keyName)
Restore the wigget geometry from settings.
QString name() const
The name of the action. This may be a longer description.
void requestRepaint()
Request a repaint of the visible items of connected views.
QgsVectorLayerCache * layerCache() const
Returns the layerCache this filter acts on.
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()
Is emitted, when edited changes successfully have been written to the data provider.
void mousePressEvent(QMouseEvent *event) override
Called for mouse press events on a table cell.
bool hidden
Flag that controls if the column is hidden.
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()
Is emitted, when editing on this layer has started.
QUuid id() const
Returns a unique id for this action.
QList< QgsFeatureId > selectedFeaturesIds() const
Returns the selected features in the attribute table in table sorted order.
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.
int width
Width of column, or -1 for default width.
QString shortTitle() const
The short title is used to label user interface elements like buttons.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
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...
Defines the configuration of a column in the attribute table.
virtual void selectRow(int row)
void actionColumnItemPainted(const QModelIndex &index) const
Is emitted when an action column item is painted.
virtual void _q_selectRow(int row)
bool nextFeature(QgsFeature &f)
QList< QgsAction > actions(const QString &actionScope=QString()) const
Returns a list of actions that are available in the given action scope.
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.
void triggerForFeature(QgsMapLayer *layer, const QgsFeature *feature)
Triggers the action with the specified layer and feature.
bool isEnabledOnlyWhenEditable() const
Returns whether only enabled in editable mode.
An action which can run on map layers.
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.
QIcon icon() const
The icon.
QModelIndex fidToIndex(QgsFeatureId fid) override