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