Skip to content

Commit ab79b15

Browse files
committedJul 18, 2017
[layout] Add measurement unit handling to QgsLayout
Allows layouts to convert from various units to their own native units Also added a QgsLayoutContext to QgsLayout.
1 parent cd380f6 commit ab79b15

File tree

4 files changed

+238
-0
lines changed

4 files changed

+238
-0
lines changed
 

‎python/core/layout/qgslayout.sip

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,84 @@ class QgsLayout : QGraphicsScene
2626

2727
QgsLayout();
2828

29+
void setUnits( QgsUnitTypes::LayoutUnit units );
30+
%Docstring
31+
Sets the native measurement ``units`` for the layout. These also form the default unit
32+
for measurements for the layout.
33+
.. seealso:: units()
34+
.. seealso:: convertToLayoutUnits()
35+
%End
36+
37+
QgsUnitTypes::LayoutUnit units() const;
38+
%Docstring
39+
Returns the native units for the layout.
40+
.. seealso:: setUnits()
41+
.. seealso:: convertToLayoutUnits()
42+
:rtype: QgsUnitTypes.LayoutUnit
43+
%End
44+
45+
double convertToLayoutUnits( const QgsLayoutMeasurement &measurement ) const;
46+
%Docstring
47+
Converts a measurement into the layout's native units.
48+
:return: length of measurement in layout units
49+
.. seealso:: convertFromLayoutUnits()
50+
.. seealso:: units()
51+
:rtype: float
52+
%End
53+
54+
QSizeF convertToLayoutUnits( const QgsLayoutSize &size ) const;
55+
%Docstring
56+
Converts a size into the layout's native units.
57+
:return: size of measurement in layout units
58+
.. seealso:: convertFromLayoutUnits()
59+
.. seealso:: units()
60+
:rtype: QSizeF
61+
%End
62+
63+
QPointF convertToLayoutUnits( const QgsLayoutPoint &point ) const;
64+
%Docstring
65+
Converts a ``point`` into the layout's native units.
66+
:return: point in layout units
67+
.. seealso:: convertFromLayoutUnits()
68+
.. seealso:: units()
69+
:rtype: QPointF
70+
%End
71+
72+
QgsLayoutMeasurement convertFromLayoutUnits( const double length, const QgsUnitTypes::LayoutUnit unit ) const;
73+
%Docstring
74+
Converts a ``length`` measurement from the layout's native units to a specified target ``unit``.
75+
:return: length of measurement in specified units
76+
.. seealso:: convertToLayoutUnits()
77+
.. seealso:: units()
78+
:rtype: QgsLayoutMeasurement
79+
%End
80+
81+
QgsLayoutSize convertFromLayoutUnits( const QSizeF &size, const QgsUnitTypes::LayoutUnit unit ) const;
82+
%Docstring
83+
Converts a ``size`` from the layout's native units to a specified target ``unit``.
84+
:return: size of measurement in specified units
85+
.. seealso:: convertToLayoutUnits()
86+
.. seealso:: units()
87+
:rtype: QgsLayoutSize
88+
%End
89+
90+
QgsLayoutPoint convertFromLayoutUnits( const QPointF &point, const QgsUnitTypes::LayoutUnit unit ) const;
91+
%Docstring
92+
Converts a ``point`` from the layout's native units to a specified target ``unit``.
93+
:return: point in specified units
94+
.. seealso:: convertToLayoutUnits()
95+
.. seealso:: units()
96+
:rtype: QgsLayoutPoint
97+
%End
98+
99+
QgsLayoutContext &context();
100+
%Docstring
101+
Returns a reference to the layout's context, which stores information relating to the
102+
current context and rendering settings for the layout.
103+
:rtype: QgsLayoutContext
104+
%End
105+
106+
29107
};
30108

31109

‎src/core/layout/qgslayout.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,33 @@ QgsLayout::QgsLayout()
2121
{
2222

2323
}
24+
25+
double QgsLayout::convertToLayoutUnits( const QgsLayoutMeasurement &measurement ) const
26+
{
27+
return mContext.measurementConverter().convert( measurement, mUnits ).length();
28+
}
29+
30+
QSizeF QgsLayout::convertToLayoutUnits( const QgsLayoutSize &size ) const
31+
{
32+
return mContext.measurementConverter().convert( size, mUnits ).toQSizeF();
33+
}
34+
35+
QPointF QgsLayout::convertToLayoutUnits( const QgsLayoutPoint &point ) const
36+
{
37+
return mContext.measurementConverter().convert( point, mUnits ).toQPointF();
38+
}
39+
40+
QgsLayoutMeasurement QgsLayout::convertFromLayoutUnits( const double length, const QgsUnitTypes::LayoutUnit unit ) const
41+
{
42+
return mContext.measurementConverter().convert( QgsLayoutMeasurement( length, mUnits ), unit );
43+
}
44+
45+
QgsLayoutSize QgsLayout::convertFromLayoutUnits( const QSizeF &size, const QgsUnitTypes::LayoutUnit unit ) const
46+
{
47+
return mContext.measurementConverter().convert( QgsLayoutSize( size.width(), size.height(), mUnits ), unit );
48+
}
49+
50+
QgsLayoutPoint QgsLayout::convertFromLayoutUnits( const QPointF &point, const QgsUnitTypes::LayoutUnit unit ) const
51+
{
52+
return mContext.measurementConverter().convert( QgsLayoutPoint( point.x(), point.y(), mUnits ), unit );
53+
}

