1 /*
2 * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3 *
4 * This file is part of the KD Chart library.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "KChartMeasure.h"
21
22 #include <KChartAbstractArea.h>
23 #include <KChartCartesianCoordinatePlane.h>
24 #include <KChartTextAttributes.h>
25 #include <KChartFrameAttributes.h>
26 #include <KChartBackgroundAttributes.h>
27 #include "KChartMath_p.h"
28
29 #include <QWidget>
30
31 namespace KChart {
32
33
Measure()34 Measure::Measure()
35 : mValue( 0.0 ),
36 mMode( KChartEnums::MeasureCalculationModeAuto ),
37 mArea( nullptr ),
38 mOrientation( KChartEnums::MeasureOrientationAuto )
39 {
40 // this bloc left empty intentionally
41 }
42
Measure(qreal value,KChartEnums::MeasureCalculationMode mode,KChartEnums::MeasureOrientation orientation)43 Measure::Measure( qreal value,
44 KChartEnums::MeasureCalculationMode mode,
45 KChartEnums::MeasureOrientation orientation )
46 : mValue( value ),
47 mMode( mode ),
48 mArea( nullptr ),
49 mOrientation( orientation )
50 {
51 // this bloc left empty intentionally
52 }
53
Measure(const Measure & r)54 Measure::Measure( const Measure& r )
55 : mValue( r.value() ),
56 mMode( r.calculationMode() ),
57 mArea( r.referenceArea() ),
58 mOrientation( r.referenceOrientation() )
59 {
60 // this bloc left empty intentionally
61 }
62
operator =(const Measure & r)63 Measure & Measure::operator=( const Measure& r )
64 {
65 if ( this != &r ) {
66 mValue = r.value();
67 mMode = r.calculationMode();
68 mArea = r.referenceArea();
69 mOrientation = r.referenceOrientation();
70 }
71
72 return *this;
73 }
74
75
calculatedValue(const QSizeF & autoSize,KChartEnums::MeasureOrientation autoOrientation) const76 qreal Measure::calculatedValue( const QSizeF& autoSize,
77 KChartEnums::MeasureOrientation autoOrientation) const
78 {
79 if ( mMode == KChartEnums::MeasureCalculationModeAbsolute ) {
80 return mValue;
81 } else {
82 qreal value = 0.0;
83 const QObject theAutoArea;
84 const QObject* autoArea = &theAutoArea;
85 const QObject* area = mArea ? mArea : autoArea;
86 KChartEnums::MeasureOrientation orientation = mOrientation;
87 switch ( mMode ) {
88 case KChartEnums::MeasureCalculationModeAuto:
89 area = autoArea;
90 orientation = autoOrientation;
91 break;
92 case KChartEnums::MeasureCalculationModeAutoArea:
93 area = autoArea;
94 break;
95 case KChartEnums::MeasureCalculationModeAutoOrientation:
96 orientation = autoOrientation;
97 break;
98 case KChartEnums::MeasureCalculationModeAbsolute: // fall through intended
99 case KChartEnums::MeasureCalculationModeRelative:
100 break;
101 }
102 if ( area ) {
103 QSizeF size;
104 if ( area == autoArea )
105 size = autoSize;
106 else
107 size = sizeOfArea( area );
108 //qDebug() << ( area == autoArea ) << "size" << size;
109 qreal referenceValue = 0;
110 switch ( orientation ) {
111 case KChartEnums::MeasureOrientationAuto: // fall through intended
112 case KChartEnums::MeasureOrientationMinimum:
113 referenceValue = qMin( size.width(), size.height() );
114 break;
115 case KChartEnums::MeasureOrientationMaximum:
116 referenceValue = qMax( size.width(), size.height() );
117 break;
118 case KChartEnums::MeasureOrientationHorizontal:
119 referenceValue = size.width();
120 break;
121 case KChartEnums::MeasureOrientationVertical:
122 referenceValue = size.height();
123 break;
124 }
125 value = mValue / 1000.0 * referenceValue;
126 }
127 return value;
128 }
129 }
130
131
calculatedValue(const QObject * autoArea,KChartEnums::MeasureOrientation autoOrientation) const132 qreal Measure::calculatedValue( const QObject* autoArea,
133 KChartEnums::MeasureOrientation autoOrientation) const
134 {
135 return calculatedValue( sizeOfArea( autoArea ), autoOrientation);
136 }
137
138
sizeOfArea(const QObject * area) const139 const QSizeF Measure::sizeOfArea( const QObject* area ) const
140 {
141 QSizeF size;
142 const CartesianCoordinatePlane* plane = dynamic_cast<const CartesianCoordinatePlane*>( area );
143 if ( false ) {
144 size = plane->visibleDiagramArea().size();
145 } else {
146 const AbstractArea* kdcArea = dynamic_cast<const AbstractArea*>(area);
147 if ( kdcArea ) {
148 size = kdcArea->geometry().size();
149 //qDebug() << "Measure::sizeOfArea() found kdcArea with size" << size;
150 } else {
151 const QWidget* widget = dynamic_cast<const QWidget*>(area);
152 if ( widget ) {
153 /* ATTENTION: Using the layout does not work: The Legend will never get the right size then!
154 const QLayout * layout = widget->layout();
155 if ( layout ) {
156 size = layout->geometry().size();
157 //qDebug() << "Measure::sizeOfArea() found widget with layout size" << size;
158 } else*/
159 {
160 size = widget->geometry().size();
161 //qDebug() << "Measure::sizeOfArea() found widget with size" << size;
162 }
163 } else if ( mMode != KChartEnums::MeasureCalculationModeAbsolute ) {
164 size = QSizeF(1.0, 1.0);
165 //qDebug("Measure::sizeOfArea() got no valid area.");
166 }
167 }
168 }
169 const QPair< qreal, qreal > factors
170 = GlobalMeasureScaling::instance()->currentFactors();
171 return QSizeF(size.width() * factors.first, size.height() * factors.second);
172 }
173
174
operator ==(const Measure & r) const175 bool Measure::operator==( const Measure& r ) const
176 {
177 return( mValue == r.value() &&
178 mMode == r.calculationMode() &&
179 mArea == r.referenceArea() &&
180 mOrientation == r.referenceOrientation() );
181 }
182
GlobalMeasureScaling()183 GlobalMeasureScaling::GlobalMeasureScaling() :
184 m_paintDevice( nullptr )
185 {
186 mFactors.push( qMakePair(qreal(1.0), qreal(1.0)) );
187 }
188
~GlobalMeasureScaling()189 GlobalMeasureScaling::~GlobalMeasureScaling()
190 {
191 // this space left empty intentionally
192 }
193
instance()194 GlobalMeasureScaling* GlobalMeasureScaling::instance()
195 {
196 static GlobalMeasureScaling instance;
197 return &instance;
198 }
199
setFactors(qreal factorX,qreal factorY)200 void GlobalMeasureScaling::setFactors(qreal factorX, qreal factorY)
201 {
202 instance()->mFactors.push( qMakePair(factorX, factorY) );
203 }
204
resetFactors()205 void GlobalMeasureScaling::resetFactors()
206 {
207 // never remove the initial (1.0. 1.0) setting
208 if ( instance()->mFactors.count() > 1 )
209 instance()->mFactors.pop();
210 }
211
currentFactors()212 const QPair< qreal, qreal > GlobalMeasureScaling::currentFactors()
213 {
214 return instance()->mFactors.top();
215 }
216
setPaintDevice(QPaintDevice * paintDevice)217 void GlobalMeasureScaling::setPaintDevice( QPaintDevice* paintDevice )
218 {
219 instance()->m_paintDevice = paintDevice;
220 }
221
paintDevice()222 QPaintDevice* GlobalMeasureScaling::paintDevice()
223 {
224 return instance()->m_paintDevice;
225 }
226
227 }
228
229 #if !defined(QT_NO_DEBUG_STREAM)
operator <<(QDebug dbg,const KChart::Measure & m)230 QDebug operator<<(QDebug dbg, const KChart::Measure& m)
231 {
232 dbg << "KChart::Measure("
233 << "value="<<m.value()
234 << "calculationmode="<<m.calculationMode()
235 << "referencearea="<<m.referenceArea()
236 << "referenceorientation="<<m.referenceOrientation()
237 << ")";
238 return dbg;
239 }
240 #endif /* QT_NO_DEBUG_STREAM */
241