Skip to content

Commit

Permalink
Add methods to clone annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Apr 20, 2017
1 parent 490f5f0 commit dce3c88
Show file tree
Hide file tree
Showing 19 changed files with 130 additions and 1 deletion.
4 changes: 4 additions & 0 deletions python/core/annotations/qgsannotation.sip
Expand Up @@ -25,6 +25,8 @@ class QgsAnnotation : QObject

QgsAnnotation( QObject* parent /TransferThis/ = nullptr );

virtual QgsAnnotation *clone() const = 0 /Factory/;

bool isVisible() const;
void setVisible( bool visible );

Expand Down Expand Up @@ -81,4 +83,6 @@ class QgsAnnotation : QObject
void _writeXml( QDomElement& itemElem, QDomDocument& doc ) const;
void _readXml( const QDomElement& annotationElem, const QDomDocument& doc );

void copyCommonProperties( QgsAnnotation *target ) const;

};
10 changes: 10 additions & 0 deletions python/core/annotations/qgsannotationmanager.sip
Expand Up @@ -68,6 +68,16 @@ class QgsAnnotationManager : QObject
QList< QgsAnnotation * > annotations() const;
%Docstring
Returns a list of all annotations contained in the manager.
\see cloneAnnotations()
:rtype: list of QgsAnnotation
%End

QList< QgsAnnotation * > cloneAnnotations() const /Factory/;
%Docstring
Returns a list containing clones of all annotations contained
in the manager. The caller takes responsibility for deleting
all returned annotations.
\see annotations()
:rtype: list of QgsAnnotation
%End

Expand Down
2 changes: 2 additions & 0 deletions python/core/annotations/qgshtmlannotation.sip
Expand Up @@ -31,6 +31,8 @@ class QgsHtmlAnnotation: QgsAnnotation

~QgsHtmlAnnotation();

virtual QgsHtmlAnnotation *clone() const /Factory/;

virtual QSizeF minimumFrameSize() const;

void setSourceFile( const QString &htmlFile );
Expand Down
2 changes: 2 additions & 0 deletions python/core/annotations/qgssvgannotation.sip
Expand Up @@ -26,6 +26,8 @@ class QgsSvgAnnotation: QgsAnnotation
Constructor for QgsSvgAnnotation.
%End

virtual QgsSvgAnnotation *clone() const /Factory/;

virtual void writeXml( QDomElement &elem, QDomDocument &doc ) const;
virtual void readXml( const QDomElement &itemElem, const QDomDocument &doc );

Expand Down
2 changes: 2 additions & 0 deletions python/core/annotations/qgstextannotation.sip
Expand Up @@ -26,6 +26,8 @@ class QgsTextAnnotation: QgsAnnotation
Constructor for QgsTextAnnotation.
%End

virtual QgsTextAnnotation *clone() const /Factory/;

const QTextDocument *document() const;
%Docstring
Returns the text document which will be rendered
Expand Down
2 changes: 2 additions & 0 deletions python/gui/qgsformannotation.sip
Expand Up @@ -7,6 +7,8 @@ class QgsFormAnnotation : QgsAnnotation

QgsFormAnnotation( QObject* parent /TransferThis/ = nullptr );

virtual QgsFormAnnotation *clone() const /Factory/;

QSizeF minimumFrameSize() const;
QSizeF preferredFrameSize() const;

Expand Down
19 changes: 19 additions & 0 deletions src/core/annotations/qgsannotation.cpp
Expand Up @@ -431,3 +431,22 @@ void QgsAnnotation::_readXml( const QDomElement &annotationElem, const QDomDocum
emit mapLayerChanged();
}

void QgsAnnotation::copyCommonProperties( QgsAnnotation *target ) const
{
target->mVisible = mVisible;
target->mHasFixedMapPosition = mHasFixedMapPosition;
target->mMapPosition = mMapPosition;
target->mMapPositionCrs = mMapPositionCrs;
target->mRelativePosition = mRelativePosition;
target->mOffsetFromReferencePoint = mOffsetFromReferencePoint;
target->mFrameSize = mFrameSize;
target->mMarkerSymbol.reset( mMarkerSymbol ? mMarkerSymbol->clone() : nullptr );
target->mContentsMargins = mContentsMargins;
target->mFillSymbol.reset( mFillSymbol ? mFillSymbol->clone() : nullptr );
target->mBalloonSegment = mBalloonSegment;
target->mBalloonSegmentPoint1 = mBalloonSegmentPoint1;
target->mBalloonSegmentPoint2 = mBalloonSegmentPoint2;
target->mMapLayer = mMapLayer;
target->mFeature = mFeature;
}

