Skip to content

Commit

Permalink
relation editor widget some multiedit support for n:m relations
Browse files Browse the repository at this point in the history
  • Loading branch information
domi4484 committed Nov 8, 2021
1 parent 90d3062 commit 20c79cd
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 54 deletions.
96 changes: 50 additions & 46 deletions src/gui/qgsabstractrelationeditorwidget.cpp
Expand Up @@ -221,41 +221,40 @@ void QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &geometry )

if ( mNmRelation.isValid() )
{
if ( multiEditModeActive() )
{
QgsLogger::warning( tr( "Adding of feature not supported in multiple edit mode for n:m relations" ) );
return;
}

// only normal relations support m:n relation
Q_ASSERT( mNmRelation.type() == QgsRelation::Normal );

// n:m Relation: first let the user create a new feature on the other table
// and autocreate a new linking feature.
QgsFeature f;
if ( !vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), geometry, &f ) )
QgsFeature finalFeature;
if ( !vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), geometry, &finalFeature ) )
return;

// Expression context for the linking table
QgsExpressionContext context = mRelation.referencingLayer()->createExpressionContext();

QgsAttributeMap linkAttributes = keyAttrs;
const auto constFieldPairs = mRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
{
const int index = fields.indexOf( fieldPair.first );
linkAttributes.insert( index, mFeatureList.first().attribute( fieldPair.second ) );
}

const auto constNmFieldPairs = mNmRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constNmFieldPairs )
for ( const QgsFeature &editingFeature : mFeatureList )
{
const int index = fields.indexOf( fieldPair.first );
linkAttributes.insert( index, f.attribute( fieldPair.second ) );
}
QgsFeature linkFeature = QgsVectorLayerUtils::createFeature( mRelation.referencingLayer(), QgsGeometry(), linkAttributes, &context );
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
{
const int index = fields.indexOf( fieldPair.first );
linkAttributes.insert( index, editingFeature.attribute( fieldPair.second ) );
}

const auto constNmFieldPairs = mNmRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constNmFieldPairs )
{
const int index = fields.indexOf( fieldPair.first );
linkAttributes.insert( index, finalFeature.attribute( fieldPair.second ) );
}

mRelation.referencingLayer()->addFeature( linkFeature );
QgsFeature linkFeature = QgsVectorLayerUtils::createFeature( mRelation.referencingLayer(), QgsGeometry(), linkAttributes, &context );

mRelation.referencingLayer()->addFeature( linkFeature );
}
}
else
{
Expand All @@ -267,6 +266,7 @@ void QgsAbstractRelationEditorWidget::addFeature( const QgsGeometry &geometry )
if ( !vlTools->addFeature( mRelation.referencingLayer(), keyAttrs, geometry, &linkFeature ) )
return;

// In multiedit add to other features to but whitout dialog
for ( const QgsFeature &feature : mFeatureList )
{
// First feature already added
Expand Down Expand Up @@ -413,12 +413,6 @@ void QgsAbstractRelationEditorWidget::deleteFeatures( const QgsFeatureIds &fids

void QgsAbstractRelationEditorWidget::linkFeature()
{
if ( multiEditModeActive() )
{
QgsLogger::warning( tr( "Linking of feature not supported in multiple edit mode" ) );
return;
}

QgsVectorLayer *layer = nullptr;

if ( mNmRelation.isValid() )
Expand All @@ -430,6 +424,12 @@ void QgsAbstractRelationEditorWidget::linkFeature()
}
else
{
if ( multiEditModeActive() )
{
QgsLogger::warning( tr( "For 1:n relations is not possible to link to multiple features" ) );
return;
}

layer = mRelation.referencingLayer();
}

Expand All @@ -447,12 +447,6 @@ void QgsAbstractRelationEditorWidget::onLinkFeatureDlgAccepted()
{
QgsFeatureSelectionDlg *selectionDlg = qobject_cast<QgsFeatureSelectionDlg *>( sender() );

if ( multiEditModeActive() )
{
QgsLogger::warning( tr( "Linking of feature not supported in multiple edit mode" ) );
return;
}

if ( mNmRelation.isValid() )
{
// only normal relations support m:n relation
Expand Down Expand Up @@ -484,24 +478,28 @@ void QgsAbstractRelationEditorWidget::onLinkFeatureDlgAccepted()
polyRel.layerRepresentation( mRelation.referencedLayer() ) );
}

const auto constFieldPairs = mRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
{
const int index = fields.indexOf( fieldPair.first );
linkAttributes.insert( index, mFeatureList.first().attribute( fieldPair.second ) );
}

while ( it.nextFeature( relatedFeature ) )
{
const auto constFieldPairs = mNmRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
for ( const QgsFeature &editFeature : mFeatureList )
{
const int index = fields.indexOf( fieldPair.first );
linkAttributes.insert( index, relatedFeature.attribute( fieldPair.second ) );
{
const auto constFieldPairs = mRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
{
const int index = fields.indexOf( fieldPair.first );
linkAttributes.insert( index, editFeature.attribute( fieldPair.second ) );
}
}

const auto constFieldPairs = mNmRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
{
const int index = fields.indexOf( fieldPair.first );
linkAttributes.insert( index, relatedFeature.attribute( fieldPair.second ) );
}
const QgsFeature linkFeature = QgsVectorLayerUtils::createFeature( mRelation.referencingLayer(), QgsGeometry(), linkAttributes, &context );
newFeatures << linkFeature;
}
const QgsFeature linkFeature = QgsVectorLayerUtils::createFeature( mRelation.referencingLayer(), QgsGeometry(), linkAttributes, &context );

newFeatures << linkFeature;
}

mRelation.referencingLayer()->addFeatures( newFeatures );
Expand All @@ -513,6 +511,12 @@ void QgsAbstractRelationEditorWidget::onLinkFeatureDlgAccepted()
}
else
{
if ( multiEditModeActive() )
{
QgsLogger::warning( tr( "For 1:n relations is not possible to link to multiple features" ) );
return;
}

QMap<int, QVariant> keys;
const auto constFieldPairs = mRelation.fieldPairs();
for ( const QgsRelation::FieldPair &fieldPair : constFieldPairs )
Expand Down
45 changes: 37 additions & 8 deletions src/gui/qgsrelationeditorwidget.cpp
Expand Up @@ -343,8 +343,14 @@ void QgsRelationEditorWidget::updateButtons()
const bool multieditLinkedChildSelected = ! selectedChildFeatureIds().isEmpty();

canAddGeometry = false;

canRemove = canRemove && !nmRelation().isValid();
canRemove = canRemove && multieditLinkedChildSelected;
canLink = false;

// In 1:n relations an element can be linked only to 1 feature
canLink = canLink && mNmRelation.isValid();

canUnlink = canUnlink && !mNmRelation.isValid();
canUnlink = canUnlink && multieditLinkedChildSelected;
}
else
Expand Down Expand Up @@ -409,7 +415,6 @@ void QgsRelationEditorWidget::addFeatureGeometry()
mMessageBarItem = QgsMessageBar::createMessage( title, msg, this );
lMainMessageBar->pushItem( mMessageBarItem );
}

}

