Skip to content

Commit

Permalink
make undo and redo of layer styling on annotation layers actually work
Browse files Browse the repository at this point in the history
the layer styling history on annotation layers has never been working because annotation layers did not have `writeStyle`/`readStyle` methods which are required to apply the changes from the undo stack (e.g. in `QgsMapLayerStyleCommand::undo()`).
  • Loading branch information
CodeBardian authored and nyalldawson committed Jan 10, 2023
1 parent 1523ba5 commit 5fdb7a3
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 38 deletions.
112 changes: 74 additions & 38 deletions src/core/annotations/qgsannotationlayer.cpp
Expand Up @@ -377,34 +377,8 @@ bool QgsAnnotationLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext
return false;
}

qDeleteAll( mItems );
mItems.clear();
mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
mNonIndexedItems.clear();

const QDomNodeList itemsElements = layerNode.toElement().elementsByTagName( QStringLiteral( "items" ) );
if ( itemsElements.size() == 0 )
return false;

const QDomNodeList items = itemsElements.at( 0 ).childNodes();
for ( int i = 0; i < items.size(); ++i )
{
const QDomElement itemElement = items.at( i ).toElement();
const QString id = itemElement.attribute( QStringLiteral( "id" ) );
const QString type = itemElement.attribute( QStringLiteral( "type" ) );
std::unique_ptr< QgsAnnotationItem > item( QgsApplication::annotationItemRegistry()->createItem( type ) );
if ( item )
{
item->readXml( itemElement, context );
if ( item->flags() & Qgis::AnnotationItemFlag::ScaleDependentBoundingBox )
mNonIndexedItems.insert( id );
else
mSpatialIndex->insert( id, item->boundingBox() );
mItems.insert( id, item.release() );
}
}

QString errorMsg;
readItems( layerNode, errorMsg, context );
readSymbology( layerNode, errorMsg, context );

triggerRepaint();
Expand All @@ -427,19 +401,10 @@ bool QgsAnnotationLayer::writeXml( QDomNode &layer_node, QDomDocument &doc, cons

mapLayerNode.setAttribute( QStringLiteral( "type" ), QgsMapLayerFactory::typeToString( QgsMapLayerType::AnnotationLayer ) );

QDomElement itemsElement = doc.createElement( QStringLiteral( "items" ) );
for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
{
QDomElement itemElement = doc.createElement( QStringLiteral( "item" ) );
itemElement.setAttribute( QStringLiteral( "type" ), ( *it )->type() );
itemElement.setAttribute( QStringLiteral( "id" ), it.key() );
( *it )->writeXml( itemElement, doc, context );
itemsElement.appendChild( itemElement );
}
mapLayerNode.appendChild( itemsElement );
QString errorMsg;
writeItems( layer_node, doc, errorMsg, context );

// renderer specific settings
QString errorMsg;
return writeSymbology( layer_node, doc, errorMsg, context );
}

Expand Down Expand Up @@ -518,6 +483,77 @@ bool QgsAnnotationLayer::readSymbology( const QDomNode &node, QString &, QgsRead
return true;
}

bool QgsAnnotationLayer::writeItems( QDomNode &node, QDomDocument &doc, QString &, const QgsReadWriteContext &context, QgsMapLayer::StyleCategories ) const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

QDomElement itemsElement = doc.createElement( QStringLiteral( "items" ) );

for ( auto it = mItems.constBegin(); it != mItems.constEnd(); ++it )
{
QDomElement itemElement = doc.createElement( QStringLiteral( "item" ) );
itemElement.setAttribute( QStringLiteral( "type" ), ( *it )->type() );
itemElement.setAttribute( QStringLiteral( "id" ), it.key() );
( *it )->writeXml( itemElement, doc, context );
itemsElement.appendChild( itemElement );
}
node.appendChild(itemsElement);

return true;
}

bool QgsAnnotationLayer::readItems( const QDomNode &node, QString &, QgsReadWriteContext &context, QgsMapLayer::StyleCategories )
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

qDeleteAll( mItems );
mItems.clear();
mSpatialIndex = std::make_unique< QgsAnnotationLayerSpatialIndex >();
mNonIndexedItems.clear();

const QDomNodeList itemsElements = node.toElement().elementsByTagName( QStringLiteral( "items" ) );
if ( itemsElements.size() == 0 )
return false;

const QDomNodeList items = itemsElements.at( 0 ).childNodes();
for ( int i = 0; i < items.size(); ++i )
{
const QDomElement itemElement = items.at( i ).toElement();
const QString id = itemElement.attribute( QStringLiteral( "id" ) );
const QString type = itemElement.attribute( QStringLiteral( "type" ) );
std::unique_ptr< QgsAnnotationItem > item( QgsApplication::annotationItemRegistry()->createItem( type ) );
if ( item )
{
item->readXml( itemElement, context );
if ( item->flags() & Qgis::AnnotationItemFlag::ScaleDependentBoundingBox )
mNonIndexedItems.insert( id );
else
mSpatialIndex->insert( id, item->boundingBox() );
mItems.insert( id, item.release() );
}
}

return true;
}

bool QgsAnnotationLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

writeItems( node, doc, errorMessage, context, categories );

return writeSymbology( node, doc, errorMessage, context, categories );
}

bool QgsAnnotationLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories )
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

readItems( node, errorMessage, context, categories );

return readSymbology( node, errorMessage, context, categories );
}

bool QgsAnnotationLayer::isEditable() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Expand Down
4 changes: 4 additions & 0 deletions src/core/annotations/qgsannotationlayer.h
Expand Up @@ -168,6 +168,8 @@ class CORE_EXPORT QgsAnnotationLayer : public QgsMapLayer
bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &, StyleCategories categories = AllStyleCategories ) const override;
bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) override;
bool writeStyle(QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, StyleCategories categories) const override;
bool readStyle(const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories) override;
bool isEditable() const override;
bool supportsEditing() const override;
QgsDataProvider *dataProvider() override;
Expand All @@ -194,6 +196,8 @@ class CORE_EXPORT QgsAnnotationLayer : public QgsMapLayer
private:

QStringList queryIndex( const QgsRectangle &bounds, QgsFeedback *feedback = nullptr ) const;
bool writeItems(QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories) const;
bool readItems(const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories );

QMap<QString, QgsAnnotationItem *> mItems;
QgsCoordinateTransformContext mTransformContext;
Expand Down

0 comments on commit 5fdb7a3

Please sign in to comment.