34 #include <QHBoxLayout>    36 #include <QMessageBox>    41   QVBoxLayout *topLayout = 
new QVBoxLayout( 
this );
    42   topLayout->setContentsMargins( 0, 9, 0, 0 );
    43   setLayout( topLayout );
    46   QHBoxLayout *buttonLayout = 
new QHBoxLayout();
    47   buttonLayout->setContentsMargins( 0, 0, 0, 0 );
    49   mToggleEditingButton = 
new QToolButton( 
this );
    50   mToggleEditingButton->setObjectName( QStringLiteral( 
"mToggleEditingButton" ) );
    52   mToggleEditingButton->setText( tr( 
"Toggle editing" ) );
    53   mToggleEditingButton->setEnabled( 
false );
    54   mToggleEditingButton->setCheckable( 
true );
    55   mToggleEditingButton->setToolTip( tr( 
"Toggle editing mode for child layer" ) );
    56   buttonLayout->addWidget( mToggleEditingButton );
    58   mSaveEditsButton = 
new QToolButton( 
this );
    60   mSaveEditsButton->setText( tr( 
"Save child layer edits" ) );
    61   mSaveEditsButton->setToolTip( tr( 
"Save child layer edits" ) );
    62   mSaveEditsButton->setEnabled( 
true );
    63   buttonLayout->addWidget( mSaveEditsButton );
    65   mAddFeatureButton = 
new QToolButton( 
this );
    67   mAddFeatureButton->setText( tr( 
"Add child feature" ) );
    68   mAddFeatureButton->setToolTip( tr( 
"Add child feature" ) );
    69   mAddFeatureButton->setObjectName( QStringLiteral( 
"mAddFeatureButton" ) );
    70   buttonLayout->addWidget( mAddFeatureButton );
    72   mDuplicateFeatureButton = 
new QToolButton( 
this );
    74   mDuplicateFeatureButton->setText( tr( 
"Duplicate child feature" ) );
    75   mDuplicateFeatureButton->setToolTip( tr( 
"Duplicate child feature" ) );
    76   mDuplicateFeatureButton->setObjectName( QStringLiteral( 
"mDuplicateFeatureButton" ) );
    77   buttonLayout->addWidget( mDuplicateFeatureButton );
    79   mDeleteFeatureButton = 
new QToolButton( 
this );
    81   mDeleteFeatureButton->setText( tr( 
"Delete child feature" ) );
    82   mDeleteFeatureButton->setToolTip( tr( 
"Delete child feature" ) );
    83   mDeleteFeatureButton->setObjectName( QStringLiteral( 
"mDeleteFeatureButton" ) );
    84   buttonLayout->addWidget( mDeleteFeatureButton );
    86   mLinkFeatureButton = 
new QToolButton( 
this );
    88   mLinkFeatureButton->setText( tr( 
"Link existing features" ) );
    89   mLinkFeatureButton->setToolTip( tr( 
"Link existing child features" ) );
    90   mLinkFeatureButton->setObjectName( QStringLiteral( 
"mLinkFeatureButton" ) );
    91   buttonLayout->addWidget( mLinkFeatureButton );
    93   mUnlinkFeatureButton = 
new QToolButton( 
this );
    95   mUnlinkFeatureButton->setText( tr( 
"Unlink feature" ) );
    96   mUnlinkFeatureButton->setToolTip( tr( 
"Unlink child feature" ) );
    97   mUnlinkFeatureButton->setObjectName( QStringLiteral( 
"mUnlinkFeatureButton" ) );
    98   buttonLayout->addWidget( mUnlinkFeatureButton );
   100   mZoomToFeatureButton = 
