Skip to content

Commit

Permalink
[layout] Add measurement unit handling to QgsLayout
Browse files Browse the repository at this point in the history
Allows layouts to convert from various units to their
own native units

Also added a QgsLayoutContext to QgsLayout.
  • Loading branch information
nyalldawson committed Jul 18, 2017
1 parent cd380f6 commit ab79b15
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 0 deletions.
78 changes: 78 additions & 0 deletions python/core/layout/qgslayout.sip
Expand Up @@ -26,6 +26,84 @@ class QgsLayout : QGraphicsScene

QgsLayout();

void setUnits( QgsUnitTypes::LayoutUnit units );
%Docstring
Sets the native measurement ``units`` for the layout. These also form the default unit
for measurements for the layout.
.. seealso:: units()
.. seealso:: convertToLayoutUnits()
%End

QgsUnitTypes::LayoutUnit units() const;
%Docstring
Returns the native units for the layout.
.. seealso:: setUnits()
.. seealso:: convertToLayoutUnits()
:rtype: QgsUnitTypes.LayoutUnit
%End

double convertToLayoutUnits( const QgsLayoutMeasurement &measurement ) const;
%Docstring
Converts a measurement into the layout's native units.
:return: length of measurement in layout units
.. seealso:: convertFromLayoutUnits()
.. seealso:: units()
:rtype: float
%End

QSizeF convertToLayoutUnits( const QgsLayoutSize &size ) const;
%Docstring
Converts a size into the layout's native units.
:return: size of measurement in layout units
.. seealso:: convertFromLayoutUnits()
.. seealso:: units()
:rtype: QSizeF
%End

QPointF convertToLayoutUnits( const QgsLayoutPoint &point ) const;
%Docstring
Converts a ``point`` into the layout's native units.
:return: point in layout units
.. seealso:: convertFromLayoutUnits()
.. seealso:: units()
:rtype: QPointF
%End

QgsLayoutMeasurement convertFromLayoutUnits( const double length, const QgsUnitTypes::LayoutUnit unit ) const;
%Docstring
Converts a ``length`` measurement from the layout's native units to a specified target ``unit``.
:return: length of measurement in specified units
.. seealso:: convertToLayoutUnits()
.. seealso:: units()
:rtype: QgsLayoutMeasurement
%End

QgsLayoutSize convertFromLayoutUnits( const QSizeF &size, const QgsUnitTypes::LayoutUnit unit ) const;
%Docstring
Converts a ``size`` from the layout's native units to a specified target ``unit``.
:return: size of measurement in specified units
.. seealso:: convertToLayoutUnits()
.. seealso:: units()
:rtype: QgsLayoutSize
%End

QgsLayoutPoint convertFromLayoutUnits( const QPointF &point, const QgsUnitTypes::LayoutUnit unit ) const;
%Docstring
Converts a ``point`` from the layout's native units to a specified target ``unit``.
:return: point in specified units
.. seealso:: convertToLayoutUnits()
.. seealso:: units()
:rtype: QgsLayoutPoint
%End

QgsLayoutContext &context();
%Docstring
Returns a reference to the layout's context, which stores information relating to the
current context and rendering settings for the layout.
:rtype: QgsLayoutContext
%End


};


Expand Down
30 changes: 30 additions & 0 deletions src/core/layout/qgslayout.cpp
Expand Up @@ -21,3 +21,33 @@ QgsLayout::QgsLayout()
{

}

double QgsLayout::convertToLayoutUnits( const QgsLayoutMeasurement &measurement ) const
{
return mContext.measurementConverter().convert( measurement, mUnits ).length();
}

QSizeF QgsLayout::convertToLayoutUnits( const QgsLayoutSize &size ) const
{
return mContext.measurementConverter().convert( size, mUnits ).toQSizeF();
}

QPointF QgsLayout::convertToLayoutUnits( const QgsLayoutPoint &point ) const
{
return mContext.measurementConverter().convert( point, mUnits ).toQPointF();
}

QgsLayoutMeasurement QgsLayout::convertFromLayoutUnits( const double length, const QgsUnitTypes::LayoutUnit unit ) const
{
return mContext.measurementConverter().convert( QgsLayoutMeasurement( length, mUnits ), unit );
}

