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:
97 if ( columnConfig.
width >= 0 )
99 setColumnWidth( i, columnConfig.
width );
103 setColumnWidth( i, horizontalHeader()->defaultSectionSize() );
111 mFilterModel = filterModel;
112 QTableView::setModel( mFilterModel );
116 connect( mFilterModel, &QObject::destroyed,
this, &QgsAttributeTableView::modelDeleted );
120 delete mFeatureSelectionModel;
121 mFeatureSelectionModel =
nullptr;
125 if ( !mFeatureSelectionManager )
130 mFeatureSelectionModel =
new QgsFeatureSelectionModel( mFilterModel, mFilterModel, mFeatureSelectionManager, mFilterModel );
131 setSelectionModel( mFeatureSelectionModel );
146 if ( mFeatureSelectionManager )
147 delete mFeatureSelectionManager;
149 mFeatureSelectionManager = featureSelectionManager;
151 if ( mFeatureSelectionModel )
155 QWidget *QgsAttributeTableView::createActionWidget(
QgsFeatureId fid )
159 QToolButton *toolButton =
nullptr;
160 QWidget *container =
nullptr;
164 toolButton =
new QToolButton();
165 toolButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
166 toolButton->setPopupMode( QToolButton::MenuButtonPopup );
167 container = toolButton;
171 container =
new QWidget();
172 container->setLayout(
new QHBoxLayout() );
173 container->layout()->setMargin( 0 );
176 QList< QAction * > actionList;
177 QAction *defaultAction =
nullptr;
180 QList<QgsAction> actions = mFilterModel->
layer()->
actions()->
actions( QStringLiteral(
"Feature" ) );
181 Q_FOREACH (
const QgsAction &action, actions )
186 QString actionTitle = !action.
shortTitle().isEmpty() ? action.
shortTitle() : action.
icon().isNull() ? action.
name() : QLatin1String(
"" );
187 QAction *act =
new QAction( action.
icon(), actionTitle, container );
188 act->setToolTip( action.
name() );
189 act->setData(
"user_action" );
190 act->setProperty(
"fid", fid );
191 act->setProperty(
"action_id", action.
id() );
192 connect( act, &QAction::triggered,
this, &QgsAttributeTableView::actionTriggered );
204 QAction *action =
new QAction( mapLayerAction->icon(), mapLayerAction->text(), container );
205 action->setData(
"map_layer_action" );
206 action->setToolTip( mapLayerAction->text() );
207 action->setProperty(
"fid", fid );
208 action->setProperty(
"action", qVariantFromValue( qobject_cast<QObject *>( mapLayerAction ) ) );
209 connect( action, &QAction::triggered,
this, &QgsAttributeTableView::actionTriggered );
210 actionList << action;
212 if ( !defaultAction &&
214 defaultAction = action;
217 if ( !defaultAction && !actionList.isEmpty() )
218 defaultAction = actionList.at( 0 );
220 Q_FOREACH ( QAction *act, actionList )
224 toolButton->addAction( act );
226 if ( act == defaultAction )
227 toolButton->setDefaultAction( act );
229 container = toolButton;
233 QToolButton *btn =
new QToolButton;
234 btn->setDefaultAction( act );
235 container->layout()->addWidget( btn );
241 static_cast< QHBoxLayout *
>( container->layout() )->addStretch();
246 if ( toolButton && !toolButton->actions().isEmpty() && actions->defaultAction() == -1 )
247 toolButton->setDefaultAction( toolButton->actions().at( 0 ) );
257 settings.
setValue( QStringLiteral(
"BetterAttributeTable/geometry" ), QVariant(
saveGeometry() ) );
262 setSelectionMode( QAbstractItemView::NoSelection );
263 QTableView::mousePressEvent( event );
264 setSelectionMode( QAbstractItemView::ExtendedSelection );
269 setSelectionMode( QAbstractItemView::NoSelection );
270 QTableView::mouseReleaseEvent( event );
271 setSelectionMode( QAbstractItemView::ExtendedSelection );
276 setSelectionMode( QAbstractItemView::NoSelection );
277 QTableView::mouseMoveEvent( event );
278 setSelectionMode( QAbstractItemView::ExtendedSelection );
283 switch ( event->key() )
292 setSelectionMode( QAbstractItemView::NoSelection );
293 QTableView::keyPressEvent( event );
294 setSelectionMode( QAbstractItemView::ExtendedSelection );
298 QTableView::keyPressEvent( event );
305 Q_FOREACH (
const QModelIndex &index, indexes )
313 setDirtyRegion( viewport()->rect() );
318 QItemSelection selection;
319 selection.append( QItemSelectionRange( mFilterModel->index( 0, 0 ), mFilterModel->index( mFilterModel->rowCount() - 1, 0 ) ) );
320 mFeatureSelectionModel->
selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
326 mActionPopup =
nullptr;
328 QModelIndex idx = indexAt( event->pos() );
329 if ( !idx.isValid() )
338 mActionPopup =
new QMenu(
this );
340 mActionPopup->addAction( tr(
"Select All" ),
this, SLOT(
selectAll() ), QKeySequence::SelectAll );
345 if ( !mActionPopup->actions().isEmpty() )
347 mActionPopup->popup( event->globalPos() );
361 void QgsAttributeTableView::modelDeleted()
363 mFilterModel =
nullptr;
364 mFeatureSelectionManager =
nullptr;
365 mFeatureSelectionModel =
nullptr;
370 if ( selectionBehavior() == QTableView::SelectColumns
371 || ( selectionMode() == QTableView::SingleSelection
372 && selectionBehavior() == QTableView::SelectItems ) )
375 if ( row >= 0 && row < model()->rowCount() )
377 int column = horizontalHeader()->logicalIndexAt( isRightToLeft() ? viewport()->width() : 0 );
378 QModelIndex index = model()->index( row, column );
379 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
380 selectionModel()->setCurrentIndex( index, QItemSelectionModel::NoUpdate );
381 if ( ( anchor && !( command & QItemSelectionModel::Current ) )
382 || ( selectionMode() == QTableView::SingleSelection ) )
383 mRowSectionAnchor = row;
385 if ( selectionMode() != QTableView::SingleSelection
386 && command.testFlag( QItemSelectionModel::Toggle ) )
389 mCtrlDragSelectionFlag = mFeatureSelectionModel->
isSelected( index )
390 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
391 command &= ~QItemSelectionModel::Toggle;
392 command |= mCtrlDragSelectionFlag;
394 command |= QItemSelectionModel::Current;
397 QModelIndex tl = model()->index( std::min( mRowSectionAnchor, row ), 0 );
398 QModelIndex br = model()->index( std::max( mRowSectionAnchor, row ), model()->columnCount() - 1 );
399 if ( verticalHeader()->sectionsMoved() && tl.row() != br.row() )
400 setSelection( visualRect( tl ) | visualRect( br ), command );
402 mFeatureSelectionModel->
selectFeatures( QItemSelection( tl, br ), command );
406 void QgsAttributeTableView::showHorizontalSortIndicator()
408 horizontalHeader()->setSortIndicatorShown(
true );
411 void QgsAttributeTableView::actionTriggered()
413 QAction *action = qobject_cast<QAction *>( sender() );
414 QgsFeatureId fid = action->property(
"fid" ).toLongLong();
419 if ( action->data().toString() == QLatin1String(
"user_action" ) )
423 else if ( action->data().toString() == QLatin1String(
"map_layer_action" ) )
425 QObject *
object = action->property(
"action" ).value<QObject *>();
434 void QgsAttributeTableView::columnSizeChanged(
int index,
int oldWidth,
int newWidth )
440 void QgsAttributeTableView::onActionColumnItemPainted(
const QModelIndex &index )
442 if ( !indexWidget( index ) )
445 mActionWidgets.insert( index, widget );
446 setIndexWidget( index, widget );
450 void QgsAttributeTableView::recreateActionWidgets()
452 QMap< QModelIndex, QWidget * >::const_iterator it = mActionWidgets.constBegin();
453 for ( ; it != mActionWidgets.constEnd(); ++it )
458 setIndexWidget( it.key(), nullptr );
460 mActionWidgets.clear();
QgsActionManager * actions()
Get 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 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.
bool isEnabledOnlyWhenEditable() const
Return 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
Return 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
bool isEditable() const override
Returns true if the provider is in editing mode.
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 restoreGeometry(QWidget *widget, const QString &keyName)
Restore the wigget geometry from settings.
void setValue(const QString &key, const QVariant &value, const QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
ActionWidgetStyle actionWidgetStyle() const
Get 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.
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
Get the list with all columns and their configuration.
QgsAttributeTableConfig attributeTableConfig() const
Get the attribute table configuration object.
int width
Width of column, or -1 for default width.
A tool button with a drop-down to select the current action.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
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.
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.