KDChartMeasure.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.  All rights reserved.
00003 **
00004 ** This file is part of the KD Chart library.
00005 **
00006 ** Licensees holding valid commercial KD Chart licenses may use this file in
00007 ** accordance with the KD Chart Commercial License Agreement provided with
00008 ** the Software.
00009 **
00010 **
00011 ** This file may be distributed and/or modified under the terms of the
00012 ** GNU General Public License version 2 and version 3 as published by the
00013 ** Free Software Foundation and appearing in the file LICENSE.GPL included.
00014 **
00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 **
00018 ** Contact info@kdab.com if any conditions of this licensing are not
00019 ** clear to you.
00020 **
00021 **********************************************************************/
00022 
00023 #include "KDChartMeasure.h"
00024 
00025 #include <QWidget>
00026 
00027 #include <QtXml/QDomDocumentFragment>
00028 #include <KDChartAbstractArea.h>
00029 #include <KDChartCartesianCoordinatePlane.h>
00030 #include <KDChartTextAttributes.h>
00031 #include <KDChartFrameAttributes.h>
00032 #include <KDChartBackgroundAttributes.h>
00033 
00034 #include <KDABLibFakes>
00035 
00036 
00037 namespace KDChart {
00038 
00039 
00040 Measure::Measure()
00041   : mValue( 0.0 ),
00042     mMode(  KDChartEnums::MeasureCalculationModeAuto ),
00043     mArea(  0 ),
00044     mOrientation( KDChartEnums::MeasureOrientationAuto )
00045 {
00046     // this bloc left empty intentionally
00047 }
00048 
00049 Measure::Measure( qreal value,
00050     KDChartEnums::MeasureCalculationMode mode,
00051     KDChartEnums::MeasureOrientation orientation )
00052   : mValue( value ),
00053     mMode(  mode ),
00054     mArea(  0 ),
00055     mOrientation( orientation )
00056 {
00057     // this bloc left empty intentionally
00058 }
00059 
00060 Measure::Measure( const Measure& r )
00061   : mValue( r.value() ),
00062     mMode(  r.calculationMode() ),
00063     mArea(  r.referenceArea() ),
00064     mOrientation( r.referenceOrientation() )
00065 {
00066     // this bloc left empty intentionally
00067 }
00068 
00069 Measure & Measure::operator=( const Measure& r )
00070 {
00071     if( this != &r ){
00072         mValue = r.value();
00073         mMode  = r.calculationMode();
00074         mArea  = r.referenceArea();
00075         mOrientation = r.referenceOrientation();
00076     }
00077 
00078     return *this;
00079 }
00080 
00081 
00082 qreal Measure::calculatedValue( const QSizeF& autoSize,
00083                                 KDChartEnums::MeasureOrientation autoOrientation) const
00084 {
00085     if( mMode == KDChartEnums::MeasureCalculationModeAbsolute ){
00086         return mValue;
00087     }else{
00088         qreal value = 0.0;
00089         const QObject theAutoArea;
00090         const QObject* autoArea = &theAutoArea;
00091         const QObject* area = mArea ? mArea : autoArea;
00092         KDChartEnums::MeasureOrientation orientation = mOrientation;
00093         switch( mMode ){
00094             case KDChartEnums::MeasureCalculationModeAuto:
00095                 area = autoArea;
00096                 orientation = autoOrientation;
00097                 break;
00098             case KDChartEnums::MeasureCalculationModeAutoArea:
00099                 area = autoArea;
00100                 break;
00101             case KDChartEnums::MeasureCalculationModeAutoOrientation:
00102                 orientation = autoOrientation;
00103                 break;
00104             case KDChartEnums::MeasureCalculationModeAbsolute: // fall through intended
00105             case KDChartEnums::MeasureCalculationModeRelative:
00106                 break;
00107         }
00108         if( area ){
00109             QSizeF size;
00110             if( area == autoArea )
00111                 size = autoSize;
00112             else
00113                 size = sizeOfArea( area );
00114             //qDebug() << ( area == autoArea ) << "size" << size;
00115             qreal referenceValue = 0;
00116             switch( orientation ){
00117                 case KDChartEnums::MeasureOrientationAuto: // fall through intended
00118                 case KDChartEnums::MeasureOrientationMinimum:
00119                     referenceValue = qMin( size.width(), size.height() );
00120                     break;
00121                 case KDChartEnums::MeasureOrientationMaximum:
00122                     referenceValue = qMax( size.width(), size.height() );
00123                     break;
00124                 case KDChartEnums::MeasureOrientationHorizontal:
00125                     referenceValue = size.width();
00126                     break;
00127                 case KDChartEnums::MeasureOrientationVertical:
00128                     referenceValue = size.height();
00129                     break;
00130             }
00131             value = mValue / 1000.0 * referenceValue;
00132         }
00133         return value;
00134     }
00135 }
00136 
00137 
00138 qreal Measure::calculatedValue( const QObject* autoArea,
00139                                 KDChartEnums::MeasureOrientation autoOrientation) const
00140 {
00141     return calculatedValue( sizeOfArea( autoArea ), autoOrientation);
00142 }
00143 
00144 
00145 const QSizeF Measure::sizeOfArea( const QObject* area ) const
00146 {
00147     QSizeF size;
00148     const CartesianCoordinatePlane* plane = dynamic_cast<const CartesianCoordinatePlane*>( area );
00149     if ( false ) {
00150         size = plane->visibleDiagramArea().size();
00151     } else {
00152         const AbstractArea* kdcArea = dynamic_cast<const AbstractArea*>(area);
00153         if( kdcArea ){
00154             size = kdcArea->geometry().size();
00155             //qDebug() << "Measure::sizeOfArea() found kdcArea with size" << size;
00156         }else{
00157             const QWidget* widget = dynamic_cast<const QWidget*>(area);
00158             if( widget ){
00159                 /* ATTENTION: Using the layout does not work: The Legend will never get the right size then!
00160                 const QLayout * layout = widget->layout();
00161                 if( layout ){
00162                     size = layout->geometry().size();
00163                     //qDebug() << "Measure::sizeOfArea() found widget with layout size" << size;
00164                 }else*/
00165                 {
00166                     size = widget->geometry().size();
00167                     //qDebug() << "Measure::sizeOfArea() found widget with size" << size;
00168                 }
00169             }else if( mMode != KDChartEnums::MeasureCalculationModeAbsolute ){
00170                 size = QSizeF(1.0, 1.0);
00171                 //qDebug("Measure::sizeOfArea() got no valid area.");
00172             }
00173         }
00174     }
00175     const QPair< qreal, qreal > factors
00176             = GlobalMeasureScaling::instance()->currentFactors();
00177     return QSizeF(size.width() * factors.first, size.height() * factors.second);
00178 }
00179 
00180 
00181 bool Measure::operator==( const Measure& r ) const
00182 {
00183     return( mValue == r.value() &&
00184             mMode  == r.calculationMode() &&
00185             mArea  == r.referenceArea() &&
00186             mOrientation == r.referenceOrientation() );
00187 }
00188 
00189 
00190 
00191 GlobalMeasureScaling::GlobalMeasureScaling()
00192 {
00193     mFactors.push( qMakePair(qreal(1.0), qreal(1.0)) );
00194 }
00195 
00196 GlobalMeasureScaling::~GlobalMeasureScaling()
00197 {
00198     // this space left empty intentionally
00199 }
00200 
00201 GlobalMeasureScaling* GlobalMeasureScaling::instance()
00202 {
00203     static GlobalMeasureScaling instance;
00204     return &instance;
00205 }
00206 
00207 void GlobalMeasureScaling::setFactors(qreal factorX, qreal factorY)
00208 {
00209     instance()->mFactors.push( qMakePair(factorX, factorY) );
00210 }
00211 
00212 void GlobalMeasureScaling::resetFactors()
00213 {
00214     // never remove the initial (1.0. 1.0) setting
00215     if( instance()->mFactors.count() > 1 )
00216         instance()->mFactors.pop();
00217 }
00218 
00219 const QPair< qreal, qreal > GlobalMeasureScaling::currentFactors()
00220 {
00221     return instance()->mFactors.top();
00222 }
00223 
00224 void GlobalMeasureScaling::setPaintDevice( QPaintDevice* paintDevice )
00225 {
00226     instance()->m_paintDevice = paintDevice;
00227 }
00228 
00229 QPaintDevice* GlobalMeasureScaling::paintDevice()
00230 {
00231     return instance()->m_paintDevice;
00232 }
00233 
00234 }
00235 
00236 #if !defined(QT_NO_DEBUG_STREAM)
00237 QDebug operator<<(QDebug dbg, const KDChart::Measure& m)
00238 {
00239     dbg << "KDChart::Measure("
00240         << "value="<<m.value()
00241         << "calculationmode="<<m.calculationMode()
00242         << "referencearea="<<m.referenceArea()
00243         << "referenceorientation="<<m.referenceOrientation()
00244         << ")";
00245     return dbg;
00246 }
00247 #endif /* QT_NO_DEBUG_STREAM */