Skip to content

Commit

Permalink
offer a restriced set of fields as referenced fiels for polymorphic r…
Browse files Browse the repository at this point in the history
…elations

only offer the fields that are across all the referenced layers

fixes #41959
  • Loading branch information
3nids committed Jun 1, 2021
1 parent 5efb8a4 commit ac8cb99
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 117 deletions.
61 changes: 59 additions & 2 deletions src/app/qgsrelationaddpolymorphicdialog.cpp
Expand Up @@ -67,6 +67,7 @@ QgsRelationAddPolymorphicDialog::QgsRelationAddPolymorphicDialog( bool isEditDia
"Duplications are made by the feature duplication action.\n"
"The default actions are activated in the Action section of the layer properties." ) );

mFieldsMappingWidget->setEnabled( false );
addFieldsRow();
updateTypeConfigWidget();
updateDialogButtons();
Expand All @@ -78,6 +79,7 @@ QgsRelationAddPolymorphicDialog::QgsRelationAddPolymorphicDialog( bool isEditDia
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDialog::updateDialogButtons );
connect( mRelationStrengthComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) { Q_UNUSED( index ); updateDialogButtons(); } );
connect( mReferencedLayerExpressionWidget, static_cast<void ( QgsFieldExpressionWidget::* )( const QString & )>( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsRelationAddPolymorphicDialog::updateDialogButtons );
connect( mReferencedLayersComboBox, &QgsCheckableComboBox::checkedItemsChanged, this, &QgsRelationAddPolymorphicDialog::referencedLayersChanged );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDialog::updateChildRelationsComboBox );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDialog::updateReferencingFieldsComboBoxes );
connect( mReferencingLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsRelationAddPolymorphicDialog::updateReferencedLayerFieldComboBox );
Expand Down Expand Up @@ -114,7 +116,7 @@ void QgsRelationAddPolymorphicDialog::updateTypeConfigWidget()
void QgsRelationAddPolymorphicDialog::addFieldsRow()
{
QgsFieldComboBox *referencingField = new QgsFieldComboBox( this );
QLineEdit *referencedPolymorphicField = new QLineEdit( this );
QComboBox *referencedPolymorphicField = new QComboBox( this );
int index = mFieldsMappingTable->rowCount();

referencingField->setLayer( mReferencingLayerComboBox->currentLayer() );
Expand Down Expand Up @@ -196,7 +198,10 @@ QList< QPair< QString, QString > > QgsRelationAddPolymorphicDialog::fieldPairs()
QList< QPair< QString, QString > > references;
for ( int i = 0, l = mFieldsMappingTable->rowCount(); i < l; i++ )
{
QString referencedField = static_cast<QLineEdit *>( mFieldsMappingTable->cellWidget( i, 0 ) )->text();
QComboBox *referencedFieldComboBox = static_cast<QComboBox *>( mFieldsMappingTable->cellWidget( i, 0 ) );
if ( referencedFieldComboBox->currentData().toInt() == -1 )
continue;
QString referencedField = referencedFieldComboBox->currentText();
QString referencingField = static_cast<QgsFieldComboBox *>( mFieldsMappingTable->cellWidget( i, 1 ) )->currentField();
references << qMakePair( referencingField, referencedField );
}
Expand Down Expand Up @@ -279,3 +284,55 @@ void QgsRelationAddPolymorphicDialog::updateReferencedLayerFieldComboBox()
{
mReferencedLayerFieldComboBox->setLayer( mReferencingLayerComboBox->currentLayer() );
}

void QgsRelationAddPolymorphicDialog::referencedLayersChanged()
{
const QStringList &layerIds = referencedLayerIds();
mFieldsMappingWidget->setEnabled( layerIds.count() > 0 );

bool firstLayer = true;
QSet<QString> fields;
for ( const QString &layerId : layerIds )
{
QgsVectorLayer *vl = QgsProject::instance()->mapLayer<QgsVectorLayer *>( layerId );
if ( vl && vl->isValid() )
{
const QSet layerFields = qgis::listToSet( vl->fields().names() );
if ( firstLayer )
{
fields = layerFields;
firstLayer = false;
}
else
{
fields.intersect( layerFields );
}
}
}

for ( int i = 0, l = mFieldsMappingTable->rowCount(); i < l; i++ )
{
QComboBox *cb = static_cast<QComboBox *>( mFieldsMappingTable->cellWidget( i, 0 ) );
const QString currentField = cb->currentText();
cb->clear();
if ( fields.count() > 0 )
{
const QSet<QString> constFields = fields;
for ( const QString &field : constFields )
{
cb->addItem( field );
if ( field == currentField )
cb->setCurrentText( field );
}
}
else
{
cb->addItem( tr( "None" ), -1 );
cb->addItem( tr( "the referenced layers have no common fields." ), -1 );
QStandardItem *item = qobject_cast<QStandardItemModel *>( cb->model() )->item( 1 );
item->setFlags( item->flags() & ~Qt::ItemIsEnabled );
}
}

updateDialogButtons();
}
1 change: 1 addition & 0 deletions src/app/qgsrelationaddpolymorphicdialog.h
Expand Up @@ -98,6 +98,7 @@ class APP_EXPORT QgsRelationAddPolymorphicDialog : public QDialog, private Ui::Q
void updateChildRelationsComboBox();
void updateReferencingFieldsComboBoxes();
void updateReferencedLayerFieldComboBox();
void referencedLayersChanged();

private:
bool isDefinitionValid();
Expand Down
241 changes: 126 additions & 115 deletions src/ui/qgsrelationmanageraddpolymorphicdialogbase.ui
Expand Up @@ -6,28 +6,67 @@
<rect>
<x>0</x>
<y>0</y>
<width>454</width>
<height>490</height>
<width>297</width>
<height>487</height>
</rect>
</property>
<property name="windowTitle">
<string>Add Polymorphic Relation</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,2,0">
<item row="1" column="0">
<widget class="QLabel" name="mReferencingLayerLabel">
<layout class="QGridLayout" name="gridLayout" columnstretch="1,0,0,0">
<item row="7" column="0">
<widget class="QLabel" name="mReferencedLayersLabel">
<property name="text">
<string>Referencing layer</string>
<string>Referenced layers</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="mIdLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>[Generated automatically]</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsFieldComboBox" name="mReferencedLayerFieldComboBox"/>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="mRelationStrengthComboBox"/>
</item>
<item row="1" column="1">
<widget class="QgsMapLayerComboBox" name="mReferencingLayerComboBox"/>
</item>
<item row="7" column="1">
<widget class="QgsCheckableComboBox" name="mReferencedLayersComboBox"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="mRelationStrengthLabel">
<property name="text">
<string>Relationship strength</string>
</property>
</widget>
</item>
<item row="12" column="0" colspan="3">
<item row="13" column="0" colspan="2">
<widget class="QDialogButtonBox" name="mButtonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mReferencingLayerLabel">
<property name="text">
<string>Referencing layer</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mReferencedLayerFieldLabel">
<property name="text">
Expand All @@ -42,131 +81,104 @@
</property>
</widget>
</item>
<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>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="9" column="2">
<layout class="QVBoxLayout" name="mFieldsMappingButtonsVBoxLayout">
<item>
<widget class="QToolButton" name="mFieldsMappingAddButton">
<property name="toolTip">
<string>Add new field pair as part of a composite foreign key</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mFieldsMappingRemoveButton">
<property name="toolTip">
<string>Remove the selected or last pair of fields</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
</property>
</widget>
</item>
<item>
<spacer name="mFieldsMappingVSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="8" column="0" colspan="2">
<widget class="QLabel" name="mFieldsMappingLabel">
<property name="text">
<string>Fields mapping</string>
</property>
</widget>
</item>
<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="9" column="0" colspan="2">
<widget class="QTableWidget" name="mFieldsMappingTable">
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="rowCount">
<number>0</number>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>150</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string comment="polymorphic relations">Referenced (parent)</string>
</property>
</column>
<column>
<property name="text">
<string>Referencing (child)</string>
</property>
</column>
</widget>
<item row="3" column="1">
<widget class="QgsFieldExpressionWidget" name="mReferencedLayerExpressionWidget" native="true"/>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="mIdLineEdit">
<property name="placeholderText">
<string>[Generated automatically]</string>
</property>
<item row="9" column="0" colspan="2">
<widget class="QWidget" name="mFieldsMappingWidget" native="true">
<layout class="QGridLayout" name="mFieldsMappingLayout">
<item row="0" column="0">
<widget class="QTableWidget" name="mFieldsMappingTable">
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="rowCount">
<number>0</number>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>150</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string comment="polymorphic relations">Referenced (parent)</string>
</property>
</column>
<column>
<property name="text">
<string>Referencing (child)</string>
</property>
</column>
</widget>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="mFieldsMappingButtonsVBoxLayout">
<item>
<widget class="QToolButton" name="mFieldsMappingAddButton">
<property name="toolTip">
<string>Add new field pair as part of a composite foreign key</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mFieldsMappingRemoveButton">
<property name="toolTip">
<string>Remove the selected or last pair of fields</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
</property>
</widget>
</item>
<item>
<spacer name="mFieldsMappingVSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QgsFieldExpressionWidget" name="mReferencedLayerExpressionWidget" native="true"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="mRelationStrengthLabel">
<item row="12" column="0" colspan="2">
<widget class="QLabel" name="mPolymorphicRelationHelpLabel">
<property name="text">
<string>Relationship strength</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="6" column="1" colspan="2">
<widget class="QComboBox" name="mRelationStrengthComboBox"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="mReferencedLayersLabel">
<item row="8" column="0" colspan="2">
<widget class="QLabel" name="mFieldsMappingLabel">
<property name="text">
<string>Referenced layers</string>
<string>Fields mapping</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="2">
<widget class="QgsCheckableComboBox" name="mReferencedLayersComboBox"/>
</item>
</layout>
</widget>
<customwidgets>
Expand Down Expand Up @@ -197,7 +209,6 @@
<tabstop>mReferencingLayerComboBox</tabstop>
<tabstop>mReferencedLayerFieldComboBox</tabstop>
<tabstop>mRelationStrengthComboBox</tabstop>
<tabstop>mFieldsMappingTable</tabstop>
<tabstop>mFieldsMappingAddButton</tabstop>
<tabstop>mFieldsMappingRemoveButton</tabstop>
</tabstops>
Expand Down

0 comments on commit ac8cb99

Please sign in to comment.