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 */