new QToolButton( 
this );
   102   mZoomToFeatureButton->setText( tr( 
"Zoom To Feature" ) );
   103   mZoomToFeatureButton->setToolTip( tr( 
"Zoom to child feature" ) );
   104   mZoomToFeatureButton->setObjectName( QStringLiteral( 
"mZoomToFeatureButton" ) );
   105   buttonLayout->addWidget( mZoomToFeatureButton );
   107   buttonLayout->addItem( 
new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
   109   mFormViewButton = 
new QToolButton( 
this );
   110   mFormViewButton->setText( tr( 
"Form view" ) );
   111   mFormViewButton->setToolTip( tr( 
"Switch to form view" ) );
   113   mFormViewButton->setCheckable( 
true );
   115   buttonLayout->addWidget( mFormViewButton );
   117   mTableViewButton = 
new QToolButton( 
this );
   118   mTableViewButton->setText( tr( 
"Table view" ) );
   119   mTableViewButton->setToolTip( tr( 
"Switch to table view" ) );
   121   mTableViewButton->setCheckable( 
true );
   123   buttonLayout->addWidget( mTableViewButton );
   125   mViewModeButtonGroup = 
new QButtonGroup( 
this );
   130   topLayout->addLayout( buttonLayout );
   132   mRelationLayout = 
new QGridLayout();
   133   mRelationLayout->setContentsMargins( 0, 0, 0, 0 );
   134   topLayout->addLayout( mRelationLayout );
   137   mDualView->
setView( mViewMode );
   141   mRelationLayout->addWidget( mDualView );
   144   connect( mViewModeButtonGroup, 
static_cast<void ( QButtonGroup::* )( 
int )
>( &QButtonGroup::buttonClicked ),
   146   connect( mToggleEditingButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::toggleEditing );
   147   connect( mSaveEditsButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::saveEdits );
   148   connect( mAddFeatureButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::addFeature );
   149   connect( mDuplicateFeatureButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::duplicateFeature );
   150   connect( mDeleteFeatureButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::deleteSelectedFeatures );
   151   connect( mLinkFeatureButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::linkFeature );
   152   connect( mUnlinkFeatureButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::unlinkSelectedFeatures );
   153   connect( mZoomToFeatureButton, &QAbstractButton::clicked, 
this, &QgsRelationEditorWidget::zoomToSelectedFeatures );
   170   mRelation = relation;
   177     setTitle( relation.
name() );
   182   if ( canChangeAttributes && !lyr->readOnly() )
   184     mToggleEditingButton->setEnabled( 
true );
   189     mToggleEditingButton->setEnabled( 
false );
   192   setObjectName( QStringLiteral( 
"referenced/" ) + mRelation.name() );
   201     mDualView->
init( mRelation.referencingLayer(), 
nullptr, myRequest, mEditorContext );
   219   mRelation = relation;
   220   mNmRelation = nmrelation;
   222   if ( !mRelation.isValid() )
   225   mToggleEditingButton->setVisible( 
true );
   228   for ( 
auto it = transactionGroups.constBegin(); it != transactionGroups.constEnd(); ++it )
   230     if ( it.value()->layers().contains( mRelation.referencingLayer() ) )
   232       mToggleEditingButton->setVisible( 
false );
   233       mSaveEditsButton->setVisible( 
false );
   246   setTitle( relation.
name() );
   251   if ( canChangeAttributes && !lyr->readOnly() )
   253     mToggleEditingButton->setEnabled( 
true );
   258     mToggleEditingButton->setEnabled( 
false );
   264     mZoomToFeatureButton->setVisible( mRelation.referencingLayer()->isSpatial() );
   266   setObjectName( QStringLiteral( 
"referenced/" ) + mRelation.name() );
   273   mEditorContext = context;
   278   return mFeatureSelectionMgr;
   294 void QgsRelationEditorWidget::updateButtons()
   296   bool editable = 
false;
   297   bool linkable = 
false;
   311   mAddFeatureButton->setEnabled( editable );
   312   mDuplicateFeatureButton->setEnabled( editable && selectionNotEmpty );
   313   mLinkFeatureButton->setEnabled( linkable );
   314   mDeleteFeatureButton->setEnabled( editable && selectionNotEmpty );
   315   mUnlinkFeatureButton->setEnabled( linkable && selectionNotEmpty );
   317   mZoomToFeatureButton->setVisible(
   333   mZoomToFeatureButton->setEnabled( selectionNotEmpty );
   335   mToggleEditingButton->setChecked( editable );
   336   mSaveEditsButton->setEnabled( editable );
   339 void QgsRelationEditorWidget::addFeature()
   361         int index = fields.
indexOf( fieldPair.first );
   362         linkAttributes.insert( index,  mFeature.
attribute( fieldPair.second ) );
   367         int index = fields.
indexOf( fieldPair.first );
   368         linkAttributes.insert( index, f.
attribute( fieldPair.second ) );
   390 void QgsRelationEditorWidget::linkFeature()
   401   if ( selectionDlg.exec() )
   423         int index = fields.
indexOf( fieldPair.first );
   424         linkAttributes.insert( index,  mFeature.
attribute( fieldPair.second ) );
   431           int index = fields.
indexOf( fieldPair.first );
   432           linkAttributes.insert( index, relatedFeature.
attribute( fieldPair.second ) );
   436         newFeatures << linkFeature;
   441       Q_FOREACH ( 
const QgsFeature &f, newFeatures )
   450       QMap<int, QVariant> keys;
   455         keys.insert( idx, val );
   460         QMapIterator<int, QVariant> it( keys );
   461         while ( it.hasNext() )
   471 void QgsRelationEditorWidget::duplicateFeature()
   484 void QgsRelationEditorWidget::deleteFeature( 
const QgsFeatureId featureid )
   489 void QgsRelationEditorWidget::deleteSelectedFeatures()
   494 void QgsRelationEditorWidget::deleteFeatures( 
const QgsFeatureIds &featureids )
   496   bool deleteFeatures = 
true;
   517     QStringList deletedFeaturesPks;
   528     QString linkingFeaturesRequestExpression;
   529     if ( !deletedFeaturesPks.empty() )
   536       int relatedLinkingFeaturesCount = 0;
   537       while ( relatedLinkingFeatures.
nextFeature( feature ) )
   539         relatedLinkingFeaturesCount++;
   542       if ( deletedFeaturesPks.size() == 1 && relatedLinkingFeaturesCount > 1 )
   544         QMessageBox messageBox( QMessageBox::Question, tr( 
"Really delete entry?" ), tr( 
"The entry on %1 is still linked to %2 features on %3. Do you want to delete it?" ).arg( mNmRelation.
referencedLayer()->
name(), QString::number( relatedLinkingFeaturesCount ), mRelation.
referencedLayer()->
name() ), QMessageBox::NoButton, 
this );
   545         messageBox.addButton( QMessageBox::Cancel );
   546         QAbstractButton *deleteButton = messageBox.addButton( tr( 
"Delete" ),  QMessageBox::AcceptRole );
   549         if ( messageBox.clickedButton() != deleteButton )
   550           deleteFeatures = 
false;
   552       else if ( deletedFeaturesPks.size() > 1 && relatedLinkingFeaturesCount > deletedFeaturesPks.size() )
   554         QMessageBox messageBox( QMessageBox::Question, tr( 
"Really delete entries?" ), tr( 
"The %1 entries on %2 are still linked to %3 features on %4. Do you want to delete them?" ).arg( QString::number( deletedFeaturesPks.size() ), mNmRelation.
referencedLayer()->
name(), QString::number( relatedLinkingFeaturesCount ), mRelation.
referencedLayer()->
name() ), QMessageBox::NoButton, 
this );
   555         messageBox.addButton( QMessageBox::Cancel );
   556         QAbstractButton *deleteButton = messageBox.addButton( tr( 
"Delete" ), QMessageBox::AcceptRole );
   559         if ( messageBox.clickedButton() != deleteButton )
   560           deleteFeatures = 
false;
   569   if ( deleteFeatures )
   576 void QgsRelationEditorWidget::unlinkFeature( 
const QgsFeatureId featureid )
   581 void QgsRelationEditorWidget::unlinkSelectedFeatures()
   586 void QgsRelationEditorWidget::zoomToSelectedFeatures()
   598 void QgsRelationEditorWidget::unlinkFeatures( 
const QgsFeatureIds &featureids )
   604                                             .setFilterFids( featureids )
   616     QString filter = QStringLiteral( 
"(%1) AND (%2)" ).arg(
   618                        filters.join( QStringLiteral( 
" OR " ) ) );
   622                                         .setFilterExpression( filter ) );
   638     QMap<int, QgsField> keyFields;
   648       keyFields.insert( idx, fld );
   653       QMapIterator<int, QgsField> it( keyFields );
   654       while ( it.hasNext() )
   663 void QgsRelationEditorWidget::toggleEditing( 
bool state )
   679 void QgsRelationEditorWidget::saveEdits()
   686 void QgsRelationEditorWidget::onCollapsedStateChanged( 
bool collapsed )
   695 void QgsRelationEditorWidget::updateUi()
   716         filters << filter.prepend( 
'(' ).append( 
')' );
   734   return mLinkFeatureButton->isVisible();
   739   mLinkFeatureButton->setVisible( showLinkButton );
   744   return mUnlinkFeatureButton->isVisible();
   749   mUnlinkFeatureButton->setVisible( showUnlinkButton );
   761   if ( mShowLabel && mRelation.
isValid() )
   762     setTitle( mRelation.
name() );
   764     setTitle( QString() );
   771     QAction *qAction = 
nullptr;
   774     connect( qAction, &QAction::triggered, 
this, [
this, fid]() { deleteFeature( fid ); } );
   777     connect( qAction, &QAction::triggered, 
this, [
this, fid]() { unlinkFeature( fid ); } );
 
Wrapper for iterator of features from vector data provider or vector layer. 
 
QSet< QgsFeatureId > QgsFeatureIds
 
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. 
 
QString referencedField() const 
Gets the name of the referenced (parent) field. 
 
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes) 
 
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
Returns the number of features that are selected in this layer. 
 
Contains mainly the QMap with QgsVectorLayer and QgsFeatureIds do list all the duplicated features...
 
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. 
 
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched. 
 
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. 
 
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
This signal is emitted when selection was changed. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
QgsAttributeList referencedFields() const 
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
 
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const 
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
 
QgsField at(int i) const 
Gets field at particular index (must be in range 0..N-1) 
 
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
 
Map canvas is a class for displaying all GIS data types on a canvas. 
 
void setView(ViewMode view)
Change the current view mode. 
 
const QgsFeatureIds & selectedFeatures()
Gets the selected features. 
 
Show a list of the features, where one can be chosen and the according attribute dialog will be prese...
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
bool isEditable() const FINAL
Returns true if the provider is in editing mode. 
 
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression. 
 
QgsFields fields() const FINAL
Returns the list of fields of this layer. 
 
Defines a relation between matching fields of the two involved tables of a relation. 
 
Shows the features and attributes in a table layout. 
 
#define QgsDebugMsgLevel(str, level)
 
QString referencingField() const 
Gets the name of the referencing (child) field. 
 
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched. 
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
static QgsFeature createFeature(const QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer. 
 
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)...
 
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=nullptr) FINAL
Adds a list of features to the sink. 
 
