Skip to content

Commit

Permalink
Improved the overall QgsPolymorphicRelations experience
Browse files Browse the repository at this point in the history
  • Loading branch information
suricactus committed Jan 18, 2021
1 parent cba4e17 commit 371534c
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 18 deletions.
26 changes: 23 additions & 3 deletions src/app/qgsrelationaddpolymorphicdlg.cpp
Expand Up @@ -33,7 +33,6 @@
#include "qgsrelationmanager.h"
#include "qgsfieldexpressionwidget.h"


QgsRelationAddPolymorphicDlg::QgsRelationAddPolymorphicDlg( QWidget *parent )
: QDialog( parent )
, Ui::QgsRelationManagerAddPolymorphicDialogBase()
Expand Down Expand Up @@ -68,12 +67,33 @@ QgsRelationAddPolymorphicDlg::QgsRelationAddPolymorphicDlg( QWidget *parent )
connect( mFieldsMappingRemoveButton, &QToolButton::clicked, this, &QgsRelationAddPolymorphicDlg::removeFieldsRow );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateDialogButtons );
// connect( mReferencedLayerExpressionWidget, &QgsFieldExpressionWidget::fieldChanged, this, &QgsRelationAddPolymorphicDlg::updateDialogButtons );
// connect( mReferencedLayerFieldLayer, &QgsQ::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateDialogButtons );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateChildRelationsComboBox );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateReferencingFieldsComboBoxes );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDlg::updateReferencedLayerFieldComboBox );
}

void QgsRelationAddPolymorphicDlg::setPolymorphicRelation( const QgsPolymorphicRelation polyRel )
{
mIdLineEdit->setText( polyRel.id() );
mReferencingLayerComboBox->setLayer( polyRel.referencingLayer() );
mReferencedLayerFieldComboBox->setLayer( polyRel.referencingLayer() );
mReferencedLayerFieldComboBox->setField( polyRel.referencedLayerField() );
mReferencedLayerExpressionWidget->setExpression( polyRel.referencedLayerExpression() );

int index = 0;
const QList<QgsRelation::FieldPair> fieldPairs = polyRel.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : fieldPairs )
{
static_cast<QLineEdit *>( mFieldsMappingTable->cellWidget( index, 0 ) )->setText( fieldPair.referencedField() );
static_cast<QgsFieldComboBox *>( mFieldsMappingTable->cellWidget( index, 1 ) )->setCurrentText( fieldPair.referencingField() );
index++;
}

const QStringList layerIds = polyRel.referencedLayerIds();
for ( const QString &layerId : layerIds )
mReferencedLayersComboBox->setItemCheckState( mReferencedLayersComboBox->findData( layerId ), Qt::Checked );
}

void QgsRelationAddPolymorphicDlg::updateTypeConfigWidget()
{
updateDialogButtons();
Expand Down Expand Up @@ -159,7 +179,7 @@ QStringList QgsRelationAddPolymorphicDlg::referencedLayerIds()
return QVariant( mReferencedLayersComboBox->checkedItemsData() ).toStringList();
}

