QGIS API Documentation 3.27.0-Master (75dc696944)
qgsannotationlayer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsannotationlayer.cpp
3 ------------------
4 copyright : (C) 2019 by Sandro Mani
5 email : smani at sourcepole dot ch
6 ***************************************************************************/
7
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#include "qgsannotationlayer.h"
19#include "qgsannotationitem.h"
21#include "qgsapplication.h"
22#include "qgslogger.h"
23#include "qgspainting.h"
24#include "qgsmaplayerfactory.h"
25#include "qgsfeedback.h"
27#include "qgspainteffect.h"
28#include "qgseffectstack.h"
30#include <QUuid>
31#include "RTree.h"
32
34class QgsAnnotationLayerSpatialIndex : public RTree<QString, float, 2, float>
35{
36 public:
37
38 void insert( const QString &uuid, const QgsRectangle &bounds )
39 {
40 std::array< float, 4 > scaledBounds = scaleBounds( bounds );
41 this->Insert(
42 {
43 scaledBounds[0], scaledBounds[ 1]
44 },
45 {
46 scaledBounds[2], scaledBounds[3]
47 },
48 uuid );
49 }
50
57 void remove( const QString &uuid, const QgsRectangle &bounds )
58 {
59 std::array< float, 4 > scaledBounds = scaleBounds( bounds );
60 this->Remove(
61 {
62 scaledBounds[0], scaledBounds[ 1]
63 },
64 {
65 scaledBounds[2], scaledBounds[3]
66 },
67 uuid );
68 }
69
75 bool intersects( const QgsRectangle &bounds, const std::function< bool( const QString &uuid )> &callback ) const
76 {
77 std::array< float, 4 > scaledBounds = scaleBounds( bounds );
78 this->Search(
79 {
80 scaledBounds[0], scaledBounds[ 1]
81 },
82 {
83 scaledBounds[2], scaledBounds[3]
84 },
85 callback );
86 return true;
87 }
88
89 private:
90 std::array<float, 4> scaleBounds( const QgsRectangle &bounds ) const
91 {
92 return
93 {
94 static_cast< float >( bounds.xMinimum() ),
95 static_cast< float >( bounds.yMinimum() ),
96 static_cast< float >( bounds.xMaximum() ),
97 static_cast< float >( bounds.yMaximum() )
98 };
99 }
100};
102
103QgsAnnotationLayer::QgsAnnotationLayer( const QString &name, const LayerOptions &options )
105 , mTransformContext( options.transformContext )
106 , mSpatialIndex( std::make_unique< QgsAnnotationLayerSpatialIndex >() )
107{
108 mShouldValidateCrs = false;
109 mValid = true;
110
111 QgsDataProvider::ProviderOptions providerOptions;
112 providerOptions.transformContext = options.transformContext;
113 mDataProvider = new QgsAnnotationLayerDataProvider( providerOptions, QgsDataProvider::ReadFlags() );
114
115 mPaintEffect.reset( QgsPaintEffectRegistry::defaultStack() );
116 mPaintEffect->setEnabled( false );
117}
118
120{
121 emit willBeDeleted();
122 qDeleteAll( mItems );
123 delete mDataProvider;
124}
125
127{
128 setOpacity( 1.0 );
131 clear();
132}
133
135{
136 const QString uuid = QUuid::createUuid().toString();
137 mItems.insert( uuid, item );
139 mNonIndexedItems.insert( uuid );
140 else
141 mSpatialIndex->insert( uuid, item->boundingBox() );
142
144
145 return uuid;
146}
147
149{
150 std::unique_ptr< QgsAnnotationItem> prevItem( mItems.take( id ) );
151
152 if ( prevItem )
153 {
154 auto it = mNonIndexedItems.find( id );
155 if ( it == mNonIndexedItems.end() )
156 {
157 mSpatialIndex->remove( id, prevItem->boundingBox() );
158 }
159 else
160 {
161 mNonIndexedItems.erase( it );
162 }
163 }
164
165 mItems.insert( id, item );
167 mNonIndexedItems.insert( id );
168 else
169 mSpatialIndex->insert( id, item->boundingBox() );
170
172}
173
174bool QgsAnnotationLayer::removeItem( const QString &id )
175{
176 if ( !mItems.contains( id ) )
177 return false;
178
179 std::unique_ptr< QgsAnnotationItem> item( mItems.take( id ) );
180
181 auto it = mNonIndexedItems.find( id );
182 if ( it == mNonIndexedItems.end() )
183 {
184 mSpatialIndex->remove( id, item->boundingBox() );
185 }
186 else
187 {
188 mNonIndexedItems.erase( it );
189 }
190
191 item.reset();
192
194
195 return true;
196}
197
199{
200 qDeleteAll( mItems );
201 mItems.clear();
202 mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
203 mNonIndexedItems.clear();
204
206}
207
209{
210 return mItems.empty();
211}
212
214{
215 return mItems.value( id );
216}
217
218
219QStringList QgsAnnotationLayer::queryIndex( const QgsRectangle &bounds, QgsFeedback *feedback ) const
220{
221 QStringList res;
222
223 mSpatialIndex->intersects( bounds, [&res, feedback]( const QString & uuid )->bool
224 {
225 res << uuid;
226 return !feedback || !feedback->isCanceled();
227 } );
228 return res;
229}
230
231QStringList QgsAnnotationLayer::itemsInBounds( const QgsRectangle &bounds, QgsRenderContext &context, QgsFeedback *feedback ) const
232{
233 QStringList res = queryIndex( bounds, feedback );
234 // we also have to search through any non-indexed items
235 for ( const QString &uuid : mNonIndexedItems )
236 {
237 if ( mItems.value( uuid )->boundingBox( context ).intersects( bounds ) )
238 res << uuid;
239 }
240
241 return res;
242}
243
245{
247 if ( QgsAnnotationItem *targetItem = item( operation->itemId() ) )
248 {
249 // remove item from index if present
250 auto it = mNonIndexedItems.find( operation->itemId() );
251 if ( it == mNonIndexedItems.end() )
252 {
253 mSpatialIndex->remove( operation->itemId(), targetItem->boundingBox() );
254 }
255 res = targetItem->applyEdit( operation );
256
257 switch ( res )
258 {
261 // re-add to index if possible
262 if ( !( targetItem->flags() & Qgis::AnnotationItemFlag::ScaleDependentBoundingBox ) )
263 mSpatialIndex->insert( operation->itemId(), targetItem->boundingBox() );
264 break;
265
267 // item needs removing from layer
268 delete mItems.take( operation->itemId() );
269 mNonIndexedItems.remove( operation->itemId() );
270 break;
271 }
272 }
273
276
277 return res;
278}
279
280Qgis::MapLayerProperties QgsAnnotationLayer::properties() const
281{
282 // annotation layers are always editable
284}
285
287{
288 const QgsAnnotationLayer::LayerOptions options( mTransformContext );
289 std::unique_ptr< QgsAnnotationLayer > layer = std::make_unique< QgsAnnotationLayer >( name(), options );
290 QgsMapLayer::clone( layer.get() );
291
292 for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
293 {
294 layer->mItems.insert( it.key(), ( *it )->clone() );
296 layer->mNonIndexedItems.insert( it.key() );
297 else
298 layer->mSpatialIndex->insert( it.key(), ( *it )->boundingBox() );
299 }
300
301 if ( mPaintEffect )
302 layer->setPaintEffect( mPaintEffect->clone() );
303
304 return layer.release();
305}
306
308{
309 return new QgsAnnotationLayerRenderer( this, rendererContext );
310}
311
313{
314 QgsRectangle rect;
315 for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
316 {
317 if ( rect.isNull() )
318 {
319 rect = it.value()->boundingBox();
320 }
321 else
322 {
323 rect.combineExtentWith( it.value()->boundingBox() );
324 }
325 }
326 return rect;
327}
328
330{
331 if ( mDataProvider )
332 mDataProvider->setTransformContext( context );
333
334 mTransformContext = context;
336}
337
338bool QgsAnnotationLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext &context )
339{
341 {
342 return false;
343 }
344
345 qDeleteAll( mItems );
346 mItems.clear();
347 mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
348 mNonIndexedItems.clear();
349
350 const QDomNodeList itemsElements = layerNode.toElement().elementsByTagName( QStringLiteral( "items" ) );
351 if ( itemsElements.size() == 0 )
352 return false;
353
354 const QDomNodeList items = itemsElements.at( 0 ).childNodes();
355 for ( int i = 0; i < items.size(); ++i )
356 {
357 const QDomElement itemElement = items.at( i ).toElement();
358 const QString id = itemElement.attribute( QStringLiteral( "id" ) );
359 const QString type = itemElement.attribute( QStringLiteral( "type" ) );
360 std::unique_ptr< QgsAnnotationItem > item( QgsApplication::annotationItemRegistry()->createItem( type ) );
361 if ( item )
362 {
363 item->readXml( itemElement, context );
365 mNonIndexedItems.insert( id );
366 else
367 mSpatialIndex->insert( id, item->boundingBox() );
368 mItems.insert( id, item.release() );
369 }
370 }
371
372 QString errorMsg;
373 readSymbology( layerNode, errorMsg, context );
374
376
377 return mValid;
378}
379
380bool QgsAnnotationLayer::writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const
381{
382 // first get the layer element so that we can append the type attribute
383 QDomElement mapLayerNode = layer_node.toElement();
384
385 if ( mapLayerNode.isNull() )
386 {
387 QgsDebugMsgLevel( QStringLiteral( "can't find maplayer node" ), 2 );
388 return false;
389 }
390
391 mapLayerNode.setAttribute( QStringLiteral( "type" ), QgsMapLayerFactory::typeToString( QgsMapLayerType::AnnotationLayer ) );
392
393 QDomElement itemsElement = doc.createElement( QStringLiteral( "items" ) );
394 for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
395 {
396 QDomElement itemElement = doc.createElement( QStringLiteral( "item" ) );
397 itemElement.setAttribute( QStringLiteral( "type" ), ( *it )->type() );
398 itemElement.setAttribute( QStringLiteral( "id" ), it.key() );
399 ( *it )->writeXml( itemElement, doc, context );
400 itemsElement.appendChild( itemElement );
401 }
402 mapLayerNode.appendChild( itemsElement );
403
404 // renderer specific settings
405 QString errorMsg;
406 return writeSymbology( layer_node, doc, errorMsg, context );
407}
408
409bool QgsAnnotationLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &, const QgsReadWriteContext &, QgsMapLayer::StyleCategories categories ) const
410{
411 // add the layer opacity
412 if ( categories.testFlag( Rendering ) )
413 {
414 QDomElement layerOpacityElem = doc.createElement( QStringLiteral( "layerOpacity" ) );
415 const QDomText layerOpacityText = doc.createTextNode( QString::number( opacity() ) );
416 layerOpacityElem.appendChild( layerOpacityText );
417 node.appendChild( layerOpacityElem );
418 }
419
420 if ( categories.testFlag( Symbology ) )
421 {
422 // add the blend mode field
423 QDomElement blendModeElem = doc.createElement( QStringLiteral( "blendMode" ) );
424 const QDomText blendModeText = doc.createTextNode( QString::number( QgsPainting::getBlendModeEnum( blendMode() ) ) );
425 blendModeElem.appendChild( blendModeText );
426 node.appendChild( blendModeElem );
427
428 QDomElement paintEffectElem = doc.createElement( QStringLiteral( "paintEffect" ) );
429 if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect.get() ) )
430 mPaintEffect->saveProperties( doc, paintEffectElem );
431 node.appendChild( paintEffectElem );
432 }
433
434 return true;
435}
436
437bool QgsAnnotationLayer::readSymbology( const QDomNode &node, QString &, QgsReadWriteContext &, QgsMapLayer::StyleCategories categories )
438{
439 if ( categories.testFlag( Rendering ) )
440 {
441 const QDomNode layerOpacityNode = node.namedItem( QStringLiteral( "layerOpacity" ) );
442 if ( !layerOpacityNode.isNull() )
443 {
444 const QDomElement e = layerOpacityNode.toElement();
445 setOpacity( e.text().toDouble() );
446 }
447 }
448
449 if ( categories.testFlag( Symbology ) )
450 {
451 // get and set the blend mode if it exists
452 const QDomNode blendModeNode = node.namedItem( QStringLiteral( "blendMode" ) );
453 if ( !blendModeNode.isNull() )
454 {
455 const QDomElement e = blendModeNode.toElement();
456 setBlendMode( QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( e.text().toInt() ) ) );
457 }
458
459 //restore layer effect
460 const QDomNode paintEffectNode = node.namedItem( QStringLiteral( "paintEffect" ) );
461 if ( !paintEffectNode.isNull() )
462 {
463 const QDomElement effectElem = paintEffectNode.firstChildElement( QStringLiteral( "effect" ) );
464 if ( !effectElem.isNull() )
465 {
466 setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
467 }
468 }
469 }
470
471 return true;
472}
473
475{
476 // annotation layers are always editable
477 return true;
478}
479
481{
482 return true;
483}
484
486{
487 return mDataProvider;
488}
489
491{
492 return mDataProvider;
493}
494
496{
497 QString metadata = QStringLiteral( "<html>\n<body>\n<h1>" ) + tr( "General" ) + QStringLiteral( "</h1>\n<hr>\n" ) + QStringLiteral( "<table class=\"list-view\">\n" );
498
499 metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Name" ) + QStringLiteral( "</td><td>" ) + name() + QStringLiteral( "</td></tr>\n" );
500
501 // Extent
502 metadata += QStringLiteral( "<tr><td class=\"highlight\">" ) + tr( "Extent" ) + QStringLiteral( "</td><td>" ) + extent().toString() + QStringLiteral( "</td></tr>\n" );
503
504 // item count
505 QLocale locale = QLocale();
506 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
507 const int itemCount = mItems.size();
508 metadata += QStringLiteral( "<tr><td class=\"highlight\">" )
509 + tr( "Item count" ) + QStringLiteral( "</td><td>" )
510 + locale.toString( static_cast<qlonglong>( itemCount ) )
511 + QStringLiteral( "</td></tr>\n" );
512 metadata += QLatin1String( "</table>\n<br><br>" );
513
514 // CRS
516
517 // items section
518 metadata += QStringLiteral( "<h1>" ) + tr( "Items" ) + QStringLiteral( "</h1>\n<hr>\n" );
519
520 metadata += QLatin1String( "<table width=\"100%\" class=\"tabular-view\">\n" );
521 metadata += QLatin1String( "<tr><th>" ) + tr( "Type" ) + QLatin1String( "</th><th>" ) + tr( "Count" ) + QLatin1String( "</th></tr>\n" );
522
523 QMap< QString, int > itemCounts;
524 for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
525 {
526 itemCounts[ it.value()->type() ]++;
527 }
528
529 const QMap<QString, QString> itemTypes = QgsApplication::annotationItemRegistry()->itemTypes();
530 int i = 0;
531 for ( auto it = itemTypes.begin(); it != itemTypes.end(); ++it )
532 {
533 QString rowClass;
534 if ( i % 2 )
535 rowClass = QStringLiteral( "class=\"odd-row\"" );
536 metadata += QLatin1String( "<tr " ) + rowClass + QLatin1String( "><td>" ) + it.value() + QLatin1String( "</td><td>" ) + locale.toString( static_cast<qlonglong>( itemCounts.value( it.key() ) ) ) + QLatin1String( "</td></tr>\n" );
537 i++;
538 }
539
540 metadata += QLatin1String( "</table>\n<br><br>" );
541
542 metadata += QLatin1String( "\n</body>\n</html>\n" );
543 return metadata;
544}
545
547{
548 return mPaintEffect.get();
549}
550
552{
553 mPaintEffect.reset( effect );
554}
555
556
557//
558// QgsAnnotationLayerDataProvider
559//
561QgsAnnotationLayerDataProvider::QgsAnnotationLayerDataProvider(
562 const ProviderOptions &options,
563 QgsDataProvider::ReadFlags flags )
564 : QgsDataProvider( QString(), options, flags )
565{}
566
568{
570}
571
572QString QgsAnnotationLayerDataProvider::name() const
573{
574 return QStringLiteral( "annotation" );
575}
576
577QString QgsAnnotationLayerDataProvider::description() const
578{
579 return QString();
580}
581
582QgsRectangle QgsAnnotationLayerDataProvider::extent() const
583{
584 return QgsRectangle();
585}
586
587bool QgsAnnotationLayerDataProvider::isValid() const
588{
589 return true;
590}
@ UsersCannotToggleEditing
Indicates that users are not allowed to toggle editing for this layer. Note that this does not imply ...
@ ScaleDependentBoundingBox
Item's bounding box will vary depending on map scale.
AnnotationItemEditOperationResult
Results from an edit operation on an annotation item.
Definition: qgis.h:1187
@ Invalid
Operation has invalid parameters for the item, no change occurred.
@ Success
Item was modified successfully.
@ ItemCleared
The operation results in the item being cleared, and the item should be removed from the layer as a r...
Abstract base class for annotation item edit operations.
QString itemId() const
Returns the associated item ID.
QMap< QString, QString > itemTypes() const
Returns a map of available item types to translated name.
Abstract base class for annotation items which are drawn with QgsAnnotationLayers.
virtual QgsRectangle boundingBox() const =0
Returns the bounding box of the item's geographic location, in the parent layer's coordinate referenc...
virtual bool readXml(const QDomElement &element, const QgsReadWriteContext &context)=0
Reads the item's state from the given DOM element.
virtual Qgis::AnnotationItemFlags flags() const
Returns item flags.
Represents a map layer containing a set of georeferenced annotations, e.g.
QgsRectangle extent() const override
Returns the extent of the layer.
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &, StyleCategories categories=AllStyleCategories) const override
Write the style for the layer into the document provided.
bool readSymbology(const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories) override
Read the symbology for the current layer from the DOM node supplied.
void clear()
Removes all items from the layer.
QgsDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsAnnotationItem * item(const QString &id)
Returns the item with the specified id, or nullptr if no matching item was found.
QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) override
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
bool isEditable() const override
Returns true if the layer can be edited.
bool removeItem(const QString &id)
Removes (and deletes) the item with matching id.
QStringList itemsInBounds(const QgsRectangle &bounds, QgsRenderContext &context, QgsFeedback *feedback=nullptr) const
Returns a list of the IDs of all annotation items within the specified bounds (in layer CRS),...
void setTransformContext(const QgsCoordinateTransformContext &context) override
Sets the coordinate transform context to transformContext.
Qgis::AnnotationItemEditOperationResult applyEdit(QgsAbstractAnnotationItemEditOperation *operation)
Applies an edit operation to the layer.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
void replaceItem(const QString &id, QgsAnnotationItem *item)
Replaces the existing item with matching id with a new item.
QgsAnnotationLayer * clone() const override
Returns a new instance equivalent to this one except for the id which is still unique.
friend class QgsAnnotationLayerRenderer
bool supportsEditing() const override
Returns whether the layer supports editing or not.
void reset()
Resets the annotation layer to a default state, and clears all items from it.
QString addItem(QgsAnnotationItem *item)
Adds an item to the layer.
QString htmlMetadata() const override
Obtain a formatted HTML string containing assorted metadata for this layer.
Qgis::MapLayerProperties properties() const override
Returns the map layer properties of this layer.
bool isEmpty() const
Returns true if the annotation layer is empty and contains no annotations.
bool writeXml(QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context) const override
Called by writeLayerXML(), used by children to write state specific to them to project files.
bool readXml(const QDomNode &layerNode, QgsReadWriteContext &context) override
Called by readLayerXML(), used by children to read state specific to them from project files.
QgsAnnotationLayer(const QString &name, const QgsAnnotationLayer::LayerOptions &options)
Constructor for a new QgsAnnotationLayer with the specified layer name.
QMap< QString, QgsAnnotationItem * > items() const
Returns a map of items contained in the layer, by unique item ID.
static QgsAnnotationItemRegistry * annotationItemRegistry()
Returns the application's annotation item registry, used for annotation item types.
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects.
This class represents a coordinate reference system (CRS).
Contains information about the context in which a coordinate transform is executed.
Abstract base class for spatial data provider implementations.
virtual void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
static QString typeToString(QgsMapLayerType type)
Converts a map layer type to a string value.
Base class for utility classes that encapsulate information necessary for rendering of map layers.
Base class for all map layer types.
Definition: qgsmaplayer.h:73
QString name
Definition: qgsmaplayer.h:76
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
QgsMapLayerType type
Definition: qgsmaplayer.h:80
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
QString crsHtmlMetadata() const
Returns a HTML fragment containing the layer's CRS metadata, for use in the htmlMetadata() method.
QgsLayerMetadata metadata
Definition: qgsmaplayer.h:78
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
void willBeDeleted()
Emitted in the destructor when the layer is about to be deleted, but it is still in a perfectly valid...
virtual QgsMapLayer * clone() const =0
Returns a new instance equivalent to this one except for the id which is still unique.
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
Definition: qgsmaplayer.h:640
QgsMapLayer::ReadFlags mReadFlags
Read flags. It's up to the subclass to respect these when restoring state from XML.
Definition: qgsmaplayer.h:1987
double opacity
Definition: qgsmaplayer.h:82
bool mValid
Indicates if the layer is valid and can be drawn.
Definition: qgsmaplayer.h:1938
@ Symbology
Symbology.
Definition: qgsmaplayer.h:161
@ Rendering
Rendering: scale visibility, simplify method, opacity.
Definition: qgsmaplayer.h:170
void invalidateWgs84Extent()
Invalidates the WGS84 extent.
bool mShouldValidateCrs
true if the layer's CRS should be validated and invalid CRSes are not permitted.
Definition: qgsmaplayer.h:1994
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
static QgsPaintEffect * defaultStack()
Returns a new effect stack consisting of a sensible selection of default effects.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
Base class for visual effects which can be applied to QPicture drawings.
static QgsPainting::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
Definition: qgspainting.cpp:80
static QPainter::CompositionMode getCompositionMode(QgsPainting::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
Definition: qgspainting.cpp:20
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer.
Definition: qgspainting.h:37
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:391
Contains information about the context of a rendering operation.
QgsMapLayerType
Types of layers that can be added to a map.
Definition: qgis.h:47
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
const QgsCoordinateReferenceSystem & crs
Setting options for loading annotation layers.
QgsCoordinateTransformContext transformContext
Coordinate transform context.
Setting options for creating vector data providers.
QgsCoordinateTransformContext transformContext
Coordinate transform context.