QgsVectorLayer referencedLayer
 
Encapsulate a field in an attribute table or data source. 
 
int lookupField(const QString &fieldName) const 
Looks up field's index from the field name. 
 
int indexOf(const QString &fieldName) const 
Gets the field index from the field name. 
 
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. 
 
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
 
int indexFromName(const QString &fieldName) const 
Gets the field index from the field name. 
 
This selection manager synchronizes a local set of selected features with an attribute table...
 
QgsAttributeTableModel * masterModel() const 
Returns the model which has the information about all features (not only filtered) ...
 
void showContextMenuExternally(QgsActionMenu *menu, QgsFeatureId fid)
Emitted when selecting context menu on the feature list to create the context menu individually...
 
void zoomToFeatureIds(QgsVectorLayer *layer, const QgsFeatureIds &ids)
Set canvas extent to the bounding box of a set of features. 
 
QVariant attribute(const QString &name) const 
Lookup attribute value from attribute name. 
 
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched. 
 
#define FID_TO_STRING(fid)
 
virtual QgsVectorDataProvider::Capabilities capabilities() const 
Returns flags containing the supported capabilities. 
 
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. 
 
QgsMapCanvas * mapCanvas() const 
Returns the associated map canvas (e.g. 
 
QgsVectorLayer * layer() const 
Returns the layer this model uses as backend. 
 
const QgsVectorLayerTools * vectorLayerTools() const 
Returns the associated vector layer tools. 
 
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) FINAL
Adds a single feature to the sink. 
 
QList< QgsRelation::FieldPair > fieldPairs() const 
Returns the field pairs which form this relation The first element of each pair are the field names o...
 
QString expression() const 
Returns the original, unmodified expression string. 
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request. 
 
QgsWkbTypes::GeometryType geometryType() const 
Returns point, line or polygon. 
 
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). 
 
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider. 
 
QList< int > QgsAttributeList
 
bool nextFeature(QgsFeature &f)
 
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required...
 
Geometry is not required. It may still be returned if e.g. required for a filter condition. 
 
Is an interface class to abstract feature selection handling. 
 
Represents a vector layer which manages a vector based data sets. 
 
Allows modification of attribute values. 
 
const QgsFeatureIds & selectedFeatureIds() const override
Returns reference to identifiers of selected features. 
 
This widget is used to show the attributes of a set of features of a QgsVectorLayer. 
 
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched. 
 
QgsExpression * filterExpression() const 
Returns the filter expression if set.