Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsembeddedsymbolrenderer.cpp 3 : : --------------------- 4 : : begin : March 2021 5 : : copyright : (C) 2021 by Nyall Dawson 6 : : email : nyall dot dawson 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 "qgsembeddedsymbolrenderer.h" 17 : : #include "qgspainteffectregistry.h" 18 : : #include "qgssymbollayerutils.h" 19 : : #include "qgssinglesymbolrenderer.h" 20 : : 21 : 0 : QgsEmbeddedSymbolRenderer::QgsEmbeddedSymbolRenderer( QgsSymbol *defaultSymbol ) 22 : 0 : : QgsFeatureRenderer( QStringLiteral( "embeddedSymbol" ) ) 23 : 0 : , mDefaultSymbol( defaultSymbol ) 24 : 0 : { 25 : : Q_ASSERT( mDefaultSymbol ); 26 : 0 : } 27 : : 28 : 0 : QgsEmbeddedSymbolRenderer::~QgsEmbeddedSymbolRenderer() = default; 29 : : 30 : 0 : QgsSymbol *QgsEmbeddedSymbolRenderer::symbolForFeature( const QgsFeature &feature, QgsRenderContext & ) const 31 : : { 32 : 0 : if ( feature.embeddedSymbol() ) 33 : 0 : return const_cast< QgsSymbol * >( feature.embeddedSymbol() ); 34 : : else 35 : 0 : return mDefaultSymbol.get(); 36 : 0 : } 37 : : 38 : 0 : QgsSymbol *QgsEmbeddedSymbolRenderer::originalSymbolForFeature( const QgsFeature &feature, QgsRenderContext &context ) const 39 : : { 40 : 0 : Q_UNUSED( context ) 41 : 0 : if ( feature.embeddedSymbol() ) 42 : 0 : return const_cast< QgsSymbol * >( feature.embeddedSymbol() ); 43 : : else 44 : 0 : return mDefaultSymbol.get(); 45 : 0 : } 46 : : 47 : 0 : void QgsEmbeddedSymbolRenderer::startRender( QgsRenderContext &context, const QgsFields &fields ) 48 : : { 49 : 0 : QgsFeatureRenderer::startRender( context, fields ); 50 : : 51 : 0 : mDefaultSymbol->startRender( context, fields ); 52 : 0 : } 53 : : 54 : 0 : bool QgsEmbeddedSymbolRenderer::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker ) 55 : : { 56 : 0 : if ( const QgsSymbol *symbol = feature.embeddedSymbol() ) 57 : : { 58 : 0 : std::unique_ptr< QgsSymbol > clone( symbol->clone() ); 59 : : 60 : 0 : clone->startRender( context ); 61 : 0 : renderFeatureWithSymbol( feature, clone.get(), context, layer, selected, drawVertexMarker ); 62 : 0 : clone->stopRender( context ); 63 : 0 : } 64 : : else 65 : : { 66 : 0 : renderFeatureWithSymbol( feature, mDefaultSymbol.get(), context, layer, selected, drawVertexMarker ); 67 : : } 68 : 0 : return true; 69 : 0 : } 70 : : 71 : 0 : void QgsEmbeddedSymbolRenderer::stopRender( QgsRenderContext &context ) 72 : : { 73 : 0 : QgsFeatureRenderer::stopRender( context ); 74 : 0 : mDefaultSymbol->stopRender( context ); 75 : 0 : } 76 : : 77 : 0 : QSet<QString> QgsEmbeddedSymbolRenderer::usedAttributes( const QgsRenderContext &context ) const 78 : : { 79 : 0 : QSet<QString> attributes; 80 : 0 : if ( mDefaultSymbol ) 81 : 0 : attributes.unite( mDefaultSymbol->usedAttributes( context ) ); 82 : 0 : return attributes; 83 : 0 : } 84 : : 85 : 0 : bool QgsEmbeddedSymbolRenderer::usesEmbeddedSymbols() const 86 : : { 87 : 0 : return true; 88 : : } 89 : : 90 : 0 : QgsEmbeddedSymbolRenderer *QgsEmbeddedSymbolRenderer::clone() const 91 : : { 92 : 0 : QgsEmbeddedSymbolRenderer *r = new QgsEmbeddedSymbolRenderer( mDefaultSymbol->clone() ); 93 : 0 : r->setUsingSymbolLevels( usingSymbolLevels() ); 94 : 0 : copyRendererData( r ); 95 : 0 : return r; 96 : 0 : } 97 : : 98 : 0 : QgsFeatureRenderer::Capabilities QgsEmbeddedSymbolRenderer::capabilities() 99 : : { 100 : 0 : return SymbolLevels; 101 : : } 102 : : 103 : 0 : QgsFeatureRenderer *QgsEmbeddedSymbolRenderer::create( QDomElement &element, const QgsReadWriteContext &context ) 104 : : { 105 : 0 : QDomElement symbolsElem = element.firstChildElement( QStringLiteral( "symbols" ) ); 106 : 0 : if ( symbolsElem.isNull() ) 107 : 0 : return nullptr; 108 : : 109 : 0 : QgsSymbolMap symbolMap = QgsSymbolLayerUtils::loadSymbols( symbolsElem, context ); 110 : : 111 : 0 : if ( !symbolMap.contains( QStringLiteral( "0" ) ) ) 112 : 0 : return nullptr; 113 : : 114 : 0 : QgsEmbeddedSymbolRenderer *r = new QgsEmbeddedSymbolRenderer( symbolMap.take( QStringLiteral( "0" ) ) ); 115 : 0 : return r; 116 : 0 : } 117 : : 118 : 0 : QgsEmbeddedSymbolRenderer *QgsEmbeddedSymbolRenderer::convertFromRenderer( const QgsFeatureRenderer *renderer ) 119 : : { 120 : 0 : if ( renderer->type() == QLatin1String( "embeddedSymbol" ) ) 121 : : { 122 : 0 : return dynamic_cast<QgsEmbeddedSymbolRenderer *>( renderer->clone() ); 123 : : } 124 : 0 : else if ( renderer->type() == QLatin1String( "singleSymbol" ) ) 125 : : { 126 : 0 : std::unique_ptr< QgsEmbeddedSymbolRenderer > symbolRenderer = std::make_unique< QgsEmbeddedSymbolRenderer >( static_cast< const QgsSingleSymbolRenderer * >( renderer )->symbol()->clone() ); 127 : 0 : return symbolRenderer.release(); 128 : 0 : } 129 : : else 130 : : { 131 : 0 : return nullptr; 132 : : } 133 : 0 : } 134 : : 135 : 0 : QDomElement QgsEmbeddedSymbolRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context ) 136 : : { 137 : 0 : QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME ); 138 : 0 : rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "embeddedSymbol" ) ); 139 : 0 : rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) ); 140 : 0 : rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) ); 141 : : 142 : 0 : QgsSymbolMap symbols; 143 : 0 : symbols[QStringLiteral( "0" )] = mDefaultSymbol.get(); 144 : 0 : QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context ); 145 : 0 : rendererElem.appendChild( symbolsElem ); 146 : : 147 : 0 : if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) ) 148 : 0 : mPaintEffect->saveProperties( doc, rendererElem ); 149 : : 150 : 0 : if ( !mOrderBy.isEmpty() ) 151 : : { 152 : 0 : QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) ); 153 : 0 : mOrderBy.save( orderBy ); 154 : 0 : rendererElem.appendChild( orderBy ); 155 : 0 : } 156 : 0 : rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) ); 157 : : 158 : 0 : return rendererElem; 159 : 0 : } 160 : : 161 : 0 : QgsSymbolList QgsEmbeddedSymbolRenderer::symbols( QgsRenderContext &context ) const 162 : : { 163 : 0 : Q_UNUSED( context ) 164 : 0 : QgsSymbolList lst; 165 : 0 : lst.append( mDefaultSymbol.get() ); 166 : 0 : return lst; 167 : 0 : } 168 : : 169 : 0 : QgsSymbol *QgsEmbeddedSymbolRenderer::defaultSymbol() const 170 : : { 171 : 0 : return mDefaultSymbol.get(); 172 : : } 173 : : 174 : 0 : void QgsEmbeddedSymbolRenderer::setDefaultSymbol( QgsSymbol *symbol ) 175 : : { 176 : : Q_ASSERT( symbol ); 177 : 0 : mDefaultSymbol.reset( symbol ); 178 : 0 : }