QList< QPair< QString, QString > > QgsRelationAddPolymorphicDlg::references()
QList< QPair< QString, QString > > QgsRelationAddPolymorphicDlg::fieldPairs()
{
QList< QPair< QString, QString > > references;
for ( int i = 0, l = mFieldsMappingTable->rowCount(); i < l; i++ )
Expand Down
44 changes: 33 additions & 11 deletions src/app/qgsrelationaddpolymorphicdlg.h
Expand Up @@ -43,14 +43,45 @@ class APP_EXPORT QgsRelationAddPolymorphicDlg : public QDialog, private Ui::QgsR
public:
explicit QgsRelationAddPolymorphicDlg( QWidget *parent = nullptr );

/**
* Returns the id of the referencing layer
*/
QString referencingLayerId();

/**
* Returns the field in the referencing layer that stores the referenced layer representation
*/
QString referencedLayerField();

/**
* Returns the expression used to generate the referenced layer representation
*/
QString referencedLayerExpression();
QList< QPair< QString, QString > > references();

/**
* Returns field pairs
*/
QList< QPair< QString, QString > > fieldPairs();

/**
* Returns the polymorphic relation id
*/
QString relationId();

/**
* Returns the polymorphic relation name
*/
QString relationName();

/**
* Returns a list of layer ids used as referenced layers and stored in the referencing layers
*/
QStringList referencedLayerIds();
QgsRelation::RelationStrength relationStrength();

/**
* Sets the values of form fields in the dialog with the values of the passed \a polyRel
*/
void setPolymorphicRelation( const QgsPolymorphicRelation polyRel );

private slots:
void addFieldsRow();
Expand All @@ -66,15 +97,6 @@ class APP_EXPORT QgsRelationAddPolymorphicDlg : public QDialog, private Ui::QgsR
private:
bool isDefinitionValid();
void updateFieldsMapping();
// QList<QgsFieldPairWidget *> mFieldPairWidgets;

// QDialogButtonBox *mButtonBox = nullptr;
// QVBoxLayout *mFieldPairsLayout = nullptr;
// QLineEdit *mNameLineEdit = nullptr;
// QComboBox *mTypeComboBox = nullptr;
// QLineEdit *mIdLineEdit = nullptr;
// QLineEdit *mReferencedLayerExpressionLineEdit = nullptr;
// QComboBox *mStrengthCombobox = nullptr;

};

Expand Down
44 changes: 43 additions & 1 deletion src/app/qgsrelationmanagerdialog.cpp
Expand Up @@ -55,12 +55,14 @@ QgsRelationManagerDialog::QgsRelationManagerDialog( QgsRelationManager *relation

connect( mBtnAddRelation, &QPushButton::clicked, this, &QgsRelationManagerDialog::mBtnAddRelation_clicked );
connect( mActionAddPolymorphicRelation, &QAction::triggered, this, &QgsRelationManagerDialog::mActionAddPolymorphicRelation_triggered );
connect( mActionEditPolymorphicRelation, &QAction::triggered, this, &QgsRelationManagerDialog::mActionEditPolymorphicRelation_triggered );
connect( mBtnDiscoverRelations, &QPushButton::clicked, this, &QgsRelationManagerDialog::mBtnDiscoverRelations_clicked );
connect( mBtnRemoveRelation, &QPushButton::clicked, this, &QgsRelationManagerDialog::mBtnRemoveRelation_clicked );

mBtnRemoveRelation->setEnabled( false );
mBtnAddRelation->setPopupMode( QToolButton::MenuButtonPopup );
mBtnAddRelation->addAction( mActionAddPolymorphicRelation );
mBtnAddRelation->addAction( mActionEditPolymorphicRelation );

connect( mRelationsTree->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsRelationManagerDialog::onSelectionChanged );
}
Expand Down Expand Up @@ -251,7 +253,40 @@ void QgsRelationManagerDialog::mActionAddPolymorphicRelation_triggered()
relation.setReferencedLayerExpression( addDlg.referencedLayerExpression() );
relation.setReferencedLayerIds( addDlg.referencedLayerIds() );

const auto references = addDlg.references();
const auto references = addDlg.fieldPairs();
for ( const auto &reference : references )
relation.addFieldPair( reference.first, reference.second );

QString relationId = addDlg.relationId();

if ( relationId.isEmpty() )
relation.generateId();
else
relation.setId( relationId );

addPolymorphicRelation( relation );
}
}

