1 /***************************************************************************
2   qgslayertreelayer.h
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 #ifndef QGSLAYERTREELAYER_H
17 #define QGSLAYERTREELAYER_H
18 
19 #include "qgis_core.h"
20 #include "qgis_sip.h"
21 #include "qgslayertreenode.h"
22 #include "qgsmaplayerref.h"
23 #include "qgsreadwritecontext.h"
24 #include "qgslegendpatchshape.h"
25 
26 class QgsMapLayer;
27 
28 /**
29  * \ingroup core
30  * \brief Layer tree node points to a map layer.
31  *
32  * The node can exist also without a valid instance of a layer (just ID). That
33  * means the referenced layer does not need to be loaded in order to use it
34  * in layer tree. In such case, resolveReferences() method can be called
35  * once the layer is loaded.
36  *
37  * A map layer is supposed to be present in one layer tree just once. It is
38  * however possible that temporarily a layer exists in one tree more than just
39  * once, e.g. while reordering items with drag and drop.
40  *
41  * \since QGIS 2.4
42  */
43 class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode
44 {
45     Q_OBJECT
46   public:
47     explicit QgsLayerTreeLayer( QgsMapLayer *layer );
48 
49 #ifndef SIP_RUN
50     QgsLayerTreeLayer( const QgsLayerTreeLayer &other );
51 #endif
52 
53     /**
54      * Constructor for QgsLayerTreeLayer using weak references to layer ID, \a name, public \a source, and \a provider key.
55      */
56     explicit QgsLayerTreeLayer( const QString &layerId, const QString &name = QString(), const QString &source = QString(), const QString &provider = QString() );
57 
58     /**
59      * Returns the ID for the map layer associated with this node.
60      *
61      * \see layer()
62      */
layerId()63     QString layerId() const { return mRef.layerId; }
64 
65     /**
66      * Returns the map layer associated with this node.
67      *
68      * \warning This can be (and often is!) NULLPTR, e.g. in the case of a layer node representing a layer
69      * which has not yet been fully loaded into a project, or a layer node representing a layer
70      * with an invalid data source. The returned pointer must ALWAYS be checked to avoid dereferencing NULLPTR.
71      *
72      * \see layerId()
73      */
layer()74     QgsMapLayer *layer() const { return mRef.get(); }
75 
76     /**
77      * Returns the layer's name.
78      *
79      * \see setName()
80      *
81      * \since QGIS 3.0
82      */
83     QString name() const override;
84 
85     /**
86      * Sets the layer's name.
87      *
88      * \see name()
89      *
90      * \since QGIS 3.0
91      */
92     void setName( const QString &n ) override;
93 
94     /**
95      * Uses the layer's name if \a use is TRUE, or the name manually set if
96      * FALSE.
97      * \since QGIS 3.8
98      */
99     void setUseLayerName( bool use = true );
100 
101     /**
102      * Returns whether the layer's name is used, or the name manually set.
103      * \since QGIS 3.8
104      */
105     bool useLayerName() const;
106 
107     /**
108      * Read layer node from XML. Returns new instance.
109      * Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
110      */
111     static QgsLayerTreeLayer *readXml( QDomElement &element, const QgsReadWriteContext &context ) SIP_FACTORY;
112 
113     /**
114      * Read layer node from XML. Returns new instance.
115      * Also resolves textual references to layers from the project (calls resolveReferences() internally).
116      * \since QGIS 3.0
117      */
118     static QgsLayerTreeLayer *readXml( QDomElement &element, const QgsProject *project, const QgsReadWriteContext &context ) SIP_FACTORY;
119 
120     void writeXml( QDomElement &parentElement, const QgsReadWriteContext &context ) override;
121 
122     QString dump() const override;
123 
124     QgsLayerTreeLayer *clone() const override SIP_FACTORY;
125 
126     /**
127      * Resolves reference to layer from stored layer ID (if it has not been resolved already)
128      * \since QGIS 3.0
129      */
130     void resolveReferences( const QgsProject *project, bool looseMatching = false ) override;
131 
132     /**
133      * set the expression to evaluate
134      *
135      * \since QGIS 3.10
136      */
137     void setLabelExpression( const QString &expression );
138 
139     /**
140      * Returns the expression member of the LayerTreeNode
141      *
142      * \since QGIS 3.10
143      */
labelExpression()144     QString labelExpression() const { return mLabelExpression; }
145 
146     /**
147      * Returns the symbol patch shape to use when rendering the legend node symbol.
148      *
149      * \see setPatchShape()
150      * \since QGIS 3.14
151      */
152     QgsLegendPatchShape patchShape() const;
153 
154     /**
155      * Sets the symbol patch \a shape to use when rendering the legend node symbol.
156      *
157      * \see patchShape()
158      * \since QGIS 3.14
159      */
160     void setPatchShape( const QgsLegendPatchShape &shape );
161 
162     /**
163      * Returns the user (overridden) size for the legend node.
164      *
165      * If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
166      * symbol width or height from QgsLegendSettings.
167      *
168      * \see setPatchSize()
169      * \since QGIS 3.14
170      */
patchSize()171     QSizeF patchSize() const { return mPatchSize; }
172 
173     /**
174      * Sets the user (overridden) \a size for the legend node.
175      *
176      * If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
177      * symbol width or height from QgsLegendSettings.
178      *
179      * \see patchSize()
180      * \since QGIS 3.14
181      */
setPatchSize(QSizeF size)182     void setPatchSize( QSizeF size ) { mPatchSize = size; }
183 
184     /**
185      * Legend node column split behavior.
186      *
187      * \since QGIS 3.14
188      */
189     enum LegendNodesSplitBehavior
190     {
191       UseDefaultLegendSetting, //!< Inherit default legend column splitting setting
192       AllowSplittingLegendNodesOverMultipleColumns, //!< Allow splitting node's legend nodes across multiple columns
193       PreventSplittingLegendNodesOverMultipleColumns, //!< Prevent splitting node's legend nodes across multiple columns
194     };
195 
196     /**
197      * Returns the column split behavior for the node.
198      *
199      * This value controls how legend nodes belonging the to layer may be split over multiple columns in legends.
200      *
201      * \see setLegendSplitBehavior()
202      * \since QGIS 3.14
203      */
legendSplitBehavior()204     LegendNodesSplitBehavior legendSplitBehavior() const { return mSplitBehavior; }
205 
206     /**
207      * Sets the column split \a behavior for the node.
208      *
209      * This value controls how legend nodes belonging the to layer may be split over multiple columns in legends.
210      *
211      * \see legendSplitBehavior()
212      * \since QGIS 3.14
213      */
setLegendSplitBehavior(LegendNodesSplitBehavior behavior)214     void setLegendSplitBehavior( LegendNodesSplitBehavior behavior ) { mSplitBehavior = behavior; }
215 
216   signals:
217 
218     /**
219      * Emitted when a previously unavailable layer got loaded.
220      */
221     void layerLoaded();
222 
223     /**
224      * Emitted when a previously available layer got unloaded (from layer registry).
225      * \since QGIS 2.6
226      */
227     void layerWillBeUnloaded();
228 
229   protected:
230     void attachToLayer();
231 
232     //! Weak reference to the layer (or just it's ID if the reference is not resolved yet)
233     QgsMapLayerRef mRef;
234     //! Layer name - only used if layer does not exist or if mUseLayerName is false
235     QString mLayerName;
236     //! Expression to evaluate in the legend
237     QString mLabelExpression;
238 
239     //!
240     bool mUseLayerName = true;
241 
242   private slots:
243 
244     /**
245      * Emits a nameChanged() signal if layer's name has changed
246      * \since QGIS 3.0
247      */
248     void layerNameChanged();
249 
250     /**
251      * Handles the event of deletion of the referenced layer
252      * \since QGIS 3.0
253      */
254     void layerWillBeDeleted();
255 
256   private:
257 
258 #ifdef SIP_RUN
259 
260     /**
261      * Copies are not allowed
262      */
263     QgsLayerTreeLayer( const QgsLayerTreeLayer &other );
264 #endif
265 
266     QgsLegendPatchShape mPatchShape;
267     QSizeF mPatchSize;
268     LegendNodesSplitBehavior mSplitBehavior = UseDefaultLegendSetting;
269 
270     QgsLayerTreeLayer &operator=( const QgsLayerTreeLayer & ) = delete;
271 };
272 
273 
274 
275 #endif // QGSLAYERTREELAYER_H
276