File indexing completed on 2024-05-12 04:20:35
0001 /* 0002 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KD Chart library. 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "KChartMeasure.h" 0010 0011 #include <KChartAbstractArea.h> 0012 #include <KChartCartesianCoordinatePlane.h> 0013 #include <KChartTextAttributes.h> 0014 #include <KChartFrameAttributes.h> 0015 #include <KChartBackgroundAttributes.h> 0016 #include "KChartMath_p.h" 0017 0018 #include <QWidget> 0019 0020 namespace KChart { 0021 0022 0023 Measure::Measure() 0024 : mValue( 0.0 ), 0025 mMode( KChartEnums::MeasureCalculationModeAuto ), 0026 mArea( nullptr ), 0027 mOrientation( KChartEnums::MeasureOrientationAuto ) 0028 { 0029 // this block left empty intentionally 0030 } 0031 0032 Measure::Measure( qreal value, 0033 KChartEnums::MeasureCalculationMode mode, 0034 KChartEnums::MeasureOrientation orientation ) 0035 : mValue( value ), 0036 mMode( mode ), 0037 mArea( nullptr ), 0038 mOrientation( orientation ) 0039 { 0040 // this block left empty intentionally 0041 } 0042 0043 Measure::Measure( const Measure& r ) 0044 : mValue( r.value() ), 0045 mMode( r.calculationMode() ), 0046 mArea( r.referenceArea() ), 0047 mOrientation( r.referenceOrientation() ) 0048 { 0049 // this block left empty intentionally 0050 } 0051 0052 Measure & Measure::operator=( const Measure& r ) 0053 { 0054 if ( this != &r ) { 0055 mValue = r.value(); 0056 mMode = r.calculationMode(); 0057 mArea = r.referenceArea(); 0058 mOrientation = r.referenceOrientation(); 0059 } 0060 0061 return *this; 0062 } 0063 0064 0065 qreal Measure::calculatedValue( const QSizeF& autoSize, 0066 KChartEnums::MeasureOrientation autoOrientation) const 0067 { 0068 if ( mMode == KChartEnums::MeasureCalculationModeAbsolute ) { 0069 return mValue; 0070 } else { 0071 qreal value = 0.0; 0072 const QObject theAutoArea; 0073 const QObject* autoArea = &theAutoArea; 0074 const QObject* area = mArea ? mArea : autoArea; 0075 KChartEnums::MeasureOrientation orientation = mOrientation; 0076 switch ( mMode ) { 0077 case KChartEnums::MeasureCalculationModeAuto: 0078 area = autoArea; 0079 orientation = autoOrientation; 0080 break; 0081 case KChartEnums::MeasureCalculationModeAutoArea: 0082 area = autoArea; 0083 break; 0084 case KChartEnums::MeasureCalculationModeAutoOrientation: 0085 orientation = autoOrientation; 0086 break; 0087 case KChartEnums::MeasureCalculationModeAbsolute: // fall through intended 0088 case KChartEnums::MeasureCalculationModeRelative: 0089 break; 0090 } 0091 if ( area ) { 0092 QSizeF size; 0093 if ( area == autoArea ) 0094 size = autoSize; 0095 else 0096 size = sizeOfArea( area ); 0097 //qDebug() << ( area == autoArea ) << "size" << size; 0098 qreal referenceValue = 0; 0099 switch ( orientation ) { 0100 case KChartEnums::MeasureOrientationAuto: // fall through intended 0101 case KChartEnums::MeasureOrientationMinimum: 0102 referenceValue = qMin( size.width(), size.height() ); 0103 break; 0104 case KChartEnums::MeasureOrientationMaximum: 0105 referenceValue = qMax( size.width(), size.height() ); 0106 break; 0107 case KChartEnums::MeasureOrientationHorizontal: 0108 referenceValue = size.width(); 0109 break; 0110 case KChartEnums::MeasureOrientationVertical: 0111 referenceValue = size.height(); 0112 break; 0113 } 0114 value = mValue / 1000.0 * referenceValue; 0115 } 0116 return value; 0117 } 0118 } 0119 0120 0121 qreal Measure::calculatedValue( const QObject* autoArea, 0122 KChartEnums::MeasureOrientation autoOrientation) const 0123 { 0124 return calculatedValue( sizeOfArea( autoArea ), autoOrientation); 0125 } 0126 0127 0128 const QSizeF Measure::sizeOfArea( const QObject* area ) const 0129 { 0130 QSizeF size; 0131 const CartesianCoordinatePlane* plane = dynamic_cast<const CartesianCoordinatePlane*>( area ); 0132 if ( false ) { 0133 size = plane->visibleDiagramArea().size(); 0134 } else { 0135 const AbstractArea* kdcArea = dynamic_cast<const AbstractArea*>(area); 0136 if ( kdcArea ) { 0137 size = kdcArea->geometry().size(); 0138 //qDebug() << "Measure::sizeOfArea() found kdcArea with size" << size; 0139 } else { 0140 const QWidget* widget = dynamic_cast<const QWidget*>(area); 0141 if ( widget ) { 0142 /* ATTENTION: Using the layout does not work: The Legend will never get the right size then! 0143 const QLayout * layout = widget->layout(); 0144 if ( layout ) { 0145 size = layout->geometry().size(); 0146 //qDebug() << "Measure::sizeOfArea() found widget with layout size" << size; 0147 } else*/ 0148 { 0149 size = widget->geometry().size(); 0150 //qDebug() << "Measure::sizeOfArea() found widget with size" << size; 0151 } 0152 } else if ( mMode != KChartEnums::MeasureCalculationModeAbsolute ) { 0153 size = QSizeF(1.0, 1.0); 0154 //qDebug("Measure::sizeOfArea() got no valid area."); 0155 } 0156 } 0157 } 0158 const QPair< qreal, qreal > factors 0159 = GlobalMeasureScaling::instance()->currentFactors(); 0160 return QSizeF(size.width() * factors.first, size.height() * factors.second); 0161 } 0162 0163 0164 bool Measure::operator==( const Measure& r ) const 0165 { 0166 return( mValue == r.value() && 0167 mMode == r.calculationMode() && 0168 mArea == r.referenceArea() && 0169 mOrientation == r.referenceOrientation() ); 0170 } 0171 0172 GlobalMeasureScaling::GlobalMeasureScaling() : 0173 m_paintDevice( nullptr ) 0174 { 0175 mFactors.push( qMakePair(qreal(1.0), qreal(1.0)) ); 0176 } 0177 0178 GlobalMeasureScaling::~GlobalMeasureScaling() 0179 { 0180 // this space left empty intentionally 0181 } 0182 0183 GlobalMeasureScaling* GlobalMeasureScaling::instance() 0184 { 0185 static GlobalMeasureScaling instance; 0186 return &instance; 0187 } 0188 0189 void GlobalMeasureScaling::setFactors(qreal factorX, qreal factorY) 0190 { 0191 instance()->mFactors.push( qMakePair(factorX, factorY) ); 0192 } 0193 0194 void GlobalMeasureScaling::resetFactors() 0195 { 0196 // never remove the initial (1.0. 1.0) setting 0197 if ( instance()->mFactors.count() > 1 ) 0198 instance()->mFactors.pop(); 0199 } 0200 0201 const QPair< qreal, qreal > GlobalMeasureScaling::currentFactors() 0202 { 0203 return instance()->mFactors.top(); 0204 } 0205 0206 void GlobalMeasureScaling::setPaintDevice( QPaintDevice* paintDevice ) 0207 { 0208 instance()->m_paintDevice = paintDevice; 0209 } 0210 0211 QPaintDevice* GlobalMeasureScaling::paintDevice() 0212 { 0213 return instance()->m_paintDevice; 0214 } 0215 0216 } 0217 0218 #if !defined(QT_NO_DEBUG_STREAM) 0219 QDebug operator<<(QDebug dbg, const KChart::Measure& m) 0220 { 0221 dbg << "KChart::Measure(" 0222 << "value="<<m.value() 0223 << "calculationmode="<<m.calculationMode() 0224 << "referencearea="<<m.referenceArea() 0225 << "referenceorientation="<<m.referenceOrientation() 0226 << ")"; 0227 return dbg; 0228 } 0229 #endif /* QT_NO_DEBUG_STREAM */