14 changes: 14 additions & 0 deletions src/core/annotations/qgsannotation.h
Expand Up @@ -57,6 +57,12 @@ class CORE_EXPORT QgsAnnotation : public QObject
*/
QgsAnnotation( QObject *parent = nullptr );

/**
* Clones the annotation, returning a new copy of the annotation
* reflecting the annotation's current state.
*/
virtual QgsAnnotation *clone() const = 0;

/**
* Returns true if the annotation is visible and should be rendered.
* \see setVisible()
Expand Down Expand Up @@ -293,6 +299,14 @@ class CORE_EXPORT QgsAnnotation : public QObject
*/
void _readXml( const QDomElement &annotationElem, const QDomDocument &doc );

/**
* Copies common annotation properties to the \a targe
* annotation.
* Can be used within QgsAnnotation::clone() implementations
* to assist with creating copies.
*/
void copyCommonProperties( QgsAnnotation *target ) const;

private:

//! Check where to attach the balloon connection between frame and map point
Expand Down
10 changes: 10 additions & 0 deletions src/core/annotations/qgsannotationmanager.cpp
Expand Up @@ -73,6 +73,16 @@ QList<QgsAnnotation *> QgsAnnotationManager::annotations() const
return mAnnotations;
}

QList<QgsAnnotation *> QgsAnnotationManager::cloneAnnotations() const
{
QList<QgsAnnotation *> results;
Q_FOREACH ( const QgsAnnotation *a, mAnnotations )
{
results << a->clone();
}
return results;
}

bool QgsAnnotationManager::readXml( const QDomElement &element, const QDomDocument &doc )
{
clear();
Expand Down
9 changes: 9 additions & 0 deletions src/core/annotations/qgsannotationmanager.h
Expand Up @@ -79,9 +79,18 @@ class CORE_EXPORT QgsAnnotationManager : public QObject

/**
* Returns a list of all annotations contained in the manager.
* \see cloneAnnotations()
*/
QList< QgsAnnotation * > annotations() const;

/**
* Returns a list containing clones of all annotations contained
* in the manager. The caller takes responsibility for deleting
* all returned annotations.
* \see annotations()
*/
QList< QgsAnnotation * > cloneAnnotations() const SIP_FACTORY;

/**
* Reads the manager's state from a DOM element, restoring all annotations
* present in the XML document.
Expand Down
8 changes: 8 additions & 0 deletions src/core/annotations/qgshtmlannotation.cpp
Expand Up @@ -47,6 +47,14 @@ QgsHtmlAnnotation::QgsHtmlAnnotation( QObject *parent )
connect( mWebPage->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared, this, &QgsHtmlAnnotation::javascript );
}

QgsHtmlAnnotation *QgsHtmlAnnotation::clone() const
{
std::unique_ptr< QgsHtmlAnnotation > c( new QgsHtmlAnnotation() );
copyCommonProperties( c.get() );
c->setSourceFile( mHtmlFile );
return c.release();
}

void QgsHtmlAnnotation::setSourceFile( const QString &htmlFile )
{
QFile file( htmlFile );
Expand Down
2 changes: 2 additions & 0 deletions src/core/annotations/qgshtmlannotation.h
Expand Up @@ -44,6 +44,8 @@ class CORE_EXPORT QgsHtmlAnnotation: public QgsAnnotation

~QgsHtmlAnnotation() = default;

QgsHtmlAnnotation *clone() const override SIP_FACTORY;

QSizeF minimumFrameSize() const override;

/**
Expand Down
8 changes: 8 additions & 0 deletions src/core/annotations/qgssvgannotation.cpp
Expand Up @@ -27,6 +27,14 @@ QgsSvgAnnotation::QgsSvgAnnotation( QObject *parent )

}

QgsSvgAnnotation *QgsSvgAnnotation::clone() const
{
std::unique_ptr< QgsSvgAnnotation > c( new QgsSvgAnnotation() );
copyCommonProperties( c.get() );
c->setFilePath( mFilePath );
return c.release();
}

void QgsSvgAnnotation::writeXml( QDomElement &elem, QDomDocument &doc ) const
{
QDomElement svgAnnotationElem = doc.createElement( QStringLiteral( "SVGAnnotationItem" ) );
Expand Down
2 changes: 2 additions & 0 deletions src/core/annotations/qgssvgannotation.h
Expand Up @@ -39,6 +39,8 @@ class CORE_EXPORT QgsSvgAnnotation: public QgsAnnotation
*/
QgsSvgAnnotation( QObject *parent SIP_TRANSFERTHIS = nullptr );

QgsSvgAnnotation *clone() const override SIP_FACTORY;

virtual void writeXml( QDomElement &elem, QDomDocument &doc ) const override;
virtual void readXml( const QDomElement &itemElem, const QDomDocument &doc ) override;

Expand Down
8 changes: 8 additions & 0 deletions src/core/annotations/qgstextannotation.cpp
Expand Up @@ -26,6 +26,14 @@ QgsTextAnnotation::QgsTextAnnotation( QObject *parent )
mDocument->setUseDesignMetrics( true );
}