void QgsRelationManagerDialog::mActionEditPolymorphicRelation_triggered()
{
QgsRelationAddPolymorphicDlg addDlg;
const QModelIndexList rows = mRelationsTree->selectionModel()->selectedRows();

if ( rows.size() != 1 )
return;

addDlg.setPolymorphicRelation( mRelationsTree->topLevelItem( rows[0].row() )->data( 0, Qt::UserRole ).value<QgsPolymorphicRelation>() );

if ( addDlg.exec() )
{
QgsPolymorphicRelation relation;
relation.setReferencingLayer( addDlg.referencingLayerId() );
relation.setReferencedLayerField( addDlg.referencedLayerField() );
relation.setReferencedLayerExpression( addDlg.referencedLayerExpression() );
relation.setReferencedLayerIds( addDlg.referencedLayerIds() );

const auto references = addDlg.fieldPairs();
for ( const auto &reference : references )
relation.addFieldPair( reference.first, reference.second );

Expand Down Expand Up @@ -335,4 +370,11 @@ QList< QgsPolymorphicRelation > QgsRelationManagerDialog::polymorphicRelations()
void QgsRelationManagerDialog::onSelectionChanged()
{
mBtnRemoveRelation->setEnabled( ! mRelationsTree->selectionModel()->selectedRows().isEmpty() );

const QModelIndexList rows = mRelationsTree->selectionModel()->selectedRows();
bool isEditPolymorphicRelationEnabled = (
rows.size() == 1
&& mRelationsTree->topLevelItem( rows[0].row() )->data( 0, Qt::UserRole ).value<QgsPolymorphicRelation>().isValid()
);
mActionEditPolymorphicRelation->setEnabled( isEditPolymorphicRelationEnabled );
}
1 change: 1 addition & 0 deletions src/app/qgsrelationmanagerdialog.h
Expand Up @@ -43,6 +43,7 @@ class APP_EXPORT QgsRelationManagerDialog : public QWidget, private Ui::QgsRelat
private slots:
void mBtnAddRelation_clicked();
void mActionAddPolymorphicRelation_triggered();
void mActionEditPolymorphicRelation_triggered();
void mBtnDiscoverRelations_clicked();
void mBtnRemoveRelation_clicked();
void onSelectionChanged();
Expand Down
49 changes: 48 additions & 1 deletion src/gui/qgsabstractrelationeditorwidget.cpp
Expand Up @@ -26,6 +26,7 @@
#include "qgsfeatureselectiondlg.h"
#include "qgsgenericfeatureselectionmanager.h"
#include "qgsrelation.h"
#include "qgspolymorphicrelation.h"
#include "qgsvectorlayertools.h"
#include "qgsproject.h"
#include "qgstransactiongroup.h"
Expand Down Expand Up @@ -222,6 +223,9 @@ void QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &geometry )

if ( mNmRelation.isValid() )
{
// there is no such case where we have polymorphic relations and m:n relation
Q_ASSERT( mNmRelation.polymorphicRelationId().isNull() );

// n:m Relation: first let the user create a new feature on the other table
// and autocreate a new linking feature.
QgsFeature f;
Expand Down Expand Up @@ -257,6 +261,11 @@ void QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &geometry )
else
{
QgsFields fields = mRelation.referencingLayer()->fields();
if ( ! mRelation.polymorphicRelationId().isNull() )
{
QgsPolymorphicRelation polyRel = mRelation.polymorphicRelation();
keyAttrs.insert( fields.indexFromName( polyRel.referencedLayerField() ), polyRel.layerRepresentation( mRelation.referencedLayer() ) );
}

const auto constFieldPairs = mRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
Expand All @@ -279,6 +288,9 @@ void QgsAbstractRelationEditorWidget::deleteFeatures( const QgsFeatureIds &fids
QgsVectorLayer *layer;
if ( mNmRelation.isValid() )
{
// there is no such case where we have polymorphic relations and m:n relation
Q_ASSERT( mNmRelation.polymorphicRelationId().isNull() );

layer = mNmRelation.referencedLayer();

// When deleting a linked feature within an N:M relation,
Expand Down Expand Up @@ -391,7 +403,12 @@ void QgsAbstractRelationEditorWidget::linkFeature()
QgsVectorLayer *layer = nullptr;

if ( mNmRelation.isValid() )
{
// there is no such case where we have polymorphic relations and m:n relation
Q_ASSERT( mNmRelation.polymorphicRelationId().isNull() );

layer = mNmRelation.referencedLayer();
}
else
layer = mRelation.referencingLayer();

Expand All @@ -410,6 +427,9 @@ void QgsAbstractRelationEditorWidget::onLinkFeatureDlgAccepted()
QgsFeatureSelectionDlg *selectionDlg = qobject_cast<QgsFeatureSelectionDlg *>( sender() );
if ( mNmRelation.isValid() )
{
// there is no such case where we have polymorphic relations and m:n relation
Q_ASSERT( mNmRelation.polymorphicRelationId().isNull() );

QgsFeatureIterator it = mNmRelation.referencedLayer()->getFeatures(
QgsFeatureRequest()
.setFilterFids( selectionDlg->selectedFeatures() )
Expand Down Expand Up @@ -467,11 +487,23 @@ void QgsAbstractRelationEditorWidget::onLinkFeatureDlgAccepted()
const auto constSelectedFeatures = selectionDlg->selectedFeatures();
for ( QgsFeatureId fid : constSelectedFeatures )
{
QgsVectorLayer *referencingLayer = mRelation.referencingLayer();
if ( ! mRelation.polymorphicRelationId().isNull() )
{
QgsPolymorphicRelation polyRel = mRelation.polymorphicRelation();

Q_ASSERT( mRelation.polymorphicRelation().isValid() );

mRelation.referencingLayer()->changeAttributeValue( fid,
referencingLayer->fields().indexFromName( polyRel.referencedLayerField() ),
polyRel.layerRepresentation( mRelation.referencedLayer() ) );
}

QMapIterator<int, QVariant> it( keys );
while ( it.hasNext() )
{
it.next();
mRelation.referencingLayer()->changeAttributeValue( fid, it.key(), it.value() );
referencingLayer->changeAttributeValue( fid, it.key(), it.value() );
}
}
}
Expand All @@ -488,6 +520,9 @@ void QgsAbstractRelationEditorWidget::unlinkFeatures( const QgsFeatureIds &fids
{
if ( mNmRelation.isValid() )
{
// there is no such case where we have polymorphic relations and m:n relation
Q_ASSERT( mNmRelation.polymorphicRelationId().isNull() );

QgsFeatureIterator selectedIterator = mNmRelation.referencedLayer()->getFeatures(
QgsFeatureRequest()
.setFilterFids( fids )
Expand Down Expand Up @@ -541,6 +576,18 @@ void QgsAbstractRelationEditorWidget::unlinkFeatures( const QgsFeatureIds &fids
const auto constFeatureids = fids;
for ( QgsFeatureId fid : constFeatureids )
{
QgsVectorLayer *referencingLayer = mRelation.referencingLayer();
if ( ! mRelation.polymorphicRelationId().isNull() )
{
QgsPolymorphicRelation polyRel = mRelation.polymorphicRelation();

Q_ASSERT( mRelation.polymorphicRelation().isValid() );

mRelation.referencingLayer()->changeAttributeValue( fid,
referencingLayer->fields().indexFromName( polyRel.referencedLayerField() ),
referencingLayer->fields().field( polyRel.referencedLayerField() ).type() );
}

QMapIterator<int, QgsField> it( keyFields );
while ( it.hasNext() )
{
Expand Down
4 changes: 2 additions & 2 deletions src/ui/qgsrelationmanageraddpolymorphicdialogbase.ui
Expand Up @@ -15,7 +15,7 @@
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,2,0">
<item row="2" column="0">
<widget class="QLabel" name="mReferencedLayerFieldLayer">
<widget class="QLabel" name="mReferencedLayerFieldLabel">
<property name="text">
<string>Layer field</string>
</property>
Expand Down Expand Up @@ -114,7 +114,7 @@
<widget class="QgsMapLayerComboBox" name="mReferencingLayerComboBox"/>
</item>
<item row="3" column="1" colspan="2">
<widget class="QgsFieldExpressionWidget" name="mReferencedLayerExpressionWidget"/>
<widget class="QgsFieldExpressionWidget" name="mReferencedLayerExpressionWidget" native="true"/>
</item>
<item row="8" column="0">
<widget class="QLabel" name="mReferencedLayersLabel">
Expand Down
20 changes: 20 additions & 0 deletions src/ui/qgsrelationmanagerdialogbase.ui
Expand Up @@ -73,6 +73,15 @@
</item>
<item>
<widget class="QToolButton" name="mBtnAddRelation">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>Add Relation</string>
</property>
Expand Down Expand Up @@ -131,6 +140,17 @@
<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>
</action>
<action name="mActionEditPolymorphicRelation">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Edit Polymorphic Relation</string>
</property>
<property name="toolTip">
<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>
</action>
</widget>
<resources>
<include location="../../images/images.qrc"/>
Expand Down

0 comments on commit 371534c

Please sign in to comment.