‎src/core/layout/qgslayout.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "qgis_core.h"
2020
#include <QGraphicsScene>
21+
#include "qgslayoutcontext.h"
2122

2223
/**
2324
* \ingroup core
@@ -39,6 +40,86 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene
3940

4041
QgsLayout();
4142

43+
/**
44+
* Sets the native measurement \a units for the layout. These also form the default unit
45+
* for measurements for the layout.
46+
* \see units()
47+
* \see convertToLayoutUnits()
48+
*/
49+
void setUnits( QgsUnitTypes::LayoutUnit units ) { mUnits = units; }
50+
51+
/**
52+
* Returns the native units for the layout.
53+
* \see setUnits()
54+
* \see convertToLayoutUnits()
55+
*/
56+
QgsUnitTypes::LayoutUnit units() const { return mUnits; }
57+
58+
/**
59+
* Converts a measurement into the layout's native units.
60+
* \returns length of measurement in layout units
61+
* \see convertFromLayoutUnits()
62+
* \see units()
63+
*/
64+
double convertToLayoutUnits( const QgsLayoutMeasurement &measurement ) const;
65+
66+
/**
67+
* Converts a size into the layout's native units.
68+
* \returns size of measurement in layout units
69+
* \see convertFromLayoutUnits()
70+
* \see units()
71+
*/
72+
QSizeF convertToLayoutUnits( const QgsLayoutSize &size ) const;
73+
74+
/**
75+
* Converts a \a point into the layout's native units.
76+
* \returns point in layout units
77+
* \see convertFromLayoutUnits()
78+
* \see units()
79+
*/
80+
QPointF convertToLayoutUnits( const QgsLayoutPoint &point ) const;
81+
82+
/**
83+
* Converts a \a length measurement from the layout's native units to a specified target \a unit.
84+
* \returns length of measurement in specified units
85+
* \see convertToLayoutUnits()
86+
* \see units()
87+
*/
88+
QgsLayoutMeasurement convertFromLayoutUnits( const double length, const QgsUnitTypes::LayoutUnit unit ) const;
89+
90+
/**
91+
* Converts a \a size from the layout's native units to a specified target \a unit.
92+
* \returns size of measurement in specified units
93+
* \see convertToLayoutUnits()
94+
* \see units()
95+
*/
96+
QgsLayoutSize convertFromLayoutUnits( const QSizeF &size, const QgsUnitTypes::LayoutUnit unit ) const;
97+
98+
/**
99+
* Converts a \a point from the layout's native units to a specified target \a unit.
100+
* \returns point in specified units
101+
* \see convertToLayoutUnits()
102+
* \see units()
103+
*/
104+
QgsLayoutPoint convertFromLayoutUnits( const QPointF &point, const QgsUnitTypes::LayoutUnit unit ) const;
105+
106+
/**
107+
* Returns a reference to the layout's context, which stores information relating to the
108+
* current context and rendering settings for the layout.
109+
*/
110+
QgsLayoutContext &context() { return mContext; }
111+
112+
/**
113+
* Returns a reference to the layout's context, which stores information relating to the
114+
* current context and rendering settings for the layout.
115+
*/
116+
SIP_SKIP const QgsLayoutContext &context() const { return mContext; }
117+
118+
private:
119+
120+
QgsUnitTypes::LayoutUnit mUnits = QgsUnitTypes::LayoutMillimeters;
121+
QgsLayoutContext mContext;
122+
42123
};
43124

44125
#endif //QGSLAYOUT_H

‎tests/src/core/testqgslayout.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class TestQgsLayout: public QObject
2828
void init();// will be called before each testfunction is executed.
2929
void cleanup();// will be called after every testfunction.
3030
void creation(); //test creation of QgsLayout
31+
void units();
3132

3233
private:
3334
QString mReport;
@@ -68,6 +69,54 @@ void TestQgsLayout::creation()
6869
delete layout;
6970
}
7071

