32#include "moc_qgssymbollayermodel.cpp"
34using namespace Qt::StringLiterals;
40 : mVectorLayer( vectorLayer )
47 : mVectorLayer( vectorLayer )
63 mSymbolType = symbolType;
71void QgsSymbolLayerModelNode::setSymbol(
QgsSymbol *symbol )
81 const QSize iconSize = QSize( size, size );
100 if ( role == Qt::DisplayRole || role == Qt::EditRole )
112 switch ( mSymbol->type() )
115 return QCoreApplication::translate(
"QgsSymbolLayerModelNode",
"Marker" );
117 return QCoreApplication::translate(
"QgsSymbolLayerModelNode",
"Fill" );
119 return QCoreApplication::translate(
"QgsSymbolLayerModelNode",
"Line" );
127 else if ( role == Qt::ForegroundRole && mIsLayer )
129 if ( !mLayer->enabled() )
131 QPalette
pal = qApp->palette();
132 QBrush brush = QBrush();
133 brush.setColor(
pal.color( QPalette::Disabled, QPalette::WindowText ) );
141 else if ( role == Qt::DecorationRole )
145 else if ( role == Qt::FontRole && !mIsLayer )
148 font.setBold(
true );
151 else if ( role == Qt::CheckStateRole )
155 return Qt::CheckState::PartiallyChecked;
158 if ( mLayer->enabled() )
160 return Qt::CheckState::Checked;
164 return Qt::CheckState::Unchecked;
180 Q_ASSERT( !node->mParent );
181 node->mParent =
this;
183 return mChildren.emplace_back( std::move( node ) ).get();
191 Q_ASSERT( !node->mParent );
192 node->mParent =
this;
194 return mChildren.insert( mChildren.begin() + index, std::move( node ) )->get();
203 Q_ASSERT( node->mParent ==
this );
206 if ( idx != -1 && idx != to )
208 std::unique_ptr<QgsSymbolLayerModelNode> n = std::move( mChildren.at( idx ) );
209 mChildren.erase( mChildren.begin() + idx );
210 mChildren.insert( mChildren.begin() + to, std::move( n ) );
222 mChildren.erase( mChildren.begin() + idx );
228 return mChildren.at( index ).get();
233 Q_ASSERT( node->mParent ==
this );
235 auto it = std::find_if( mChildren.begin(), mChildren.end(), [&](
const std::unique_ptr<QgsSymbolLayerModelNode> &p ) { return p.get() == node; } );
237 if ( it != mChildren.end() )
238 return std::distance( mChildren.begin(), it );
244 return mChildren.size();
252 return mParent->indexOf(
this );
256 : QAbstractItemModel(
parent )
264 if ( !
index.isValid() )
265 return Qt::ItemFlags();
267 Qt::ItemFlags f = Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable;
272 f |= Qt::ItemFlag::ItemIsUserCheckable;
276 f &= ~Qt::ItemFlag::ItemIsUserCheckable;
284 if ( !
index.isValid() )
291 return node->
data( role );
296 if ( !
index.isValid() )
303 if ( role == Qt::CheckStateRole )
309 bool checked = value.value<Qt::CheckState>() == Qt::Checked;
313 emit dataChanged(
index,
index, { Qt::CheckStateRole } );
317 return QAbstractItemModel::setData(
index, value, role );
336 if ( !hasIndex( row, column,
parent ) )
337 return QModelIndex();
341 return QModelIndex();
343 return createIndex( row, column, node->
childAt( row ) );
348 if ( !child.isValid() )
349 return QModelIndex();
353 return indexOfParentTreeNode( node->parent() );
358 return QModelIndex();
364 Q_ASSERT( parentNode );
367 if ( !grandParentNode )
368 return QModelIndex();
370 int row = grandParentNode->
indexOf( parentNode );
371 Q_ASSERT( row >= 0 );
373 return createIndex( row, 0, parentNode );
378 if ( !
index.isValid() )
379 return mRootNode.get();
386 if ( !node || !node->
parent() )
387 return QModelIndex();
392 Q_ASSERT( row >= 0 );
393 return index( row, 0, parentIndex );
396void QgsSymbolLayerModel::rebuild()
399 mRootNode->deleteChildren();
400 loadSymbol( mSymbol, mRootNode.get() );
407 beginRemoveRows( parentIndex, 0,
rowCount( parentIndex ) - 1 );
413 loadSymbol( symbol,
parent );
429 const int layerIdx =
parent->rowCount() - row - 1;
434 beginMoveRows( parentIndex, row, row, parentIndex, row + offset + ( offset > 0 ? 1 : 0 ) );
435 parent->moveChildNode( node, row + offset );
445 const int insertIdx = node->
rowIndex();
453 if ( insertIdx == -1 )
459 beginInsertRows( parentIndex, insertIdx, insertIdx );
461 auto newNode = std::make_unique<QgsSymbolLayerModelNode>( newLayer, parentSymbol->
type(), mVectorLayer, mScreen );
463 if ( insertIdx == -1 )
464 newNodePtr =
parent->addChildNode( std::move( newNode ) );
466 newNodePtr =
parent->insertChildNode( insertIdx, std::move( newNode ) );
470 loadSymbol( newLayer->
subSymbol(), newNodePtr );
480 if ( !
index.isValid() )
502 if ( insertIdx == -1 )
510 static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedSize( ddSize );
512 static_cast<QgsMarkerSymbol *
>( parentSymbol )->setDataDefinedAngle( ddAngle );
514 static_cast<QgsLineSymbol *
>( parentSymbol )->setDataDefinedWidth( ddWidth );
517 const int atRowIndex = ( insertIdx == -1 ) ? 0 : insertIdx;
518 beginInsertRows(
node2index( node ), atRowIndex, atRowIndex );
520 auto newNode = std::make_unique<QgsSymbolLayerModelNode>( newLayer, parentSymbol->
type(), mVectorLayer, mScreen );
536 const int layerIdx =
parent->rowCount() - row - 1;
540 parent->removeChildNode( node );
575 if ( !
index.isValid() )
578 emit dataChanged(
index,
index, QVector<int>() << Qt::DecorationRole );
601 QList<QgsSymbolLayerModelNode * > stack;
602 stack.append( mRootNode.get() );
604 while ( !stack.isEmpty() )
610 for (
int i = 0; i < node->
rowCount(); ++i )
612 stack.append( node->
childAt( i ) );
627 auto symbolNode = std::make_unique<QgsSymbolLayerModelNode>( symbol, mVectorLayer, mScreen );
629 for (
int i = count - 1; i >= 0; i-- )
631 auto layerNode = std::make_unique<QgsSymbolLayerModelNode>( symbol->
symbolLayer( i ), symbol->
type(), mVectorLayer, mScreen );
636 symbolNode->addChildNode( std::move( layerNode ) );
638 parent->addChildNode( std::move( symbolNode ) );
@ Millimeters
Millimeters.
static QgsSymbolLayerRegistry * symbolLayerRegistry()
Returns the application's symbol layer registry, used for managing symbol layers.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
A line symbol type, for rendering LineString and MultiLineString geometries.
QgsProperty dataDefinedWidth() const
Returns data defined width for whole symbol (including all symbol layers).
Struct for storing maximum and minimum scales for measurements in map units.
A marker symbol type, for rendering Point and MultiPoint geometries.
QgsProperty dataDefinedAngle() const
Returns data defined angle for whole symbol (including all symbol layers).
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
A store for object properties.
Stores properties relating to a screen.
A node contained within a QgsSymbolLayerModel.
QgsSymbolLayerModelNode * parent()
Returns the pointer of the parent node. If parent is nullptr, the node is a root node.
void setLayer(QgsSymbolLayer *layer, Qgis::SymbolType symbolType)
Sets the layer associated with the node, and the symbolType of the QgsSymbol it belongs to.
QgsSymbol * symbol()
Returns the symbol pointer; helpful in determining a layer's parent symbol.
QgsSymbolLayer * layer()
Returns the symbol layer pointer.
int rowCount() const
Returns the number of rows(children) belonging to the node.
QgsSymbolLayerModelNode * childAt(int index) const
Returns the child node at the given index.
void moveChildNode(QgsSymbolLayerModelNode *node, int to)
Move a child node of the current node, the ownership of the moved node is transferred to the current ...
int rowIndex() const
Returns the row index of the node within its parent.
~QgsSymbolLayerModelNode()
QgsSymbolLayerModelNode * insertChildNode(int index, std::unique_ptr< QgsSymbolLayerModelNode > node)
Inserts a child node to this node at index, transferring ownership of the node.
void removeChildNode(QgsSymbolLayerModelNode *node)
Remove a child node of the current node.
QIcon icon() const
Returns the item preview icon.
void setScreen(QScreen *screen)
Sets the screen associated with the node, which is used to render the preview icons.
bool isLayer() const
Returns true if the node is a symbol layer. And otherwise, it is a symbol.
void deleteChildren()
Deletes all child nodes from this node.
QgsSymbolLayerModelNode()
Constructor for QgsSymbolLayerModelNode for an empty node.
int indexOf(const QgsSymbolLayerModelNode *node)
Returns the index position of the given node within the current node's children.
QVariant data(int role) const
Returns the item's data for the given role.
QgsSymbolLayerModelNode * addChildNode(std::unique_ptr< QgsSymbolLayerModelNode > node)
Adds a child node to this node, transferring ownership of the node.
int columnCount(const QModelIndex &=QModelIndex()) const override
void updateNode(QgsSymbol *symbol, QgsSymbolLayerModelNode *parent)
Updates the descendants of the given parent node with the given symbol.
QModelIndex parent(const QModelIndex &child) const override
QVariant data(const QModelIndex &index, int role) const override
QgsSymbolLayerModelNode * addLayer(QModelIndex index)
Adds the symbol layer node inserted right before the idx.
bool setData(const QModelIndex &index, const QVariant &value, int role) override
void removeLayer(QgsSymbolLayerModelNode *node)
Removes the symbol layer node from it's parent node hierarchy.
void moveLayerByOffset(QgsSymbolLayerModelNode *node, int offset)
Moves the symbol layer node by the offset in the parent hierarchy.
QgsSymbolLayerModelNode * duplicateLayer(QgsSymbolLayerModelNode *node)
Duplicates the symbol layer node in the parent node hierarchy.
QModelIndex node2index(QgsSymbolLayerModelNode *node) const
Returns the model index corresponding to the given node.
QgsSymbolLayerModel(QgsVectorLayer *vl, QObject *parent=nullptr, QScreen *screen=nullptr)
Constructor for QgsSymbolLayerModel, with the specified parent object.
Qt::ItemFlags flags(const QModelIndex &index) const override
void setSymbol(QgsSymbol *symbol)
Sets the symbol associated with the model.
void setScreen(QScreen *screen)
Set the QScreen of the model itself.
void changeLayer(QgsSymbolLayerModelNode *node, QgsSymbolLayer *newLayer)
Change the symbol layer associated with node by a newLayer symbol layer.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QgsSymbolLayerModelNode * index2node(const QModelIndex &index) const
Returns the model node corresponding to the given index.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void updatePreviewIcons(QgsSymbolLayerModelNode *node)
Updates the preview icon of the given node.
static std::unique_ptr< QgsSymbolLayer > defaultSymbolLayer(Qgis::SymbolType type)
create a new instance of symbol layer for specified symbol type with default settings
QgsSymbolLayerAbstractMetadata * symbolLayerMetadata(const QString &name) const
Returns metadata for specified symbol layer. Returns nullptr if not found.
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, Qgis::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::SymbolType parentSymbolType=Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Draws a symbol layer preview to an icon.
static QPixmap symbolPreviewPixmap(const QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr, bool selected=false, const QgsExpressionContext *expressionContext=nullptr, const QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Returns a pixmap preview for a color ramp.
static void resetSymbolLayerIds(QgsSymbol *symbol)
Regenerate recursively unique id from all symbol symbol layers.
Abstract base class for symbol layers.
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setEnabled(bool enabled)
Sets whether symbol layer is enabled and should be drawn.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
Abstract base class for all rendered symbols.
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
bool appendSymbolLayer(QgsSymbolLayer *layer)
Appends a symbol layer at the end of the current symbol layer list.
bool insertSymbolLayer(int index, QgsSymbolLayer *layer)
Inserts a symbol layer to specified index.
bool changeSymbolLayer(int index, QgsSymbolLayer *layer)
Deletes the current layer at the specified index and replaces it with layer.
QgsSymbolLayer * takeSymbolLayer(int index)
Removes a symbol layer from the list and returns a pointer to it.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Qgis::SymbolType type() const
Returns the symbol's type.
Represents a vector layer which manages a vector based dataset.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
#define QgsDebugError(str)