QgsTextAnnotation *QgsTextAnnotation::clone() const
{
std::unique_ptr< QgsTextAnnotation > c( new QgsTextAnnotation() );
copyCommonProperties( c.get() );
c->setDocument( mDocument ? mDocument->clone() : nullptr );
return c.release();
}

const QTextDocument *QgsTextAnnotation::document() const
{
return mDocument.get();
Expand Down
2 changes: 2 additions & 0 deletions src/core/annotations/qgstextannotation.h
Expand Up @@ -39,6 +39,8 @@ class CORE_EXPORT QgsTextAnnotation: public QgsAnnotation
*/
QgsTextAnnotation( QObject *parent SIP_TRANSFERTHIS = nullptr );

QgsTextAnnotation *clone() const override SIP_FACTORY;

/**
* Returns the text document which will be rendered
* within the annotation.
Expand Down
8 changes: 8 additions & 0 deletions src/gui/qgsformannotation.cpp
Expand Up @@ -40,6 +40,14 @@ QgsFormAnnotation::QgsFormAnnotation( QObject *parent )
: QgsAnnotation( parent )
{}

QgsFormAnnotation *QgsFormAnnotation::clone() const
{
std::unique_ptr< QgsFormAnnotation > c( new QgsFormAnnotation() );
copyCommonProperties( c.get() );
c->setDesignerForm( mDesignerForm );
return c.release();
}

void QgsFormAnnotation::setDesignerForm( const QString &uiFile )
{
mDesignerForm = uiFile;
Expand Down
4 changes: 3 additions & 1 deletion src/gui/qgsformannotation.h
Expand Up @@ -39,6 +39,8 @@ class GUI_EXPORT QgsFormAnnotation: public QgsAnnotation
*/
QgsFormAnnotation( QObject *parent = nullptr );

QgsFormAnnotation *clone() const override SIP_FACTORY;

QSizeF minimumFrameSize() const override;
//! Returns the optimal frame size
QSizeF preferredFrameSize() const;
Expand All @@ -63,7 +65,7 @@ class GUI_EXPORT QgsFormAnnotation: public QgsAnnotation
/**
* Returns a new QgsFormAnnotation object.
*/
static QgsFormAnnotation *create() { return new QgsFormAnnotation(); }
static QgsFormAnnotation *create() SIP_FACTORY { return new QgsFormAnnotation(); }

protected:

Expand Down
15 changes: 15 additions & 0 deletions tests/src/python/test_qgsannotation.py 100644 → 100755
Expand Up @@ -63,6 +63,11 @@ def testTextAnnotation(self):
im = self.renderAnnotation(a, QPointF(20, 30))
self.assertTrue(self.imageCheck('text_annotation', 'text_annotation', im))

# check clone
clone = a.clone()
im = self.renderAnnotation(a, QPointF(20, 30))
self.assertTrue(self.imageCheck('text_annotation', 'text_annotation', im))

def testSvgAnnotation(self):
""" test rendering a svg annotation"""
a = QgsSvgAnnotation()
Expand All @@ -73,6 +78,11 @@ def testSvgAnnotation(self):
im = self.renderAnnotation(a, QPointF(20, 30))
self.assertTrue(self.imageCheck('svg_annotation', 'svg_annotation', im))

# check clone
clone = a.clone()
im = self.renderAnnotation(a, QPointF(20, 30))
self.assertTrue(self.imageCheck('svg_annotation', 'svg_annotation', im))

def testHtmlAnnotation(self):
""" test rendering a html annotation"""
a = QgsHtmlAnnotation()
Expand All @@ -83,6 +93,11 @@ def testHtmlAnnotation(self):
im = self.renderAnnotation(a, QPointF(20, 30))
self.assertTrue(self.imageCheck('html_annotation', 'html_annotation', im))

# check clone
clone = a.clone()
im = self.renderAnnotation(a, QPointF(20, 30))
self.assertTrue(self.imageCheck('html_annotation', 'html_annotation', im))

def testHtmlAnnotationWithFeature(self):
""" test rendering a html annotation with a feature"""
layer = QgsVectorLayer("Point?crs=EPSG:3111&field=station:string&field=suburb:string",
Expand Down

0 comments on commit dce3c88

Please sign in to comment.