Skip to content

Commit

Permalink
Correct project and parent handling for report sections
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jan 5, 2018
1 parent 57628fa commit 6284f5e
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 18 deletions.
38 changes: 34 additions & 4 deletions python/core/layout/qgsabstractreportsection.sip
Expand Up @@ -20,9 +20,10 @@ class QgsAbstractReportSection : QgsAbstractLayoutIterator
%End
public:

QgsAbstractReportSection();
QgsAbstractReportSection( QgsAbstractReportSection *parent = 0 );
%Docstring
Constructor for QgsAbstractReportSection
Constructor for QgsAbstractReportSection, attached to the specified ``parent`` section.
Note that ownership is not transferred to ``parent``.
%End

~QgsAbstractReportSection();
Expand All @@ -36,6 +37,16 @@ transferred to the caller.

Subclasses should call copyCommonProperties() in their clone()
implementations.
%End

QgsAbstractReportSection *parent();
%Docstring
Returns the parent report section.
%End

QgsProject *project();
%Docstring
Returns the associated project.
%End

virtual int count();
Expand Down Expand Up @@ -230,6 +241,11 @@ Removes the child section at the specified ``index``, deleting it.
%Docstring
Copies the common properties of a report section to a ``destination`` section.
This method should be called from clone() implementations.
%End

void setParent( QgsAbstractReportSection *parent );
%Docstring
Sets the ``parent`` report section.
%End

private:
Expand All @@ -249,6 +265,12 @@ class QgsReportSectionLayout : QgsAbstractReportSection
%End
public:

QgsReportSectionLayout( QgsAbstractReportSection *parent = 0 );
%Docstring
Constructor for QgsReportSectionLayout, attached to the specified ``parent`` section.
Note that ownership is not transferred to ``parent``.
%End

QgsLayout *body();
%Docstring
Returns the body layout for the section.
Expand Down Expand Up @@ -290,9 +312,17 @@ subclasses.
%End
public:

QgsReport();
QgsReport( QgsProject *project );
%Docstring
Constructor for QgsReport, associated with the specified
``project``.

Note that ownership is not transferred to ``project``.
%End

QgsProject *project();
%Docstring
Constructor for QgsReport.
Returns the associated project.
%End

virtual QgsReport *clone() const /Factory/;
Expand Down
39 changes: 36 additions & 3 deletions src/core/layout/qgsabstractreportsection.cpp
Expand Up @@ -17,11 +17,31 @@
#include "qgsabstractreportsection.h"
#include "qgslayout.h"

QgsAbstractReportSection::QgsAbstractReportSection( QgsAbstractReportSection *parent )
: mParent( parent )
{}

QgsAbstractReportSection::~QgsAbstractReportSection()
{
qDeleteAll( mChildren );
}

QgsProject *QgsAbstractReportSection::project()
{
QgsAbstractReportSection *current = this;
while ( QgsAbstractReportSection *parent = current->parent() )
{
if ( !parent )
return nullptr;

if ( QgsReport *report = dynamic_cast< QgsReport * >( parent ) )
return report->project();

current = parent;
}
return nullptr;
}