72+
void TestQgsLayout::units()
73+
{
74+
QgsLayout layout;
75+
layout.setUnits( QgsUnitTypes::LayoutCentimeters );
76+
QCOMPARE( layout.units(), QgsUnitTypes::LayoutCentimeters );
77+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutMeasurement( 10.0, QgsUnitTypes::LayoutMillimeters ) ), 1.0 );
78+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutSize( 10.0, 20.0, QgsUnitTypes::LayoutMillimeters ) ), QSizeF( 1.0, 2.0 ) );
79+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutPoint( 10.0, 20.0, QgsUnitTypes::LayoutMillimeters ) ), QPointF( 1.0, 2.0 ) );
80+
QCOMPARE( layout.convertFromLayoutUnits( 1.0, QgsUnitTypes::LayoutMillimeters ), QgsLayoutMeasurement( 10.0, QgsUnitTypes::LayoutMillimeters ) );
81+
QCOMPARE( layout.convertFromLayoutUnits( QSizeF( 1.0, 2.0 ), QgsUnitTypes::LayoutMillimeters ), QgsLayoutSize( 10.0, 20.0, QgsUnitTypes::LayoutMillimeters ) );
82+
QCOMPARE( layout.convertFromLayoutUnits( QPointF( 1.0, 2.0 ), QgsUnitTypes::LayoutMillimeters ), QgsLayoutPoint( 10.0, 20.0, QgsUnitTypes::LayoutMillimeters ) );
83+
84+
//check with dpi conversion
85+
layout.setUnits( QgsUnitTypes::LayoutInches );
86+
layout.context().setDpi( 96.0 );
87+
QCOMPARE( layout.context().dpi(), 96.0 );
88+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutMeasurement( 96, QgsUnitTypes::LayoutPixels ) ), 1.0 );
89+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutSize( 96, 96, QgsUnitTypes::LayoutPixels ) ), QSizeF( 1.0, 1.0 ) );
90+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutPoint( 96, 96, QgsUnitTypes::LayoutPixels ) ), QPointF( 1.0, 1.0 ) );
91+
QgsLayoutMeasurement result = layout.convertFromLayoutUnits( 1.0, QgsUnitTypes::LayoutPixels );
92+
QCOMPARE( result.units(), QgsUnitTypes::LayoutPixels );
93+
QCOMPARE( result.length(), 96.0 );
94+
QgsLayoutSize sizeResult = layout.convertFromLayoutUnits( QSizeF( 1.0, 1.0 ), QgsUnitTypes::LayoutPixels );
95+
QCOMPARE( sizeResult.units(), QgsUnitTypes::LayoutPixels );
96+
QCOMPARE( sizeResult.width(), 96.0 );
97+
QCOMPARE( sizeResult.height(), 96.0 );
98+
QgsLayoutPoint pointResult = layout.convertFromLayoutUnits( QPointF( 1.0, 1.0 ), QgsUnitTypes::LayoutPixels );
99+
QCOMPARE( pointResult.units(), QgsUnitTypes::LayoutPixels );
100+
QCOMPARE( pointResult.x(), 96.0 );
101+
QCOMPARE( pointResult.y(), 96.0 );
102+
103+
layout.setUnits( QgsUnitTypes::LayoutPixels );
104+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutMeasurement( 1, QgsUnitTypes::LayoutInches ) ), 96.0 );
105+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutSize( 1, 2, QgsUnitTypes::LayoutInches ) ), QSizeF( 96.0, 192.0 ) );
106+
QCOMPARE( layout.convertToLayoutUnits( QgsLayoutPoint( 1, 2, QgsUnitTypes::LayoutInches ) ), QPointF( 96.0, 192.0 ) );
107+
result = layout.convertFromLayoutUnits( 96.0, QgsUnitTypes::LayoutInches );
108+
QCOMPARE( result.units(), QgsUnitTypes::LayoutInches );
109+
QCOMPARE( result.length(), 1.0 );
110+
sizeResult = layout.convertFromLayoutUnits( QSizeF( 96.0, 192.0 ), QgsUnitTypes::LayoutInches );
111+
QCOMPARE( sizeResult.units(), QgsUnitTypes::LayoutInches );
112+
QCOMPARE( sizeResult.width(), 1.0 );
113+
QCOMPARE( sizeResult.height(), 2.0 );
114+
pointResult = layout.convertFromLayoutUnits( QPointF( 96.0, 192.0 ), QgsUnitTypes::LayoutInches );
115+
QCOMPARE( pointResult.units(), QgsUnitTypes::LayoutInches );
116+
QCOMPARE( pointResult.x(), 1.0 );
117+
QCOMPARE( pointResult.y(), 2.0 );
118+
}
119+
71120

72121
QGSTEST_MAIN( TestQgsLayout )
73122
#include "testqgslayout.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.