From 85a7327aaecbb39098ed65bd70d3e9573a89879a Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 18 Apr 2017 14:01:48 +1000 Subject: [PATCH] Add some useful operators to layer reference --- src/core/layertree/qgslayertreelayer.cpp | 28 ++++++++++++------------ src/core/layertree/qgslayertreelayer.h | 2 +- src/core/qgsmaplayerref.h | 22 ++++++++++++++++++- src/core/qgsvectorlayerjoininfo.h | 2 +- tests/src/core/testqgsmaplayer.cpp | 23 ++++++++++++------- 5 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/core/layertree/qgslayertreelayer.cpp b/src/core/layertree/qgslayertreelayer.cpp index ef998699eef..a0ba7d7a6c7 100644 --- a/src/core/layertree/qgslayertreelayer.cpp +++ b/src/core/layertree/qgslayertreelayer.cpp @@ -45,7 +45,7 @@ QgsLayerTreeLayer::QgsLayerTreeLayer( const QgsLayerTreeLayer &other ) void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool looseMatching ) { - if ( mRef.layer ) + if ( mRef ) return; // already assigned if ( !looseMatching ) @@ -57,7 +57,7 @@ void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool loose mRef.resolveWeakly( project ); } - if ( !mRef.layer ) + if ( !mRef ) return; attachToLayer(); @@ -66,7 +66,7 @@ void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool loose void QgsLayerTreeLayer::attachToLayer() { - if ( !mRef.layer ) + if ( !mRef ) return; connect( mRef.layer, &QgsMapLayer::nameChanged, this, &QgsLayerTreeLayer::layerNameChanged ); @@ -76,16 +76,16 @@ void QgsLayerTreeLayer::attachToLayer() QString QgsLayerTreeLayer::name() const { - return mRef.layer ? mRef.layer->name() : mLayerName; + return mRef ? mRef->name() : mLayerName; } void QgsLayerTreeLayer::setName( const QString &n ) { - if ( mRef.layer ) + if ( mRef ) { - if ( mRef.layer->name() == n ) + if ( mRef->name() == n ) return; - mRef.layer->setName( n ); + mRef->setName( n ); // no need to emit signal: we will be notified from layer's nameChanged() signal } else @@ -136,10 +136,10 @@ void QgsLayerTreeLayer::writeXml( QDomElement &parentElement ) elem.setAttribute( QStringLiteral( "id" ), layerId() ); elem.setAttribute( QStringLiteral( "name" ), name() ); - if ( mRef.layer ) + if ( mRef ) { - elem.setAttribute( "source", mRef.layer->publicSource() ); - elem.setAttribute( "providerKey", mRef.layer->dataProvider() ? mRef.layer->dataProvider()->name() : QString() ); + elem.setAttribute( "source", mRef->publicSource() ); + elem.setAttribute( "providerKey", mRef->dataProvider() ? mRef->dataProvider()->name() : QString() ); } elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) ); @@ -162,9 +162,9 @@ QgsLayerTreeLayer *QgsLayerTreeLayer::clone() const void QgsLayerTreeLayer::layerWillBeDeleted() { - Q_ASSERT( mRef.layer ); + Q_ASSERT( mRef ); - mLayerName = mRef.layer->name(); + mLayerName = mRef->name(); // in theory we do not even need to do this - the weak ref should clear itself mRef.layer.clear(); // layerId stays in the reference @@ -175,6 +175,6 @@ void QgsLayerTreeLayer::layerWillBeDeleted() void QgsLayerTreeLayer::layerNameChanged() { - Q_ASSERT( mRef.layer ); - emit nameChanged( this, mRef.layer->name() ); + Q_ASSERT( mRef ); + emit nameChanged( this, mRef->name() ); } diff --git a/src/core/layertree/qgslayertreelayer.h b/src/core/layertree/qgslayertreelayer.h index 5836a3d7916..8a06b7c1da2 100644 --- a/src/core/layertree/qgslayertreelayer.h +++ b/src/core/layertree/qgslayertreelayer.h @@ -54,7 +54,7 @@ class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode QString layerId() const { return mRef.layerId; } - QgsMapLayer *layer() const { return mRef.get(); } + QgsMapLayer *layer() const { return &mRef; } /** * Returns the layer's name. diff --git a/src/core/qgsmaplayerref.h b/src/core/qgsmaplayerref.h index 86cc7de93e1..aeca41332d6 100644 --- a/src/core/qgsmaplayerref.h +++ b/src/core/qgsmaplayerref.h @@ -67,11 +67,31 @@ struct _LayerRef provider = l && l->dataProvider() ? l->dataProvider()->name() : QString(); } + /** + * Returns true if the layer reference is resolved and contains a reference to an existing + * map layer. + */ + operator bool() const + { + return static_cast< bool >( layer.data() ); + } + + /** + * Forwards the to map layer. + */ + TYPE *operator->() const + { + return layer.data(); + } + /** * Returns a pointer to the layer, or nullptr if the reference has not yet been matched * to a layer. */ - TYPE *get() const { return layer.data(); } + TYPE *operator &() const + { + return layer.data(); + } //! Weak pointer to map layer QPointer layer; diff --git a/src/core/qgsvectorlayerjoininfo.h b/src/core/qgsvectorlayerjoininfo.h index 7641552aac4..6d2e0673a4c 100644 --- a/src/core/qgsvectorlayerjoininfo.h +++ b/src/core/qgsvectorlayerjoininfo.h @@ -27,7 +27,7 @@ class CORE_EXPORT QgsVectorLayerJoinInfo //! Sets weak reference to the joined layer void setJoinLayer( QgsVectorLayer *layer ) { mJoinLayerRef = QgsVectorLayerRef( layer ); } //! Returns joined layer (may be null if the reference was set by layer ID and not resolved yet) - QgsVectorLayer *joinLayer() const { return mJoinLayerRef.get(); } + QgsVectorLayer *joinLayer() const { return &mJoinLayerRef; } //! Sets ID of the joined layer. It will need to be overwritten by setJoinLayer() to a reference to real layer void setJoinLayerId( const QString &layerId ) { mJoinLayerRef = QgsVectorLayerRef( layerId ); } diff --git a/tests/src/core/testqgsmaplayer.cpp b/tests/src/core/testqgsmaplayer.cpp index f6d18249420..d62b486ae57 100644 --- a/tests/src/core/testqgsmaplayer.cpp +++ b/tests/src/core/testqgsmaplayer.cpp @@ -160,19 +160,25 @@ void TestQgsMapLayer::layerRef() { // construct from layer QgsVectorLayerRef ref( mpLayer ); - QCOMPARE( ref.get(), mpLayer ); + QCOMPARE( &ref, mpLayer ); QCOMPARE( ref.layer.data(), mpLayer ); QCOMPARE( ref.layerId, mpLayer->id() ); QCOMPARE( ref.name, QStringLiteral( "points" ) ); QCOMPARE( ref.source, mpLayer->publicSource() ); QCOMPARE( ref.provider, QStringLiteral( "ogr" ) ); + // bool operator + QVERIFY( ref ); + // -> operator + QCOMPARE( ref->id(), mpLayer->id() ); + // verify that layer matches layer QVERIFY( ref.layerMatchesSource( mpLayer ) ); // create a weak reference QgsVectorLayerRef ref2( mpLayer->id(), QStringLiteral( "points" ), mpLayer->publicSource(), QStringLiteral( "ogr" ) ); - QVERIFY( !ref2.get() ); + QVERIFY( !ref2 ); + QVERIFY( !&ref2 ); QVERIFY( !ref2.layer.data() ); QCOMPARE( ref2.layerId, mpLayer->id() ); QCOMPARE( ref2.name, QStringLiteral( "points" ) ); @@ -184,7 +190,8 @@ void TestQgsMapLayer::layerRef() // resolve layer using project QCOMPARE( ref2.resolve( QgsProject::instance() ), mpLayer ); - QCOMPARE( ref2.get(), mpLayer ); + QVERIFY( ref2 ); + QCOMPARE( &ref2, mpLayer ); QCOMPARE( ref2.layer.data(), mpLayer ); QCOMPARE( ref2.layerId, mpLayer->id() ); QCOMPARE( ref2.name, QStringLiteral( "points" ) ); @@ -193,9 +200,9 @@ void TestQgsMapLayer::layerRef() // setLayer QgsVectorLayerRef ref3; - QVERIFY( !ref3.get() ); + QVERIFY( !&ref3 ); ref3.setLayer( mpLayer ); - QCOMPARE( ref3.get(), mpLayer ); + QCOMPARE( &ref3, mpLayer ); QCOMPARE( ref3.layer.data(), mpLayer ); QCOMPARE( ref3.layerId, mpLayer->id() ); QCOMPARE( ref3.name, QStringLiteral( "points" ) ); @@ -204,10 +211,10 @@ void TestQgsMapLayer::layerRef() // weak resolve QgsVectorLayerRef ref4( QStringLiteral( "badid" ), QStringLiteral( "points" ), mpLayer->publicSource(), QStringLiteral( "ogr" ) ); - QVERIFY( !ref4.get() ); + QVERIFY( !&ref4 ); QVERIFY( !ref4.resolve( QgsProject::instance() ) ); QCOMPARE( ref4.resolveWeakly( QgsProject::instance() ), mpLayer ); - QCOMPARE( ref4.get(), mpLayer ); + QCOMPARE( &ref4, mpLayer ); QCOMPARE( ref4.layer.data(), mpLayer ); QCOMPARE( ref4.layerId, mpLayer->id() ); QCOMPARE( ref4.name, QStringLiteral( "points" ) ); @@ -216,7 +223,7 @@ void TestQgsMapLayer::layerRef() // try resolving a bad reference QgsVectorLayerRef ref5( QStringLiteral( "badid" ), QStringLiteral( "points" ), mpLayer->publicSource(), QStringLiteral( "xxx" ) ); - QVERIFY( !ref5.get() ); + QVERIFY( !&ref5 ); QVERIFY( !ref5.resolve( QgsProject::instance() ) ); QVERIFY( !ref5.resolveWeakly( QgsProject::instance() ) ); }