Skip to content

Commit

Permalink
Make QgsRelation implicitly shared
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Aug 24, 2018
1 parent a5a6f00 commit 86e1382
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 92 deletions.
3 changes: 3 additions & 0 deletions python/core/auto_generated/qgsrelation.sip.in
Expand Up @@ -11,6 +11,7 @@




class QgsRelation
{

Expand All @@ -34,6 +35,8 @@ class QgsRelation
%Docstring
Default constructor. Creates an invalid relation.
%End
~QgsRelation();
QgsRelation( const QgsRelation &other );

static QgsRelation createFromXml( const QDomNode &node, QgsReadWriteContext &context );
%Docstring
Expand Down
159 changes: 93 additions & 66 deletions src/core/qgsrelation.cpp
Expand Up @@ -20,6 +20,26 @@
#include "qgslogger.h"
#include "qgsproject.h"
#include "qgsvectorlayer.h"
#include "qgsrelation_p.h"

QgsRelation::QgsRelation()
{
}

QgsRelation::~QgsRelation()
{
}

QgsRelation::QgsRelation( const QgsRelation &other )
: d( other.d )
{
}

QgsRelation &QgsRelation::operator=( const QgsRelation &other )
{
d = other.d;
return *this;
}

QgsRelation QgsRelation::createFromXml( const QDomNode &node, QgsReadWriteContext &context )
{
Expand Down Expand Up @@ -61,19 +81,19 @@ QgsRelation QgsRelation::createFromXml( const QDomNode &node, QgsReadWriteContex
QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencedLayerId ) );
}

relation.mReferencingLayerId = referencingLayerId;
relation.mReferencingLayer = qobject_cast<QgsVectorLayer *>( referencingLayer );
relation.mReferencedLayerId = referencedLayerId;
relation.mReferencedLayer = qobject_cast<QgsVectorLayer *>( referencedLayer );
relation.mRelationId = id;
relation.mRelationName = name;
if ( strength == "Composition" )
relation.d->mReferencingLayerId = referencingLayerId;
relation.d->mReferencingLayer = qobject_cast<QgsVectorLayer *>( referencingLayer );
relation.d->mReferencedLayerId = referencedLayerId;
relation.d->mReferencedLayer = qobject_cast<QgsVectorLayer *>( referencedLayer );
relation.d->mRelationId = id;
relation.d->mRelationName = name;
if ( strength == QLatin1String( "Composition" ) )
{
relation.mRelationStrength = RelationStrength::Composition;
relation.d->mRelationStrength = RelationStrength::Composition;
}
else
{
relation.mRelationStrength = RelationStrength::Association;
relation.d->mRelationStrength = RelationStrength::Association;
}