void QgsRelationEditorWidget::onDigitizingCompleted( const QgsFeature &feature )
Expand Down Expand Up @@ -486,12 +491,36 @@ void QgsRelationEditorWidget::updateUi()
QgsFeature featureChild;
while ( featureIterator.nextFeature( featureChild ) )
{
QTreeWidgetItem *treeWidgetItemChild = new QTreeWidgetItem( treeWidgetItem );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Child ) );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ), featureChild.id() );
treeWidgetItemChild->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mRelation.referencingLayer(), featureChild ) );
treeWidgetItemChild->setIcon( 0, QgsIconUtils::iconForLayer( mRelation.referencingLayer() ) );
treeWidgetItem->addChild( treeWidgetItemChild );
if ( mNmRelation.isValid() )
{
QgsFeatureRequest requestFinalChild = mNmRelation.getReferencedFeatureRequest( featureChild );
QgsFeatureIterator featureIteratorFinalChild = mNmRelation.referencedLayer()->getFeatures( requestFinalChild );
QgsFeature featureChildChild;
while ( featureIteratorFinalChild.nextFeature( featureChildChild ) )
{
QTreeWidgetItem *treeWidgetItemChild = new QTreeWidgetItem( treeWidgetItem );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Child ) );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ), featureChildChild.id() );
treeWidgetItemChild->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mNmRelation.referencedLayer(), featureChildChild ) );
treeWidgetItemChild->setIcon( 0, QgsIconUtils::iconForLayer( mNmRelation.referencedLayer() ) );

// For nm relations deleting/unlinking ist not supported now, so selection
// is also not possible
if ( nmRelation().isValid() )
treeWidgetItem->setFlags( Qt::ItemIsEnabled );

treeWidgetItem->addChild( treeWidgetItemChild );
}
}
else
{
QTreeWidgetItem *treeWidgetItemChild = new QTreeWidgetItem( treeWidgetItem );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureType ), static_cast<int>( MultiEditFeatureType::Child ) );
treeWidgetItemChild->setData( 0, static_cast<int>( MultiEditTreeWidgetRole::FeatureId ), featureChild.id() );
treeWidgetItemChild->setText( 0, QgsVectorLayerUtils::getFeatureDisplayString( mRelation.referencingLayer(), featureChild ) );
treeWidgetItemChild->setIcon( 0, QgsIconUtils::iconForLayer( mRelation.referencingLayer() ) );
treeWidgetItem->addChild( treeWidgetItemChild );
}
}

treeWidgetItem->setExpanded( true );
Expand Down

0 comments on commit 20c79cd

Please sign in to comment.