QString QgsAbstractReportSection::filePath( const QString &baseFilePath, const QString &extension )
{
QString base = QStringLiteral( "%1_%2" ).arg( baseFilePath ).arg( mSectionNumber, 4, 10, QChar( '0' ) );
Expand Down Expand Up @@ -158,11 +178,13 @@ QgsAbstractReportSection *QgsAbstractReportSection::child( int index )

void QgsAbstractReportSection::appendChild( QgsAbstractReportSection *section )
{
section->setParent( this );
mChildren.append( section );
}

void QgsAbstractReportSection::insertChild( int index, QgsAbstractReportSection *section )
{
section->setParent( this );
index = std::max( 0, index );
index = std::min( index, mChildren.count() );
mChildren.insert( index, section );
Expand Down Expand Up @@ -202,16 +224,21 @@ void QgsAbstractReportSection::copyCommonProperties( QgsAbstractReportSection *d

for ( QgsAbstractReportSection *child : qgis::as_const( mChildren ) )
{
destination->mChildren.append( child->clone() );
destination->appendChild( child->clone() );
}
}


// QgsReport

QgsReport::QgsReport( QgsProject *project )
: QgsAbstractReportSection( nullptr )
, mProject( project )
{}

QgsReport *QgsReport::clone() const
{
std::unique_ptr< QgsReport > copy = qgis::make_unique< QgsReport >();
std::unique_ptr< QgsReport > copy = qgis::make_unique< QgsReport >( mProject );
copyCommonProperties( copy.get() );
return copy.release();
}
Expand All @@ -220,13 +247,19 @@ QgsReport *QgsReport::clone() const
// QgsReportSectionLayout
//

QgsReportSectionLayout::QgsReportSectionLayout( QgsAbstractReportSection *parent )
: QgsAbstractReportSection( parent )
{}

QgsReportSectionLayout *QgsReportSectionLayout::clone() const
{
std::unique_ptr< QgsReportSectionLayout > copy = qgis::make_unique< QgsReportSectionLayout >();
std::unique_ptr< QgsReportSectionLayout > copy = qgis::make_unique< QgsReportSectionLayout >( nullptr );
copyCommonProperties( copy.get() );

if ( mBody )
{
copy->mBody.reset( mBody->clone() );
}
else
copy->mBody.reset();

Expand Down
48 changes: 44 additions & 4 deletions src/core/layout/qgsabstractreportsection.h
Expand Up @@ -31,8 +31,11 @@ class CORE_EXPORT QgsAbstractReportSection : public QgsAbstractLayoutIterator

public:

//! Constructor for QgsAbstractReportSection
QgsAbstractReportSection() = default;
/**
* Constructor for QgsAbstractReportSection, attached to the specified \a parent section.
* Note that ownership is not transferred to \a parent.
*/
QgsAbstractReportSection( QgsAbstractReportSection *parent = nullptr );

~QgsAbstractReportSection() override;

Expand All @@ -51,6 +54,16 @@ class CORE_EXPORT QgsAbstractReportSection : public QgsAbstractLayoutIterator
*/
virtual QgsAbstractReportSection *clone() const = 0 SIP_FACTORY;

/**
* Returns the parent report section.
*/
QgsAbstractReportSection *parent() { return mParent; }

/**
* Returns the associated project.
*/
QgsProject *project();

// TODO - how to handle this?
int count() override { return -1; }

Expand Down Expand Up @@ -208,8 +221,15 @@ class CORE_EXPORT QgsAbstractReportSection : public QgsAbstractLayoutIterator
*/
void copyCommonProperties( QgsAbstractReportSection *destination ) const;

/**
* Sets the \a parent report section.
*/
void setParent( QgsAbstractReportSection *parent ) { mParent = parent; }

private:

QgsAbstractReportSection *mParent = nullptr;

int mSectionNumber = 0;
SubSection mNextSection = Header;
int mNextChild = 0;
Expand Down Expand Up @@ -237,6 +257,12 @@ class CORE_EXPORT QgsReportSectionLayout : public QgsAbstractReportSection
{
public:

/**
* Constructor for QgsReportSectionLayout, attached to the specified \a parent section.
* Note that ownership is not transferred to \a parent.
*/
QgsReportSectionLayout( QgsAbstractReportSection *parent = nullptr );

/**
* Returns the body layout for the section.
* \see setBody()
Expand Down Expand Up @@ -277,11 +303,25 @@ class CORE_EXPORT QgsReport : public QgsAbstractReportSection

public:

//! Constructor for QgsReport.
QgsReport() = default;
/**
* Constructor for QgsReport, associated with the specified
* \a project.
*
* Note that ownership is not transferred to \a project.
*/
QgsReport( QgsProject *project );

/**
* Returns the associated project.
*/
QgsProject *project() { return mProject; }

QgsReport *clone() const override SIP_FACTORY;

private:

QgsProject *mProject = nullptr;

};

#endif //QGSABSTRACTREPORTSECTION_H
2 changes: 1 addition & 1 deletion tests/src/python/test_qgslayoutexporter.py
Expand Up @@ -729,7 +729,7 @@ def testIteratorToPdf(self):

def testExportReport(self):
p = QgsProject()
r = QgsReport()
r = QgsReport(p)

# add a header
r.setHeaderEnabled(True)
Expand Down
22 changes: 16 additions & 6 deletions tests/src/python/test_qgsreport.py
Expand Up @@ -27,7 +27,9 @@ class TestQgsReport(unittest.TestCase):

def testGettersSetters(self):
p = QgsProject()
r = QgsReport()
r = QgsReport(p)

self.assertEqual(r.project(), p)

r.setHeaderEnabled(True)
self.assertTrue(r.headerEnabled())
Expand All @@ -45,7 +47,7 @@ def testGettersSetters(self):

def testChildren(self):
p = QgsProject()
r = QgsReport()
r = QgsReport(p)
self.assertEqual(r.childCount(), 0)
self.assertEqual(r.children(), [])
self.assertIsNone(r.child(-1))
Expand All @@ -60,32 +62,38 @@ def testChildren(self):

# append child
child1 = QgsReportSectionLayout()
self.assertIsNone(child1.project())
r.appendChild(child1)
self.assertEqual(r.childCount(), 1)
self.assertEqual(r.children(), [child1])
self.assertEqual(r.child(0), child1)
self.assertEqual(child1.parent(), r)
self.assertEqual(child1.project(), p)
child2 = QgsReportSectionLayout()
r.appendChild(child2)
self.assertEqual(r.childCount(), 2)
self.assertEqual(r.children(), [child1, child2])
self.assertEqual(r.child(1), child2)
self.assertEqual(child2.parent(), r)

def testInsertChild(self):
p = QgsProject()
r = QgsReport()
r = QgsReport(p)

child1 = QgsReportSectionLayout()
r.insertChild(11, child1)
self.assertEqual(r.childCount(), 1)
self.assertEqual(r.children(), [child1])
self.assertEqual(child1.parent(), r)
child2 = QgsReportSectionLayout()
r.insertChild(-1, child2)
self.assertEqual(r.childCount(), 2)
self.assertEqual(r.children(), [child2, child1])
self.assertEqual(child2.parent(), r)

def testRemoveChild(self):
p = QgsProject()
r = QgsReport()
r = QgsReport(p)

child1 = QgsReportSectionLayout()
r.appendChild(child1)
Expand All @@ -108,7 +116,7 @@ def testRemoveChild(self):

def testClone(self):
p = QgsProject()
r = QgsReport()
r = QgsReport(p)

child1 = QgsReportSectionLayout()
child1.setHeaderEnabled(True)
Expand All @@ -121,8 +129,10 @@ def testClone(self):
self.assertEqual(cloned.childCount(), 2)
self.assertTrue(cloned.child(0).headerEnabled())
self.assertFalse(cloned.child(0).footerEnabled())
self.assertEqual(cloned.child(0).parent(), cloned)
self.assertFalse(cloned.child(1).headerEnabled())
self.assertTrue(cloned.child(1).footerEnabled())
self.assertEqual(cloned.child(1).parent(), cloned)

def testReportSectionLayout(self):
r = QgsReportSectionLayout()
Expand All @@ -133,7 +143,7 @@ def testReportSectionLayout(self):

def testIteration(self):
p = QgsProject()
r = QgsReport()
r = QgsReport(p)

# empty report
self.assertTrue(r.beginRender())
Expand Down

0 comments on commit 6284f5e

Please sign in to comment.