Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgslayertreelayer.cpp
3 : : --------------------------------------
4 : : Date : May 2014
5 : : Copyright : (C) 2014 by Martin Dobias
6 : : Email : wonder dot sk at gmail dot com
7 : : ***************************************************************************
8 : : * *
9 : : * This program is free software; you can redistribute it and/or modify *
10 : : * it under the terms of the GNU General Public License as published by *
11 : : * the Free Software Foundation; either version 2 of the License, or *
12 : : * (at your option) any later version. *
13 : : * *
14 : : ***************************************************************************/
15 : :
16 : : #include "qgslayertreelayer.h"
17 : :
18 : : #include "qgslayertreeutils.h"
19 : : #include "qgsmaplayer.h"
20 : : #include "qgsproject.h"
21 : : #include "qgssymbollayerutils.h"
22 : :
23 : :
24 : 3 : QgsLayerTreeLayer::QgsLayerTreeLayer( QgsMapLayer *layer )
25 : 1 : : QgsLayerTreeNode( NodeLayer, true )
26 : 1 : , mRef( layer )
27 : 1 : , mLayerName( layer->name() )
28 : 2 : {
29 : 1 : attachToLayer();
30 : 1 : }
31 : :
32 : 0 : QgsLayerTreeLayer::QgsLayerTreeLayer( const QString &layerId, const QString &name, const QString &source, const QString &provider )
33 : 0 : : QgsLayerTreeNode( NodeLayer, true )
34 : 0 : , mRef( layerId, name, source, provider )
35 : 0 : , mLayerName( name.isEmpty() ? QStringLiteral( "(?)" ) : name )
36 : 0 : {
37 : 0 : }
38 : :
39 : 0 : QgsLayerTreeLayer::QgsLayerTreeLayer( const QgsLayerTreeLayer &other )
40 : 0 : : QgsLayerTreeNode( other )
41 : 0 : , mRef( other.mRef )
42 : 0 : , mLayerName( other.mLayerName )
43 : 0 : , mPatchShape( other.mPatchShape )
44 : 0 : , mPatchSize( other.mPatchSize )
45 : 0 : , mSplitBehavior( other.mSplitBehavior )
46 : 0 : {
47 : 0 : attachToLayer();
48 : 0 : }
49 : :
50 : 0 : void QgsLayerTreeLayer::resolveReferences( const QgsProject *project, bool looseMatching )
51 : : {
52 : 0 : if ( mRef )
53 : 0 : return; // already assigned
54 : :
55 : 0 : if ( !looseMatching )
56 : : {
57 : 0 : mRef.resolve( project );
58 : 0 : }
59 : : else
60 : : {
61 : 0 : mRef.resolveWeakly( project );
62 : : }
63 : :
64 : 0 : if ( !mRef )
65 : 0 : return;
66 : :
67 : 0 : attachToLayer();
68 : 0 : emit layerLoaded();
69 : 0 : }
70 : :
71 : 1 : void QgsLayerTreeLayer::attachToLayer()
72 : : {
73 : 1 : if ( !mRef )
74 : 0 : return;
75 : :
76 : 1 : connect( mRef.layer, &QgsMapLayer::nameChanged, this, &QgsLayerTreeLayer::layerNameChanged );
77 : 1 : connect( mRef.layer, &QgsMapLayer::willBeDeleted, this, &QgsLayerTreeLayer::layerWillBeDeleted );
78 : 1 : }
79 : :
80 : :
81 : 0 : QString QgsLayerTreeLayer::name() const
82 : : {
83 : 0 : return ( mRef && mUseLayerName ) ? mRef->name() : mLayerName;
84 : : }
85 : :
86 : 0 : void QgsLayerTreeLayer::setName( const QString &n )
87 : : {
88 : 0 : if ( mRef && mUseLayerName )
89 : : {
90 : 0 : if ( mRef->name() == n )
91 : 0 : return;
92 : 0 : mRef->setName( n );
93 : : // no need to emit signal: we will be notified from layer's nameChanged() signal
94 : 0 : }
95 : : else
96 : : {
97 : 0 : if ( mLayerName == n )
98 : 0 : return;
99 : 0 : mLayerName = n;
100 : 0 : emit nameChanged( this, n );
101 : : }
102 : 0 : }
103 : :
104 : 0 : QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsReadWriteContext &context )
105 : : {
106 : 0 : if ( element.tagName() != QLatin1String( "layer-tree-layer" ) )
107 : 0 : return nullptr;
108 : :
109 : 0 : QString layerID = element.attribute( QStringLiteral( "id" ) );
110 : 0 : QString layerName = element.attribute( QStringLiteral( "name" ) );
111 : :
112 : 0 : QString providerKey = element.attribute( QStringLiteral( "providerKey" ) );
113 : 0 : QString source = context.pathResolver().readPath( element.attribute( QStringLiteral( "source" ) ) );
114 : :
115 : 0 : Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( QStringLiteral( "checked" ) ) );
116 : 0 : bool isExpanded = ( element.attribute( QStringLiteral( "expanded" ), QStringLiteral( "1" ) ) == QLatin1String( "1" ) );
117 : 0 : QString labelExpression = element.attribute( QStringLiteral( "legend_exp" ) );
118 : :
119 : : // needs to have the layer reference resolved later
120 : 0 : QgsLayerTreeLayer *nodeLayer = new QgsLayerTreeLayer( layerID, layerName, source, providerKey );
121 : :
122 : 0 : nodeLayer->readCommonXml( element );
123 : :
124 : 0 : nodeLayer->setItemVisibilityChecked( checked != Qt::Unchecked );
125 : 0 : nodeLayer->setExpanded( isExpanded );
126 : 0 : nodeLayer->setLabelExpression( labelExpression );
127 : :
128 : 0 : const QDomElement patchElem = element.firstChildElement( QStringLiteral( "patch" ) );
129 : 0 : if ( !patchElem.isNull() )
130 : : {
131 : 0 : QgsLegendPatchShape patch;
132 : 0 : patch.readXml( patchElem, context );
133 : 0 : nodeLayer->setPatchShape( patch );
134 : 0 : }
135 : :
136 : 0 : nodeLayer->setPatchSize( QgsSymbolLayerUtils::decodeSize( element.attribute( QStringLiteral( "patch_size" ) ) ) );
137 : :
138 : 0 : nodeLayer->setLegendSplitBehavior( static_cast< LegendNodesSplitBehavior >( element.attribute( QStringLiteral( "legend_split_behavior" ), QStringLiteral( "0" ) ).toInt() ) );
139 : :
140 : 0 : return nodeLayer;
141 : 0 : }
142 : :
143 : 0 : QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context )
144 : : {
145 : 0 : QgsLayerTreeLayer *node = readXml( element, context );
146 : 0 : if ( node )
147 : 0 : node->resolveReferences( project );
148 : 0 : return node;
149 : : }
150 : :
151 : 0 : void QgsLayerTreeLayer::writeXml( QDomElement &parentElement, const QgsReadWriteContext &context )
152 : : {
153 : 0 : QDomDocument doc = parentElement.ownerDocument();
154 : 0 : QDomElement elem = doc.createElement( QStringLiteral( "layer-tree-layer" ) );
155 : 0 : elem.setAttribute( QStringLiteral( "id" ), layerId() );
156 : 0 : elem.setAttribute( QStringLiteral( "name" ), name() );
157 : :
158 : 0 : if ( mRef )
159 : : {
160 : 0 : elem.setAttribute( QStringLiteral( "source" ), context.pathResolver().writePath( mRef->publicSource() ) );
161 : 0 : elem.setAttribute( QStringLiteral( "providerKey" ), mRef->dataProvider() ? mRef->dataProvider()->name() : QString() );
162 : 0 : }
163 : :
164 : 0 : elem.setAttribute( QStringLiteral( "checked" ), mChecked ? QStringLiteral( "Qt::Checked" ) : QStringLiteral( "Qt::Unchecked" ) );
165 : 0 : elem.setAttribute( QStringLiteral( "expanded" ), mExpanded ? "1" : "0" );
166 : 0 : elem.setAttribute( QStringLiteral( "legend_exp" ), mLabelExpression );
167 : :
168 : 0 : if ( !mPatchShape.isNull() )
169 : : {
170 : 0 : QDomElement patchElem = doc.createElement( QStringLiteral( "patch" ) );
171 : 0 : mPatchShape.writeXml( patchElem, doc, context );
172 : 0 : elem.appendChild( patchElem );
173 : 0 : }
174 : 0 : elem.setAttribute( QStringLiteral( "patch_size" ), QgsSymbolLayerUtils::encodeSize( mPatchSize ) );
175 : :
176 : 0 : elem.setAttribute( QStringLiteral( "legend_split_behavior" ), mSplitBehavior );
177 : :
178 : 0 : writeCommonXml( elem );
179 : :
180 : 0 : parentElement.appendChild( elem );
181 : 0 : }
182 : :
183 : 0 : QString QgsLayerTreeLayer::dump() const
184 : : {
185 : 0 : return QStringLiteral( "LAYER: %1 checked=%2 expanded=%3 id=%4\n" ).arg( name() ).arg( mChecked ).arg( mExpanded ).arg( layerId() );
186 : 0 : }
187 : :
188 : 0 : QgsLayerTreeLayer *QgsLayerTreeLayer::clone() const
189 : : {
190 : 0 : return new QgsLayerTreeLayer( *this );
191 : 0 : }
192 : :
193 : 1 : void QgsLayerTreeLayer::layerWillBeDeleted()
194 : : {
195 : : Q_ASSERT( mRef );
196 : :
197 : 1 : emit layerWillBeUnloaded();
198 : :
199 : 1 : mLayerName = mRef->name();
200 : : // in theory we do not even need to do this - the weak ref should clear itself
201 : 1 : mRef.layer.clear();
202 : : // layerId stays in the reference
203 : :
204 : 1 : }
205 : :
206 : 0 : void QgsLayerTreeLayer::setUseLayerName( const bool use )
207 : : {
208 : 0 : mUseLayerName = use;
209 : 0 : }
210 : :
211 : 0 : bool QgsLayerTreeLayer::useLayerName() const
212 : : {
213 : 0 : return mUseLayerName;
214 : : }
215 : :
216 : 0 : void QgsLayerTreeLayer::layerNameChanged()
217 : : {
218 : : Q_ASSERT( mRef );
219 : 0 : emit nameChanged( this, mRef->name() );
220 : 0 : }
221 : :
222 : 0 : void QgsLayerTreeLayer::setLabelExpression( const QString &expression )
223 : : {
224 : 0 : mLabelExpression = expression;
225 : 0 : }
226 : :
227 : 0 : QgsLegendPatchShape QgsLayerTreeLayer::patchShape() const
228 : : {
229 : 0 : return mPatchShape;
230 : : }
231 : :
232 : 0 : void QgsLayerTreeLayer::setPatchShape( const QgsLegendPatchShape &shape )
233 : : {
234 : 0 : mPatchShape = shape;
235 : 0 : }
236 : :
|