22 #include "qgsexpression.h" 33 #include <QHBoxLayout> 39 QVBoxLayout *topLayout =
new QVBoxLayout(
this );
40 topLayout->setContentsMargins( 0, 9, 0, 0 );
41 setLayout( topLayout );
44 QHBoxLayout *buttonLayout =
new QHBoxLayout();
45 buttonLayout->setContentsMargins( 0, 0, 0, 0 );
47 mToggleEditingButton =
new QToolButton(
this );
48 mToggleEditingButton->setObjectName( QStringLiteral(
"mToggleEditingButton" ) );
50 mToggleEditingButton->setText( tr(
"Toggle editing" ) );
51 mToggleEditingButton->setEnabled(
false );
52 mToggleEditingButton->setCheckable(
true );
53 mToggleEditingButton->setToolTip( tr(
"Toggle editing mode for child layer" ) );
54 buttonLayout->addWidget( mToggleEditingButton );
56 mSaveEditsButton =
new QToolButton(
this );
58 mSaveEditsButton->setText( tr(
"Save child layer edits" ) );
59 mSaveEditsButton->setToolTip( tr(
"Save child layer edits" ) );
60 mSaveEditsButton->setEnabled(
true );
61 buttonLayout->addWidget( mSaveEditsButton );
63 mAddFeatureButton =
new QToolButton(
this );
65 mAddFeatureButton->setText( tr(
"Add child feature" ) );
66 mAddFeatureButton->setToolTip( tr(
"Add child feature" ) );
67 mAddFeatureButton->setObjectName( QStringLiteral(
"mAddFeatureButton" ) );
68 buttonLayout->addWidget( mAddFeatureButton );
70 mDuplicateFeatureButton =
new QToolButton(
this );
72 mDuplicateFeatureButton->setText( tr(
"Duplicate child feature" ) );
73 mDuplicateFeatureButton->setToolTip( tr(
"Duplicate child feature" ) );
74 mDuplicateFeatureButton->setObjectName( QStringLiteral(
"mDuplicateFeatureButton" ) );
75 buttonLayout->addWidget( mDuplicateFeatureButton );
77 mDeleteFeatureButton =
new QToolButton(
this );
79 mDeleteFeatureButton->setText( tr(
"Delete child feature" ) );
80 mDeleteFeatureButton->setToolTip( tr(
"Delete child feature" ) );
81 mDeleteFeatureButton->setObjectName( QStringLiteral(
"mDeleteFeatureButton" ) );
82 buttonLayout->addWidget( mDeleteFeatureButton );
84 mLinkFeatureButton =
new QToolButton(
this );
86 mLinkFeatureButton->setText( tr(
"Link existing features" ) );
87 mLinkFeatureButton->setToolTip( tr(
"Link existing child features" ) );
88 mLinkFeatureButton->setObjectName( QStringLiteral(
"mLinkFeatureButton" ) );
89 buttonLayout->addWidget( mLinkFeatureButton );
91 mUnlinkFeatureButton =
new QToolButton(
this );
93 mUnlinkFeatureButton->setText( tr(
"Unlink feature" ) );
94 mUnlinkFeatureButton->setToolTip( tr(
"Unlink child feature" ) );
95 mUnlinkFeatureButton->setObjectName( QStringLiteral(
"mUnlinkFeatureButton" ) );
96 buttonLayout->addWidget( mUnlinkFeatureButton );
98 buttonLayout->addItem(
new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
100 mFormViewButton =
new QToolButton(
this );
101 mFormViewButton->setText( tr(
"Form view" ) );
102 mFormViewButton->setToolTip( tr(
"Switch to form view" ) );
104 mFormViewButton->setCheckable(
true );
106 buttonLayout->addWidget( mFormViewButton );
108 mTableViewButton =
new QToolButton(
this );
109 mTableViewButton->setText( tr(
"Table view" ) );
110 mTableViewButton->setToolTip( tr(
"Switch to table view" ) );
112 mTableViewButton->setCheckable(
true );
114 buttonLayout->addWidget( mTableViewButton );
116 mViewModeButtonGroup =
new QButtonGroup(
this );
121 topLayout->addLayout( buttonLayout );
123 mRelationLayout =
new QGridLayout();
124 mRelationLayout->setContentsMargins( 0, 0, 0, 0 );
125 topLayout->addLayout( mRelationLayout );
128 mDualView->
setView( mViewMode );
132 mRelationLayout->addWidget( mDualView );
135 connect( mViewModeButtonGroup,
static_cast<void ( QButtonGroup::* )(
int )
>( &QButtonGroup::buttonClicked ),
137 connect( mToggleEditingButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::toggleEditing );
138 connect( mSaveEditsButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::saveEdits );
139 connect( mAddFeatureButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::addFeature );
140 connect( mDuplicateFeatureButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::duplicateFeature );
141 connect( mDeleteFeatureButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::deleteSelectedFeatures );
142 connect( mLinkFeatureButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::linkFeature );
143 connect( mUnlinkFeatureButton, &QAbstractButton::clicked,
this, &QgsRelationEditorWidget::unlinkSelectedFeatures );
160 mRelation = relation;
167 setTitle( relation.
name() );
172 if ( canChangeAttributes && !lyr->readOnly() )
174 mToggleEditingButton->setEnabled(
true );
179 mToggleEditingButton->setEnabled(
false );
182 setObjectName( QStringLiteral(
"referenced/" ) + mRelation.name() );
192 mDualView->
init( mRelation.referencingLayer(),
nullptr, myRequest, mEditorContext );
210 mRelation = relation;
211 mNmRelation = nmrelation;
213 if ( !mRelation.isValid() )
216 mToggleEditingButton->setVisible(
true );
219 for (
auto it = transactionGroups.constBegin(); it != transactionGroups.constEnd(); ++it )
221 if ( it.value()->layers().contains( mRelation.referencingLayer() ) )
223 mToggleEditingButton->setVisible(
false );
224 mSaveEditsButton->setVisible(
false );
237 setTitle( relation.
name() );
242 if ( canChangeAttributes && !lyr->readOnly() )
244 mToggleEditingButton->setEnabled(
true );
249 mToggleEditingButton->setEnabled(
false );
252 setObjectName( QStringLiteral(
"referenced/" ) + mRelation.name() );
259 mEditorContext = context;
264 return mFeatureSelectionMgr;
281 void QgsRelationEditorWidget::updateButtons()
283 bool editable =
false;
284 bool linkable =
false;
298 mAddFeatureButton->setEnabled( editable );
299 mDuplicateFeatureButton->setEnabled( editable && selectionNotEmpty );
300 mLinkFeatureButton->setEnabled( linkable );
301 mDeleteFeatureButton->setEnabled( editable && selectionNotEmpty );
302 mUnlinkFeatureButton->setEnabled( linkable && selectionNotEmpty );
303 mToggleEditingButton->setChecked( editable );
304 mSaveEditsButton->setEnabled( editable );
307 void QgsRelationEditorWidget::addFeature()
329 int index = fields.
indexOf( fieldPair.first );
330 linkAttributes.insert( index, mFeature.
attribute( fieldPair.second ) );
335 int index = fields.
indexOf( fieldPair.first );
336 linkAttributes.insert( index, f.
attribute( fieldPair.second ) );
358 void QgsRelationEditorWidget::linkFeature()
369 if ( selectionDlg.exec() )
391 int index = fields.
indexOf( fieldPair.first );
392 linkAttributes.insert( index, mFeature.
attribute( fieldPair.second ) );
399 int index = fields.
indexOf( fieldPair.first );
400 linkAttributes.insert( index, relatedFeature.
attribute( fieldPair.second ) );
404 newFeatures << linkFeature;
418 QMap<int, QVariant> keys;
423 keys.insert( idx, val );
428 QMapIterator<int, QVariant> it( keys );
429 while ( it.hasNext() )
439 void QgsRelationEditorWidget::duplicateFeature()
452 void QgsRelationEditorWidget::deleteFeature(
const QgsFeatureId featureid )
456 featureids << featureid;
458 deleteFeatures( featureids );
462 void QgsRelationEditorWidget::deleteSelectedFeatures( )
467 void QgsRelationEditorWidget::deleteFeatures(
const QgsFeatureIds &featureids )
475 QgsDebugMsg( QString(
"Delete %1" ).arg( featureids.size() ) );
480 void QgsRelationEditorWidget::unlinkFeature(
const QgsFeatureId featureid )
484 featureids << featureid;
486 unlinkFeatures( featureids );
489 void QgsRelationEditorWidget::unlinkSelectedFeatures( )
494 void QgsRelationEditorWidget::unlinkFeatures(
const QgsFeatureIds &featureids )
500 .setFilterFids( featureids )
512 QString filter = QStringLiteral(
"(%1) AND (%2)" ).arg(
514 filters.join( QStringLiteral(
" OR " ) ) );
518 .setFilterExpression( filter ) );
534 QMap<int, QgsField> keyFields;
544 keyFields.insert( idx, fld );
549 QMapIterator<int, QgsField> it( keyFields );
550 while ( it.hasNext() )
559 void QgsRelationEditorWidget::toggleEditing(
bool state )
575 void QgsRelationEditorWidget::saveEdits()
582 void QgsRelationEditorWidget::onCollapsedStateChanged(
bool collapsed )
592 void QgsRelationEditorWidget::updateUi()
613 filters << filter.prepend(
'(' ).append(
')' );
631 return mLinkFeatureButton->isVisible();
636 mLinkFeatureButton->setVisible( showLinkButton );
641 return mUnlinkFeatureButton->isVisible();
646 mUnlinkFeatureButton->setVisible( showUnlinkButton );
658 if ( mShowLabel && mRelation.
isValid() )
659 setTitle( mRelation.
name() );
661 setTitle( QString() );
668 QAction *qAction =
nullptr;
671 connect( qAction, &QAction::triggered,
this, [
this, fid]() { deleteFeature( fid ); } );
674 connect( qAction, &QAction::triggered,
this, [
this, fid]() { unlinkFeature( fid ); } );
int lookupField(const QString &fieldName) const
Look up field's index from the field name.
const QgsVectorLayerTools * vectorLayerTools() const
Wrapper for iterator of features from vector data provider or vector layer.
QgsVectorLayer * layer() const
Returns the layer this model uses as backend.
static QgsFeature createFeature(QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer.
void init(QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request=QgsFeatureRequest(), const QgsAttributeEditorContext &context=QgsAttributeEditorContext(), bool loadFeatures=true)
Has to be called to initialize the dual view.
bool collapsed
The collapsed state of this group box.
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
QgsAttributeTableModel * masterModel() const
Returns the model which has the information about all features (not only filtered) ...
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
Set the feature selection model.
A groupbox that collapses/expands when toggled and can save its collapsed and checked states...
int selectedFeatureCount() override
The number of features that are selected in this layer.
Contains mainly the QMap with QgsVectorLayer and QgsFeatureIds do list all the duplicated features...
QSet< QgsFeatureId > QgsFeatureIds
This class contains context information for attribute editor widgets.
QList< QgsFeature > QgsFeatureList
QgsVectorLayer referencingLayer
ViewMode
The view modes, in which this widget can present information.
void collapsedStateChanged(bool collapsed)
Signal emitted when groupbox collapsed/expanded state is changed, and when first shown.
#define FID_TO_STRING(fid)
bool deleteFeatures(const QgsFeatureIds &fids)
Deletes a set of features from the layer (but does not commit it)
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
void selectByIds(const QgsFeatureIds &ids, SelectBehavior behavior=SetSelection)
Select matching features using a list of feature IDs.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
bool isEditable() const override
Returns true if the provider is in editing mode.
void setView(ViewMode view)
Change the current view mode.
const QgsFeatureIds & selectedFeatures()
Get the selected features.
QgsField at(int i) const
Get field at particular index (must be in range 0..N-1)
QgsExpression * filterExpression() const
Returns the filter expression if set.
Show a list of the features, where one can be chosen and the according attribute dialog will be prese...
QgsAttributeList referencedFields() const
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
int indexFromName(const QString &fieldName) const
Get the field index from the field name.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
Defines a relation between matching fields of the two involved tables of a relation.
QgsFields fields() const override
Returns the list of fields of this layer.
Shows the features and attributes in a table layout.
#define QgsDebugMsgLevel(str, level)
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QMap< int, QVariant > QgsAttributeMap
void editingStopped()
Is emitted, when edited changes successfully have been written to the data provider.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsVectorLayer referencedLayer
Encapsulate a field in an attribute table or data source.
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
void editingStarted()
Is emitted, when editing on this layer has started.
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Query the layer for features specified in request.
This selection manager synchronizes a local set of selected features with an attribute table...
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
int indexOf(const QString &fieldName) const
Get the field index from the field name.
QMap< QPair< QString, QString >, QgsTransactionGroup * > transactionGroups()
Map of transaction groups.
static QgsFeature duplicateFeature(QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext)
Duplicates a feature and it's children (one level deep).
static QgsProject * instance()
Returns the QgsProject singleton instance.
QString referencedField() const
Get the name of the referenced (parent) field.
QgsVectorDataProvider * dataProvider() override
Returns the layer's data provider.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the sink.
bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant(), bool skipDefaultValues=false)
Changes an attribute value for a feature (but does not immediately commit the changes).
QList< int > QgsAttributeList
bool nextFeature(QgsFeature &f)
Is an interface class to abstract feature selection handling.
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
QString referencingField() const
Get the name of the referencing (child) field.
Allows modification of attribute values.
const QgsFeatureIds & selectedFeatureIds() const override
Return reference to identifiers of selected features.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) override
Adds a single feature to the sink.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, const bool clearAndSelect)
This signal is emitted when selection was changed.
This widget is used to show the attributes of a set of features of a QgsVectorLayer.
void showContextMenuExternally(QgsActionMenu *menu, const QgsFeatureId fid)
Emitted when selecting context menu on the feature list to create the context menu individually...