QDomNodeList references = elem.elementsByTagName( QStringLiteral( "fieldRef" ) );
Expand All @@ -95,11 +115,11 @@ QgsRelation QgsRelation::createFromXml( const QDomNode &node, QgsReadWriteContex
void QgsRelation::writeXml( QDomNode &node, QDomDocument &doc ) const
{
QDomElement elem = doc.createElement( QStringLiteral( "relation" ) );
elem.setAttribute( QStringLiteral( "id" ), mRelationId );
elem.setAttribute( QStringLiteral( "name" ), mRelationName );
elem.setAttribute( QStringLiteral( "referencingLayer" ), mReferencingLayerId );
elem.setAttribute( QStringLiteral( "referencedLayer" ), mReferencedLayerId );
if ( mRelationStrength == RelationStrength::Composition )
elem.setAttribute( QStringLiteral( "id" ), d->mRelationId );
elem.setAttribute( QStringLiteral( "name" ), d->mRelationName );
elem.setAttribute( QStringLiteral( "referencingLayer" ), d->mReferencingLayerId );
elem.setAttribute( QStringLiteral( "referencedLayer" ), d->mReferencedLayerId );
if ( d->mRelationStrength == RelationStrength::Composition )
{
elem.setAttribute( QStringLiteral( "strength" ), QStringLiteral( "Composition" ) );
}
Expand All @@ -108,7 +128,7 @@ void QgsRelation::writeXml( QDomNode &node, QDomDocument &doc ) const
elem.setAttribute( QStringLiteral( "strength" ), QStringLiteral( "Association" ) );
}

Q_FOREACH ( const FieldPair &fields, mFieldPairs )
Q_FOREACH ( const FieldPair &fields, d->mFieldPairs )
{
QDomElement referenceElem = doc.createElement( QStringLiteral( "fieldRef" ) );
referenceElem.setAttribute( QStringLiteral( "referencingField" ), fields.first );
Expand All @@ -121,45 +141,52 @@ void QgsRelation::writeXml( QDomNode &node, QDomDocument &doc ) const

void QgsRelation::setId( const QString &id )
{
mRelationId = id;
d.detach();
d->mRelationId = id;

updateRelationStatus();
}

void QgsRelation::setName( const QString &name )
{
mRelationName = name;
d.detach();
d->mRelationName = name;
}


void QgsRelation::setStrength( RelationStrength strength )
{
mRelationStrength = strength;
d.detach();
d->mRelationStrength = strength;
}

void QgsRelation::setReferencingLayer( const QString &id )
{
mReferencingLayerId = id;
d.detach();
d->mReferencingLayerId = id;

updateRelationStatus();
}

void QgsRelation::setReferencedLayer( const QString &id )
{
mReferencedLayerId = id;
d.detach();
d->mReferencedLayerId = id;

updateRelationStatus();
}

void QgsRelation::addFieldPair( const QString &referencingField, const QString &referencedField )
{
mFieldPairs << FieldPair( referencingField, referencedField );
d.detach();
d->mFieldPairs << FieldPair( referencingField, referencedField );
updateRelationStatus();
}

void QgsRelation::addFieldPair( const FieldPair &fieldPair )
{
mFieldPairs << fieldPair;
d.detach();
d->mFieldPairs << fieldPair;
updateRelationStatus();
}

Expand All @@ -182,7 +209,7 @@ QString QgsRelation::getRelatedFeaturesFilter( const QgsFeature &feature ) const
{
QStringList conditions;

Q_FOREACH ( const QgsRelation::FieldPair &fieldPair, mFieldPairs )
Q_FOREACH ( const QgsRelation::FieldPair &fieldPair, d->mFieldPairs )
{
QVariant val( feature.attribute( fieldPair.referencedField() ) );
conditions << QgsExpression::createFieldEqualityExpression( fieldPair.referencingField(), val );
Expand All @@ -195,7 +222,7 @@ QgsFeatureRequest QgsRelation::getReferencedFeatureRequest( const QgsAttributes
{
QStringList conditions;

Q_FOREACH ( const QgsRelation::FieldPair &fieldPair, mFieldPairs )
Q_FOREACH ( const QgsRelation::FieldPair &fieldPair, d->mFieldPairs )
{
int referencingIdx = referencingLayer()->fields().indexFromName( fieldPair.referencingField() );
conditions << QgsExpression::createFieldEqualityExpression( fieldPair.referencedField(), attributes.at( referencingIdx ) );
Expand All @@ -220,67 +247,67 @@ QgsFeature QgsRelation::getReferencedFeature( const QgsFeature &feature ) const
QgsFeatureRequest request = getReferencedFeatureRequest( feature );

QgsFeature f;
mReferencedLayer->getFeatures( request ).nextFeature( f );
d->mReferencedLayer->getFeatures( request ).nextFeature( f );
return f;
}

QString QgsRelation::name() const
{
return mRelationName;
return d->mRelationName;
}

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

QString QgsRelation::id() const
{
return mRelationId;
return d->mRelationId;
}

void QgsRelation::generateId()
{
mRelationId = QStringLiteral( "%1_%2_%3_%4" )
.arg( referencingLayerId(),
mFieldPairs.at( 0 ).referencingField(),
referencedLayerId(),
mFieldPairs.at( 0 ).referencedField() );
d->mRelationId = QStringLiteral( "%1_%2_%3_%4" )
.arg( referencingLayerId(),
d->mFieldPairs.at( 0 ).referencingField(),
referencedLayerId(),
d->mFieldPairs.at( 0 ).referencedField() );
updateRelationStatus();
}

QString QgsRelation::referencingLayerId() const
{
return mReferencingLayerId;
return d->mReferencingLayerId;
}

QgsVectorLayer *QgsRelation::referencingLayer() const
{
return mReferencingLayer;
return d->mReferencingLayer;
}

QString QgsRelation::referencedLayerId() const
{
return mReferencedLayerId;
return d->mReferencedLayerId;
}

QgsVectorLayer *QgsRelation::referencedLayer() const
{
return mReferencedLayer;
return d->mReferencedLayer;
}

QList<QgsRelation::FieldPair> QgsRelation::fieldPairs() const
{
return mFieldPairs;
return d->mFieldPairs;
}

QgsAttributeList QgsRelation::referencedFields() const
{
QgsAttributeList attrs;

Q_FOREACH ( const FieldPair &pair, mFieldPairs )
Q_FOREACH ( const FieldPair &pair, d->mFieldPairs )
{
attrs << mReferencedLayer->fields().lookupField( pair.second );
attrs << d->mReferencedLayer->fields().lookupField( pair.second );
}
return attrs;
}
Expand All @@ -289,27 +316,27 @@ QgsAttributeList QgsRelation::referencingFields() const
{
QgsAttributeList attrs;

Q_FOREACH ( const FieldPair &pair, mFieldPairs )
Q_FOREACH ( const FieldPair &pair, d->mFieldPairs )
{
attrs << mReferencingLayer->fields().lookupField( pair.first );
attrs << d->mReferencingLayer->fields().lookupField( pair.first );
}
return attrs;

}

bool QgsRelation::isValid() const
{
return mValid;
return d->mValid;
}

bool QgsRelation::hasEqualDefinition( const QgsRelation &other ) const
{
return mReferencedLayerId == other.mReferencedLayerId && mReferencingLayerId == other.mReferencingLayerId && mFieldPairs == other.mFieldPairs;
return d->mReferencedLayerId == other.d->mReferencedLayerId && d->mReferencingLayerId == other.d->mReferencingLayerId && d->mFieldPairs == other.d->mFieldPairs;
}

QString QgsRelation::resolveReferencedField( const QString &referencingField ) const
{
Q_FOREACH ( const FieldPair &pair, mFieldPairs )
Q_FOREACH ( const FieldPair &pair, d->mFieldPairs )
{
if ( pair.first == referencingField )
return pair.second;
Expand All @@ -319,7 +346,7 @@ QString QgsRelation::resolveReferencedField( const QString &referencingField ) c

QString QgsRelation::resolveReferencingField( const QString &referencedField ) const
{
Q_FOREACH ( const FieldPair &pair, mFieldPairs )
Q_FOREACH ( const FieldPair &pair, d->mFieldPairs )
{
if ( pair.second == referencedField )
return pair.first;
Expand All @@ -331,48 +358,48 @@ void QgsRelation::updateRelationStatus()
{
const QMap<QString, QgsMapLayer *> &mapLayers = QgsProject::instance()->mapLayers();

mReferencingLayer = qobject_cast<QgsVectorLayer *>( mapLayers[mReferencingLayerId] );
mReferencedLayer = qobject_cast<QgsVectorLayer *>( mapLayers[mReferencedLayerId] );
d->mReferencingLayer = qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencingLayerId] );
d->mReferencedLayer = qobject_cast<QgsVectorLayer *>( mapLayers[d->mReferencedLayerId] );

mValid = true;
d->mValid = true;

if ( mRelationId.isEmpty() )
if ( d->mRelationId.isEmpty() )
{
QgsDebugMsg( "Invalid relation: no ID" );
mValid = false;
d->mValid = false;
}
else
{
if ( !mReferencedLayer )
if ( !d->mReferencedLayer )
{
QgsDebugMsgLevel( QStringLiteral( "Invalid relation: referenced layer does not exist. ID: %1" ).arg( mReferencedLayerId ), 4 );
mValid = false;
QgsDebugMsgLevel( QStringLiteral( "Invalid relation: referenced layer does not exist. ID: %1" ).arg( d->mReferencedLayerId ), 4 );
d->mValid = false;
}
else if ( !mReferencingLayer )
else if ( !d->mReferencingLayer )
{
QgsDebugMsgLevel( QStringLiteral( "Invalid relation: referencing layer does not exist. ID: %2" ).arg( mReferencingLayerId ), 4 );
mValid = false;
QgsDebugMsgLevel( QStringLiteral( "Invalid relation: referencing layer does not exist. ID: %2" ).arg( d->mReferencingLayerId ), 4 );
d->mValid = false;
}
else
{
if ( mFieldPairs.count() < 1 )
if ( d->mFieldPairs.count() < 1 )
{
QgsDebugMsgLevel( "Invalid relation: no pair of field is specified.", 4 );
mValid = false;
d->mValid = false;
}

Q_FOREACH ( const FieldPair &fieldPair, mFieldPairs )
Q_FOREACH ( const FieldPair &fieldPair, d->mFieldPairs )
{
if ( -1 == mReferencingLayer->fields().lookupField( fieldPair.first ) )
if ( -1 == d->mReferencingLayer->fields().lookupField( fieldPair.first ) )
{
QgsDebugMsg( QStringLiteral( "Invalid relation: field %1 does not exist in referencing layer %2" ).arg( fieldPair.first, mReferencingLayer->name() ) );
mValid = false;
QgsDebugMsg( QStringLiteral( "Invalid relation: field %1 does not exist in referencing layer %2" ).arg( fieldPair.first, d->mReferencingLayer->name() ) );
d->mValid = false;
break;
}
else if ( -1 == mReferencedLayer->fields().lookupField( fieldPair.second ) )
else if ( -1 == d->mReferencedLayer->fields().lookupField( fieldPair.second ) )
{
QgsDebugMsg( QStringLiteral( "Invalid relation: field %1 does not exist in referencedg layer %2" ).arg( fieldPair.second, mReferencedLayer->name() ) );
mValid = false;
QgsDebugMsg( QStringLiteral( "Invalid relation: field %1 does not exist in referencedg layer %2" ).arg( fieldPair.second, d->mReferencedLayer->name() ) );
d->mValid = false;
break;
}
}
Expand Down

0 comments on commit 86e1382

Please sign in to comment.