31#include "moc_qgsannotationmanager.cpp"
50 if ( mAnnotations.contains( annotation ) )
53 mAnnotations << annotation;
55 mProject->setDirty(
true );
64 if ( !mAnnotations.contains( annotation ) )
68 mAnnotations.removeAll( annotation );
71 mProject->setDirty(
true );
77 for (
auto *a : std::as_const( mAnnotations ) )
90 QList<QgsAnnotation *> results;
91 for (
const auto *a : std::as_const( mAnnotations ) )
93 results << a->clone();
105 return readXmlPrivate( element, context, layer, transformContext );
114 auto createAnnotationFromElement = [
this, &context, layer, &transformContext](
const QDomElement & element )
116 std::unique_ptr< QgsAnnotation > annotation( createAnnotationFromXml( element, context ) );
122 std::unique_ptr< QgsAnnotationItem > annotationItem = convertToAnnotationItem( annotation.get(), layer, transformContext );
123 if ( annotationItem )
125 layer->
addItem( annotationItem.release() );
139 QDomElement annotationsElem = element.firstChildElement( QStringLiteral(
"Annotations" ) );
141 QDomElement annotationElement = annotationsElem.firstChildElement( QStringLiteral(
"Annotation" ) );
142 while ( ! annotationElement.isNull() )
144 createAnnotationFromElement( annotationElement );
145 annotationElement = annotationElement.nextSiblingElement( QStringLiteral(
"Annotation" ) );
149 if ( annotationElement.isNull() )
151 QDomNodeList oldItemList = element.elementsByTagName( QStringLiteral(
"TextAnnotationItem" ) );
152 for (
int i = 0; i < oldItemList.size(); ++i )
154 createAnnotationFromElement( oldItemList.at( i ).toElement() );
156 oldItemList = element.elementsByTagName( QStringLiteral(
"FormAnnotationItem" ) );
157 for (
int i = 0; i < oldItemList.size(); ++i )
159 createAnnotationFromElement( oldItemList.at( i ).toElement() );
161 oldItemList = element.elementsByTagName( QStringLiteral(
"HtmlAnnotationItem" ) );
162 for (
int i = 0; i < oldItemList.size(); ++i )
164 createAnnotationFromElement( oldItemList.at( i ).toElement() );
166 oldItemList = element.elementsByTagName( QStringLiteral(
"SVGAnnotationItem" ) );
167 for (
int i = 0; i < oldItemList.size(); ++i )
169 createAnnotationFromElement( oldItemList.at( i ).toElement() );
178 auto setCommonProperties = [layer, &transformContext](
const QgsAnnotation * source, QgsAnnotationItem * destination ) ->
bool
180 destination->setEnabled( source->isVisible() );
181 if ( source->hasFixedMapPosition() )
183 QgsPointXY mapPosition = source->mapPosition();
184 QgsCoordinateTransform transform( source->mapPositionCrs(), layer->
crs(), transformContext );
187 mapPosition = transform.transform( mapPosition );
189 catch ( QgsCsException & )
191 QgsDebugError( QStringLiteral(
"Error transforming annotation position" ) );
197 auto callout = std::make_unique< QgsBalloonCallout >();
198 if ( QgsFillSymbol *fill = source->fillSymbol() )
199 callout->setFillSymbol( fill->clone() );
201 if ( QgsMarkerSymbol *marker = source->markerSymbol() )
202 callout->setMarkerSymbol( marker->clone() );
203 callout->setMargins( source->contentsMargin() );
205 destination->setCallout( callout.release() );
208 if ( source->mapLayer() )
214 if (
const QgsSvgAnnotation *svg =
dynamic_cast< const QgsSvgAnnotation *
>( annotation ) )
216 QgsPointXY mapPosition = svg->mapPosition();
217 QgsCoordinateTransform transform( svg->mapPositionCrs(), layer->
crs(), transformContext );
220 transform.transform( mapPosition );
222 catch ( QgsCsException & )
224 QgsDebugError( QStringLiteral(
"Error transforming annotation position" ) );
229 if ( !setCommonProperties( annotation, item.get() ) )
232 const QgsMargins margins = svg->contentsMargin();
233 item->setFixedSize( QSizeF( svg->frameSizeMm().width() - margins.
left() - margins.
right(),
234 svg->frameSizeMm().height() - margins.
top() - margins.
bottom() ) );
237 if ( svg->hasFixedMapPosition() )
241 item->setOffsetFromCallout( QSizeF( svg->frameOffsetFromReferencePointMm().x() + margins.
left(),
242 svg->frameOffsetFromReferencePointMm().y() + margins.
top() ) );
248 item->setBounds( QgsRectangle( svg->relativePosition().x(), svg->relativePosition().y(),
249 svg->relativePosition().x(), svg->relativePosition().y() ) );
250 if ( QgsFillSymbol *fill = svg->fillSymbol() )
252 item->setBackgroundEnabled(
true );
253 item->setBackgroundSymbol( fill->clone() );
259 else if (
const QgsTextAnnotation *text =
dynamic_cast< const QgsTextAnnotation *
>( annotation ) )
261 QgsPointXY mapPosition = text->mapPosition();
262 QgsCoordinateTransform transform( text->mapPositionCrs(), layer->
crs(), transformContext );
265 transform.transform( mapPosition );
267 catch ( QgsCsException & )
269 QgsDebugError( QStringLiteral(
"Error transforming annotation position" ) );
273 if ( !setCommonProperties( annotation, item.get() ) )
276 QgsTextFormat format = item->format();
278 item->setFormat( format );
280 const QgsMargins margins = text->contentsMargin();
281 item->setFixedSize( QSizeF( text->frameSizeMm().width() - margins.
left() - margins.
right(),
282 text->frameSizeMm().height() - margins.
top() - margins.
bottom() ) );
285 if ( text->hasFixedMapPosition() )
289 item->setOffsetFromCallout( QSizeF( text->frameOffsetFromReferencePointMm().x() + margins.
left(),
290 text->frameOffsetFromReferencePointMm().y() + margins.
top() ) );
292 item->setBackgroundEnabled(
false );
293 item->setFrameEnabled(
false );
298 item->setBounds( QgsRectangle( text->relativePosition().x(), text->relativePosition().y(),
299 text->relativePosition().x(), text->relativePosition().y() ) );
300 if ( QgsFillSymbol *fill = text->fillSymbol() )
302 item->setBackgroundEnabled(
true );
303 item->setBackgroundSymbol( fill->clone() );
315 QDomElement annotationsElem = doc.createElement( QStringLiteral(
"Annotations" ) );
316 QListIterator<QgsAnnotation *> i( mAnnotations );
319 while ( i.hasPrevious() )
328 annotation->
writeXml( annotationsElem, doc, context );
330 return annotationsElem;
335 if ( mAnnotations.empty() )
344 if ( !a->accept( visitor ) )
356 QString type = element.tagName();
361 annotation->
readXml( element, context );
@ Millimeters
Millimeters.
@ FixedSize
Item is rendered at a fixed size, regardless of map scale. Item's location is georeferenced to a spat...
@ RelativeToMapFrame
Items size and placement is relative to the map's frame, and the item will always be rendered in the ...
Represents a map layer containing a set of georeferenced annotations, e.g.
void setLinkedVisibilityLayer(QgsMapLayer *layer)
Sets a linked layer, where the items in this annotation layer will only be visible when the linked la...
QString addItem(QgsAnnotationItem *item)
Adds an item to the layer.
QList< QgsAnnotation * > annotations() const
Returns a list of all annotations contained in the manager.
QList< QgsAnnotation * > cloneAnnotations() const
Returns a list containing clones of all annotations contained in the manager.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the state of the manager.
void annotationRemoved()
Emitted when an annotation was removed from the manager.
QgsAnnotationManager(QgsProject *project=nullptr)
Constructor for QgsAnnotationManager.
void annotationAboutToBeRemoved(QgsAnnotation *annotation)
Emitted when an annotation is about to be removed from the manager.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the manager's state from a DOM element, restoring all annotations present in the XML document.
bool readXmlAndUpgradeToAnnotationLayerItems(const QDomElement &element, const QgsReadWriteContext &context, QgsAnnotationLayer *layer, const QgsCoordinateTransformContext &transformContext)
Reads the manager's state from a DOM element, restoring annotations present in the XML document.
~QgsAnnotationManager() override
bool removeAnnotation(QgsAnnotation *annotation)
Removes an annotation from the manager.
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified style entity visitor, causing it to visit all style entities associated within ...
void clear()
Removes and deletes all annotations from the manager.
bool addAnnotation(QgsAnnotation *annotation)
Adds an annotation to the manager.
void annotationAdded(QgsAnnotation *annotation)
Emitted when a annotation has been added to the manager.
Abstract base class for annotation items which are drawn over a map.
QgsCoordinateReferenceSystem mapPositionCrs() const
Returns the CRS of the map position, or an invalid CRS if the annotation does not have a fixed map po...
void setMapPositionCrs(const QgsCoordinateReferenceSystem &crs)
Sets the CRS of the map position.
virtual void readXml(const QDomElement &itemElem, const QgsReadWriteContext &context)=0
Restores the annotation's state from a DOM element.
virtual void writeXml(QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context) const =0
Writes the annotation state to a DOM element.
static QgsAnnotationRegistry * annotationRegistry()
Returns the application's annotation registry, used for managing annotation types.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Contains information about the context in which a coordinate transform is executed.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
QgsCoordinateReferenceSystem crs
double top() const
Returns the top margin.
double right() const
Returns the right margin.
double bottom() const
Returns the bottom margin.
double left() const
Returns the left margin.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
QgsCoordinateReferenceSystem crs
A container for the context for various read/write operations on objects.
static QgsRectangle fromCenterAndSize(const QgsPointXY ¢er, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
An interface for classes which can visit style entity (e.g.
@ Annotations
Annotations collection.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
void setAllowHtmlFormatting(bool allow)
Sets whether text should be treated as a HTML document and HTML tags should be used for formatting th...
#define QgsDebugError(str)
Contains information relating to a node (i.e.