QgsLayoutSize QgsLayout::convertFromLayoutUnits( const QSizeF &size, const QgsUnitTypes::LayoutUnit unit ) const
{
return mContext.measurementConverter().convert( QgsLayoutSize( size.width(), size.height(), mUnits ), unit );
}

QgsLayoutPoint QgsLayout::convertFromLayoutUnits( const QPointF &point, const QgsUnitTypes::LayoutUnit unit ) const
{
return mContext.measurementConverter().convert( QgsLayoutPoint( point.x(), point.y(), mUnits ), unit );
}
81 changes: 81 additions & 0 deletions src/core/layout/qgslayout.h
Expand Up @@ -18,6 +18,7 @@

#include "qgis_core.h"
#include <QGraphicsScene>
#include "qgslayoutcontext.h"

/**
* \ingroup core
Expand All @@ -39,6 +40,86 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene

QgsLayout();

/**
* Sets the native measurement \a units for the layout. These also form the default unit
* for measurements for the layout.
* \see units()
* \see convertToLayoutUnits()
*/
void setUnits( QgsUnitTypes::LayoutUnit units ) { mUnits = units; }

/**
* Returns the native units for the layout.
* \see setUnits()
* \see convertToLayoutUnits()
*/
QgsUnitTypes::LayoutUnit units() const { return mUnits; }

/**
* Converts a measurement into the layout's native units.
* \returns length of measurement in layout units
* \see convertFromLayoutUnits()
* \see units()
*/
double convertToLayoutUnits( const QgsLayoutMeasurement &measurement ) const;

/**
* Converts a size into the layout's native units.
* \returns size of measurement in layout units
* \see convertFromLayoutUnits()
* \see units()
*/
QSizeF convertToLayoutUnits( const QgsLayoutSize &size ) const;

/**
* Converts a \a point into the layout's native units.
* \returns point in layout units
* \see convertFromLayoutUnits()
* \see units()
*/
QPointF convertToLayoutUnits( const QgsLayoutPoint &point ) const;

/**
* Converts a \a length measurement from the layout's native units to a specified target \a unit.
* \returns length of measurement in specified units
* \see convertToLayoutUnits()
* \see units()
*/
QgsLayoutMeasurement convertFromLayoutUnits( const double length, const QgsUnitTypes::LayoutUnit unit ) const;

/**
* Converts a \a size from the layout's native units to a specified target \a unit.
* \returns size of measurement in specified units
* \see convertToLayoutUnits()
* \see units()
*/
QgsLayoutSize convertFromLayoutUnits( const QSizeF &size, const QgsUnitTypes::LayoutUnit unit ) const;

/**
* Converts a \a point from the layout's native units to a specified target \a unit.
* \returns point in specified units
* \see convertToLayoutUnits()
* \see units()
*/
QgsLayoutPoint convertFromLayoutUnits( const QPointF &point, const QgsUnitTypes::LayoutUnit unit ) const;

/**
* Returns a reference to the layout's context, which stores information relating to the
* current context and rendering settings for the layout.
*/
QgsLayoutContext &context() { return mContext; }

/**
* Returns a reference to the layout's context, which stores information relating to the
* current context and rendering settings for the layout.
*/
SIP_SKIP const QgsLayoutContext &context() const { return mContext; }

private:

QgsUnitTypes::LayoutUnit mUnits = QgsUnitTypes::LayoutMillimeters;
QgsLayoutContext mContext;

};

#endif //QGSLAYOUT_H
Expand Down
49 changes: 49 additions & 0 deletions tests/src/core/testqgslayout.cpp
Expand Up @@ -28,6 +28,7 @@ class TestQgsLayout: public QObject
void init();// will be called before each testfunction is executed.
void cleanup();// will be called after every testfunction.
void creation(); //test creation of QgsLayout
void units();

private:
QString mReport;
Expand Down Expand Up @@ -68,6 +69,54 @@ void TestQgsLayout::creation()
delete layout;
}

