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.
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.
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:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void readOnlyChanged()
Emitted when the read only state of this layer is changed.
bool isEnabledOnlyWhenEditable() const
Returns whether only enabled in editable mode.
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...
QString shortTitle() const
The short title is used to label user interface elements like buttons.
void selectAll() override
void actionColumnItemPainted(const QModelIndex &index) const
Is 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.
void saveGeometry(QWidget *widget, const QString &keyName)
Save the wigget geometry into settings.
Get the feature id of the feature in this row.
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.
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()
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)
QIcon icon() const
The icon.
QString name() const
The name of the action. This may be a longer description.
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.
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.
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)
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.
void triggerForFeature(QgsMapLayer *layer, const QgsFeature *feature)
Triggers the action with the specified layer and feature.
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