Skip to content

Commit

Permalink
Support polymorphic relationship strength
Browse files Browse the repository at this point in the history
  • Loading branch information
suricactus committed Jan 18, 2021
1 parent b9f73e7 commit 6dc92b5
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 58 deletions.
10 changes: 10 additions & 0 deletions python/core/auto_generated/qgspolymorphicrelation.sip.in
Expand Up @@ -227,6 +227,16 @@ Returns a list of generated relations, based on the currently set :py:func:`~Qgs
QString layerRepresentation( const QgsVectorLayer *layer ) const;
%Docstring
Returns layer representation as evaluated string
%End

QgsRelation::RelationStrength strength() const;
%Docstring
Returns the relation strength for all the generated normal relations
%End

void setRelationStrength( QgsRelation::RelationStrength relationStrength );
%Docstring
Sets the relation strength for all the generated normal relations
%End

};
Expand Down
15 changes: 14 additions & 1 deletion src/app/qgsrelationaddpolymorphicdlg.cpp
Expand Up @@ -57,6 +57,12 @@ QgsRelationAddPolymorphicDlg::QgsRelationAddPolymorphicDlg( QWidget *parent )
mReferencedLayersComboBox->addItem( vl->name(), vl->id() );
}

mRelationStrengthComboBox->addItem( tr( "Association" ), QVariant::fromValue( QgsRelation::RelationStrength::Association ) );
mRelationStrengthComboBox->addItem( tr( "Composition" ), QVariant::fromValue( QgsRelation::RelationStrength::Composition ) );
mRelationStrengthComboBox->setToolTip( tr( "When composition is selected the child features will be duplicated too.\n"
"Duplications are made by the feature duplication action.\n"
"The default actions are activated in the Action section of the layer properties." ) );

addFieldsRow();
updateTypeConfigWidget();
updateDialogButtons();
Expand All @@ -66,7 +72,8 @@ QgsRelationAddPolymorphicDlg::QgsRelationAddPolymorphicDlg( QWidget *parent )
connect( mFieldsMappingAddButton, &QToolButton::clicked, this, &QgsRelationAddPolymorphicDlg::addFieldsRow );
connect( mFieldsMappingRemoveButton, &QToolButton::clicked, this, &QgsRelationAddPolymorphicDlg::removeFieldsRow );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateDialogButtons );
// connect( mReferencedLayerExpressionWidget, &QgsFieldExpressionWidget::fieldChanged, this, &QgsRelationAddPolymorphicDlg::updateDialogButtons );
connect( mRelationStrengthComboBox, QOverload<int>::of( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) { Q_UNUSED( index ); updateDialogButtons(); } );
connect( mReferencedLayerExpressionWidget, static_cast<void ( QgsFieldExpressionWidget::* )( const QString & )>( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsRelationAddPolymorphicDlg::updateDialogButtons );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateChildRelationsComboBox );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateReferencingFieldsComboBoxes );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateReferencedLayerFieldComboBox );
Expand All @@ -79,6 +86,7 @@ void QgsRelationAddPolymorphicDlg::setPolymorphicRelation( const QgsPolymorphicR
mReferencedLayerFieldComboBox->setLayer( polyRel.referencingLayer() );
mReferencedLayerFieldComboBox->setField( polyRel.referencedLayerField() );
mReferencedLayerExpressionWidget->setExpression( polyRel.referencedLayerExpression() );
mRelationStrengthComboBox->setCurrentIndex( mRelationStrengthComboBox->findData( polyRel.strength() ) );

int index = 0;
const QList<QgsRelation::FieldPair> fieldPairs = polyRel.fieldPairs();
Expand Down Expand Up @@ -203,6 +211,11 @@ QString QgsRelationAddPolymorphicDlg::relationName()
return tr( "Polymorphic relations for \"%1\"" ).arg( vl ? vl->name() : QStringLiteral( "<NO LAYER>" ) );
}

QgsRelation::RelationStrength QgsRelationAddPolymorphicDlg::relationStrength()
{
return mRelationStrengthComboBox->currentData().value<QgsRelation::RelationStrength>();
}

void QgsRelationAddPolymorphicDlg::updateDialogButtons()
{
mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( isDefinitionValid() );
Expand Down
5 changes: 5 additions & 0 deletions src/app/qgsrelationaddpolymorphicdlg.h
Expand Up @@ -78,6 +78,11 @@ class APP_EXPORT QgsRelationAddPolymorphicDlg : public QDialog, private Ui::QgsR
*/
QStringList referencedLayerIds();

/**
* Return the relation strength for the generated normal relations
*/
QgsRelation::RelationStrength relationStrength();

/**
* Sets the values of form fields in the dialog with the values of the passed \a polyRel
*/
Expand Down
27 changes: 16 additions & 11 deletions src/app/qgsrelationmanagerdialog.cpp
Expand Up @@ -148,24 +148,24 @@ void QgsRelationManagerDialog::addRelation( const QgsRelation &rel )
mRelationsTree->setSortingEnabled( true );
}

void QgsRelationManagerDialog::addPolymorphicRelation( const QgsPolymorphicRelation &relation )
void QgsRelationManagerDialog::addPolymorphicRelation( const QgsPolymorphicRelation &polyRel )
{
if ( ! relation.isValid() )
if ( ! polyRel.isValid() )
return;

QString referencingFields;
QString referencedFields;

for ( int i = 0; i < relation.fieldPairs().count(); i++ )
for ( int i = 0; i < polyRel.fieldPairs().count(); i++ )
{
if ( i != 0 )
{
referencingFields += QStringLiteral( ", " );
referencedFields += QStringLiteral( ", " );
}

referencingFields += relation.fieldPairs().at( i ).referencingField();
referencedFields += relation.fieldPairs().at( i ).referencedField();
referencingFields += polyRel.fieldPairs().at( i ).referencingField();
referencedFields += polyRel.fieldPairs().at( i ).referencedField();
}

mRelationsTree->setSortingEnabled( false );
Expand All @@ -177,15 +177,18 @@ void QgsRelationManagerDialog::addPolymorphicRelation( const QgsPolymorphicRelat
// Save relation in first column's item
item->setExpanded( true );
item->setFlags( item->flags() | Qt::ItemIsEditable );
item->setData( 0, Qt::UserRole, QVariant::fromValue<QgsPolymorphicRelation>( relation ) );
item->setText( 0, relation.name() );
item->setText( 1, relation.referencingLayer()->name() );
item->setData( 0, Qt::UserRole, QVariant::fromValue<QgsPolymorphicRelation>( polyRel ) );
item->setText( 0, polyRel.name() );
item->setText( 1, polyRel.referencingLayer()->name() );
item->setText( 2, referencedFields );
item->setText( 3, QStringLiteral( "as in \"%1\".\"%2\"" ).arg( relation.referencingLayer()->name(), relation.referencedLayerField() ) );
item->setText( 3, QStringLiteral( "as in \"%1\".\"%2\"" ).arg( polyRel.referencingLayer()->name(), polyRel.referencedLayerField() ) );
item->setText( 4, referencingFields );
item->setText( 5, relation.id() );
item->setText( 5, polyRel.id() );
item->setText( 6, polyRel.strength() == QgsRelation::RelationStrength::Composition
? QStringLiteral( "Composition" )
: QStringLiteral( "Association" ) );

const QList<QgsRelation> generatedRelations = relation.generateRelations();
const QList<QgsRelation> generatedRelations = polyRel.generateRelations();
for ( const QgsRelation &generatedRelation : generatedRelations )
{
if ( !generatedRelation.isValid() )
Expand Down Expand Up @@ -252,6 +255,7 @@ void QgsRelationManagerDialog::mActionAddPolymorphicRelation_triggered()
relation.setReferencedLayerField( addDlg.referencedLayerField() );
relation.setReferencedLayerExpression( addDlg.referencedLayerExpression() );
relation.setReferencedLayerIds( addDlg.referencedLayerIds() );
relation.setRelationStrength( addDlg.relationStrength() );

const auto references = addDlg.fieldPairs();
for ( const auto &reference : references )
Expand Down Expand Up @@ -285,6 +289,7 @@ void QgsRelationManagerDialog::mActionEditPolymorphicRelation_triggered()
relation.setReferencedLayerField( addDlg.referencedLayerField() );
relation.setReferencedLayerExpression( addDlg.referencedLayerExpression() );
relation.setReferencedLayerIds( addDlg.referencedLayerIds() );
relation.setRelationStrength( addDlg.relationStrength() );

const auto references = addDlg.fieldPairs();
for ( const auto &reference : references )
Expand Down
18 changes: 17 additions & 1 deletion src/core/qgspolymorphicrelation.cpp
Expand Up @@ -66,7 +66,8 @@ QgsPolymorphicRelation QgsPolymorphicRelation::createFromXml( const QDomNode &no
QString referencedLayerExpression = elem.attribute( QStringLiteral( "referencedLayerExpression" ) );
QString id = elem.attribute( QStringLiteral( "id" ) );
QString name = elem.attribute( QStringLiteral( "name" ) );
const QStringList referencedLayerIds = elem.attribute( QStringLiteral( "referencedLayerIds" ) ).split( "," );
QString relationStrength = elem.attribute( QStringLiteral( "relationStrength" ) );
QStringList referencedLayerIds = elem.attribute( QStringLiteral( "referencedLayerIds" ) ).split( "," );

QMap<QString, QgsMapLayer *> mapLayers = relationContext.project()->mapLayers();

Expand All @@ -77,6 +78,7 @@ QgsPolymorphicRelation QgsPolymorphicRelation::createFromXml( const QDomNode &no
relation.d->mReferencedLayerIds = referencedLayerIds;
relation.d->mRelationId = id;
relation.d->mRelationName = name;
relation.d->mRelationStrength = qgsEnumKeyToValue<QgsRelation::RelationStrength>( relationStrength, QgsRelation::RelationStrength::Association );

QDomNodeList references = elem.elementsByTagName( QStringLiteral( "fieldRef" ) );
for ( int i = 0; i < references.size(); ++i )
Expand All @@ -103,6 +105,7 @@ void QgsPolymorphicRelation::writeXml( QDomNode &node, QDomDocument &doc ) const
elem.setAttribute( QStringLiteral( "referencedLayerField" ), d->mReferencedLayerField );
elem.setAttribute( QStringLiteral( "referencedLayerExpression" ), d->mReferencedLayerExpression );
elem.setAttribute( QStringLiteral( "referencedLayerIds" ), d->mReferencedLayerIds.join( "," ) );
elem.setAttribute( QStringLiteral( "relationStrength" ), qgsEnumValueToKey<QgsRelation::RelationStrength>( d->mRelationStrength ) );

// note that a layer id can store a comma in theory. Luckyly, this is not easy to achieve, e.g. you need to modify the .qgs file manually
for ( const QString &layerId : qgis::as_const( d->mReferencedLayerIds ) )
Expand Down Expand Up @@ -360,6 +363,18 @@ QStringList QgsPolymorphicRelation::referencedLayerIds() const
return d->mReferencedLayerIds;
}

QgsRelation::RelationStrength QgsPolymorphicRelation::strength() const
{
return d->mRelationStrength;
}

void QgsPolymorphicRelation::setRelationStrength( QgsRelation::RelationStrength relationStrength )
{
d.detach();
d->mRelationStrength = relationStrength;
updateRelationStatus();
}

QList<QgsRelation> QgsPolymorphicRelation::generateRelations() const
{
QList<QgsRelation> relations;
Expand All @@ -379,6 +394,7 @@ QList<QgsRelation> QgsPolymorphicRelation::generateRelations() const
relation.setName( QStringLiteral( "Generated for \"%1\"" ).arg( referencedLayerName ) );
relation.setId( QStringLiteral( "%1_%2" ).arg( d->mRelationId, referencedLayerName ) );
relation.setPolymorphicRelationId( d->mRelationId );
relation.setStrength( d->mRelationStrength );

const QList<QgsRelation::FieldPair> constFieldPairs = fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgspolymorphicrelation.h
Expand Up @@ -274,6 +274,16 @@ class CORE_EXPORT QgsPolymorphicRelation
*/
QString layerRepresentation( const QgsVectorLayer *layer ) const;

/**
* Returns the relation strength for all the generated normal relations
*/
QgsRelation::RelationStrength strength() const;

/**
* Sets the relation strength for all the generated normal relations
*/
void setRelationStrength( QgsRelation::RelationStrength relationStrength );

private:

QExplicitlySharedDataPointer<QgsPolymorphicRelationPrivate> d;
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgspolymorphicrelation_p.h
Expand Up @@ -67,6 +67,9 @@ class QgsPolymorphicRelationPrivate : public QSharedData
//! A map of the layerIds and the respective layers
QMap<QString, QgsVectorLayer *> mReferencedLayersMap;

//! The relation strength for all the generated normal relations
QgsRelation::RelationStrength mRelationStrength;

//! Whether the polymorphic relation is valid
bool mValid = false;
};
Expand Down
100 changes: 55 additions & 45 deletions src/ui/qgsrelationmanageraddpolymorphicdialogbase.ui
Expand Up @@ -14,6 +14,20 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,2,0">
<item row="1" column="0">
<widget class="QLabel" name="mReferencingLayerLabel">
<property name="text">
<string>Referencing layer</string>
</property>
</widget>
</item>
<item row="12" column="0" colspan="3">
<widget class="QDialogButtonBox" name="mButtonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mReferencedLayerFieldLabel">
<property name="text">
Expand All @@ -28,17 +42,27 @@
</property>
</widget>
</item>
<item row="8" column="1" colspan="2">
<widget class="QgsCheckableComboBox" name="mReferencedLayersComboBox"/>
<item row="10" column="0">
<widget class="QLabel" name="mReferencedLayersLabel">
<property name="text">
<string>Referenced layers</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="mFieldsMappingLabel">
<item row="1" column="1" colspan="2">
<widget class="QgsMapLayerComboBox" name="mReferencingLayerComboBox"/>
</item>
<item row="11" column="0" colspan="3">
<widget class="QLabel" name="mPolymorphicRelationHelpLabel">
<property name="text">
<string>Fields mapping</string>
<string>Polymorphic relations are for advanced usage where a set of standard relations have the same referencing layer but the referenced layer is calculated from an expression.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="2">
<item row="9" column="2">
<layout class="QVBoxLayout" name="mFieldsMappingButtonsVBoxLayout">
<item>
<widget class="QToolButton" name="mFieldsMappingAddButton">
Expand Down Expand Up @@ -77,14 +101,27 @@
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mReferencingLayerLabel">
<item row="8" column="0" colspan="2">
<widget class="QLabel" name="mFieldsMappingLabel">
<property name="text">
<string>Referencing layer</string>
<string>Fields mapping</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<item row="2" column="1" colspan="2">
<widget class="QgsFieldComboBox" name="mReferencedLayerFieldComboBox"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="mReferencedLayerExpressionLabel">
<property name="text">
<string>Layer field expression</string>
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<widget class="QgsCheckableComboBox" name="mReferencedLayersComboBox"/>
</item>
<item row="9" column="0" colspan="2">
<widget class="QTableWidget" name="mFieldsMappingTable">
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
Expand All @@ -110,52 +147,25 @@
</column>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QgsMapLayerComboBox" name="mReferencingLayerComboBox"/>
</item>
<item row="3" column="1" colspan="2">
<widget class="QgsFieldExpressionWidget" name="mReferencedLayerExpressionWidget" native="true"/>
</item>
<item row="8" column="0">
<widget class="QLabel" name="mReferencedLayersLabel">
<property name="text">
<string>Referenced layers</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="mReferencedLayerExpressionLabel">
<property name="text">
<string>Layer field expression</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QgsFieldComboBox" name="mReferencedLayerFieldComboBox"/>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="mIdLineEdit">
<property name="placeholderText">
<string>[Generated automatically]</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="3">
<widget class="QLabel" name="mPolymorphicRelationHelpLabel">
<item row="3" column="1" colspan="2">
<widget class="QgsFieldExpressionWidget" name="mReferencedLayerExpressionWidget"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="mRelationStrengthLabel">
<property name="text">
<string>Polymorphic relations are for advanced usage where a set of standard relations have the same referencing layer but the referenced layer is calculated from an expression.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
<string>Relationship strength</string>
</property>
</widget>
</item>
<item row="10" column="0" colspan="3">
<widget class="QDialogButtonBox" name="mButtonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property>
</widget>
<item row="6" column="1" colspan="2">
<widget class="QComboBox" name="mRelationStrengthComboBox"/>
</item>
</layout>
</widget>
Expand Down

0 comments on commit 6dc92b5

Please sign in to comment.