void TestQgsLayout::units()
{
QgsLayout layout;
layout.setUnits( QgsUnitTypes::LayoutCentimeters );
QCOMPARE( layout.units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutMeasurement( 10.0, QgsUnitTypes::LayoutMillimeters ) ), 1.0 );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutSize( 10.0, 20.0, QgsUnitTypes::LayoutMillimeters ) ), QSizeF( 1.0, 2.0 ) );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutPoint( 10.0, 20.0, QgsUnitTypes::LayoutMillimeters ) ), QPointF( 1.0, 2.0 ) );
QCOMPARE( layout.convertFromLayoutUnits( 1.0, QgsUnitTypes::LayoutMillimeters ), QgsLayoutMeasurement( 10.0, QgsUnitTypes::LayoutMillimeters ) );
QCOMPARE( layout.convertFromLayoutUnits( QSizeF( 1.0, 2.0 ), QgsUnitTypes::LayoutMillimeters ), QgsLayoutSize( 10.0, 20.0, QgsUnitTypes::LayoutMillimeters ) );
QCOMPARE( layout.convertFromLayoutUnits( QPointF( 1.0, 2.0 ), QgsUnitTypes::LayoutMillimeters ), QgsLayoutPoint( 10.0, 20.0, QgsUnitTypes::LayoutMillimeters ) );

//check with dpi conversion
layout.setUnits( QgsUnitTypes::LayoutInches );
layout.context().setDpi( 96.0 );
QCOMPARE( layout.context().dpi(), 96.0 );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutMeasurement( 96, QgsUnitTypes::LayoutPixels ) ), 1.0 );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutSize( 96, 96, QgsUnitTypes::LayoutPixels ) ), QSizeF( 1.0, 1.0 ) );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutPoint( 96, 96, QgsUnitTypes::LayoutPixels ) ), QPointF( 1.0, 1.0 ) );
QgsLayoutMeasurement result = layout.convertFromLayoutUnits( 1.0, QgsUnitTypes::LayoutPixels );
QCOMPARE( result.units(), QgsUnitTypes::LayoutPixels );
QCOMPARE( result.length(), 96.0 );
QgsLayoutSize sizeResult = layout.convertFromLayoutUnits( QSizeF( 1.0, 1.0 ), QgsUnitTypes::LayoutPixels );
QCOMPARE( sizeResult.units(), QgsUnitTypes::LayoutPixels );
QCOMPARE( sizeResult.width(), 96.0 );
QCOMPARE( sizeResult.height(), 96.0 );
QgsLayoutPoint pointResult = layout.convertFromLayoutUnits( QPointF( 1.0, 1.0 ), QgsUnitTypes::LayoutPixels );
QCOMPARE( pointResult.units(), QgsUnitTypes::LayoutPixels );
QCOMPARE( pointResult.x(), 96.0 );
QCOMPARE( pointResult.y(), 96.0 );

layout.setUnits( QgsUnitTypes::LayoutPixels );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutMeasurement( 1, QgsUnitTypes::LayoutInches ) ), 96.0 );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutSize( 1, 2, QgsUnitTypes::LayoutInches ) ), QSizeF( 96.0, 192.0 ) );
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutPoint( 1, 2, QgsUnitTypes::LayoutInches ) ), QPointF( 96.0, 192.0 ) );
result = layout.convertFromLayoutUnits( 96.0, QgsUnitTypes::LayoutInches );
QCOMPARE( result.units(), QgsUnitTypes::LayoutInches );
QCOMPARE( result.length(), 1.0 );
sizeResult = layout.convertFromLayoutUnits( QSizeF( 96.0, 192.0 ), QgsUnitTypes::LayoutInches );
QCOMPARE( sizeResult.units(), QgsUnitTypes::LayoutInches );
QCOMPARE( sizeResult.width(), 1.0 );
QCOMPARE( sizeResult.height(), 2.0 );
pointResult = layout.convertFromLayoutUnits( QPointF( 96.0, 192.0 ), QgsUnitTypes::LayoutInches );
QCOMPARE( pointResult.units(), QgsUnitTypes::LayoutInches );
QCOMPARE( pointResult.x(), 1.0 );
QCOMPARE( pointResult.y(), 2.0 );
}


QGSTEST_MAIN( TestQgsLayout )
#include "testqgslayout.moc"

0 comments on commit ab79b15

Please sign in to comment.