File indexing completed on 2024-05-12 04:20:28
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 "KChartAbstractAxis.h" 0010 #include "KChartAbstractAxis_p.h" 0011 #include "KChartAbstractDiagram.h" 0012 #include "KChartAbstractCartesianDiagram.h" 0013 #include "KChartEnums.h" 0014 #include "KChartMeasure.h" 0015 #include "KChartMath_p.h" 0016 0017 using namespace KChart; 0018 0019 #define d d_func() 0020 0021 AbstractAxis::Private::Private( AbstractDiagram* diagram, AbstractAxis* axis ) 0022 : observer( nullptr ) 0023 , mDiagram( diagram ) 0024 , mAxis( axis ) 0025 { 0026 // Note: We do NOT call setDiagram( diagram, axis ); 0027 // but it is called in AbstractAxis::delayedInit() instead! 0028 } 0029 0030 AbstractAxis::Private::~Private() 0031 { 0032 delete observer; 0033 observer = nullptr; 0034 } 0035 0036 bool AbstractAxis::Private::setDiagram( AbstractDiagram* diagram_, bool delayedInit ) 0037 { 0038 AbstractDiagram* diagram = delayedInit ? mDiagram : diagram_; 0039 if ( delayedInit ) { 0040 mDiagram = nullptr; 0041 } 0042 0043 // do not set a diagram again that was already set 0044 if ( diagram && 0045 ((diagram == mDiagram) || secondaryDiagrams.contains( diagram )) ) 0046 return false; 0047 0048 bool bNewDiagramStored = false; 0049 if ( ! mDiagram ) { 0050 mDiagram = diagram; 0051 delete observer; 0052 if ( mDiagram ) { 0053 observer = new DiagramObserver( mDiagram, mAxis ); 0054 const bool con = connect( observer, &DiagramObserver::diagramDataChanged, 0055 mAxis, &AbstractAxis::coordinateSystemChanged ); 0056 Q_UNUSED( con ) 0057 Q_ASSERT( con ); 0058 bNewDiagramStored = true; 0059 } else { 0060 observer = nullptr; 0061 } 0062 } else { 0063 if ( diagram ) 0064 secondaryDiagrams.enqueue( diagram ); 0065 } 0066 return bNewDiagramStored; 0067 } 0068 0069 void AbstractAxis::Private::unsetDiagram( AbstractDiagram* diagram ) 0070 { 0071 if ( diagram == mDiagram ) { 0072 mDiagram = nullptr; 0073 delete observer; 0074 observer = nullptr; 0075 } else { 0076 secondaryDiagrams.removeAll( diagram ); 0077 } 0078 if ( !secondaryDiagrams.isEmpty() ) { 0079 AbstractDiagram *nextDiagram = secondaryDiagrams.dequeue(); 0080 setDiagram( nextDiagram ); 0081 } 0082 } 0083 0084 bool AbstractAxis::Private::hasDiagram( AbstractDiagram* diagram ) const 0085 { 0086 return diagram == mDiagram || secondaryDiagrams.contains( diagram ); 0087 } 0088 0089 void AbstractAxis::Private::updateLayouts() 0090 { 0091 if ( CartesianAxis* cartesianAxis = qobject_cast< CartesianAxis* >( mAxis ) ) { 0092 cartesianAxis->layoutPlanes(); 0093 } else { 0094 mAxis->update(); 0095 } 0096 } 0097 0098 AbstractAxis::AbstractAxis ( AbstractDiagram* diagram ) 0099 : AbstractArea( new Private( diagram, this ) ) 0100 { 0101 init(); 0102 QTimer::singleShot(0, this, SLOT(delayedInit())); 0103 } 0104 0105 AbstractAxis::~AbstractAxis() 0106 { 0107 d->mDiagram = nullptr; 0108 d->secondaryDiagrams.clear(); 0109 } 0110 0111 0112 void AbstractAxis::init() 0113 { 0114 Measure m( 14, KChartEnums::MeasureCalculationModeAuto, KChartEnums::MeasureOrientationAuto ); 0115 d->textAttributes.setFontSize( m ); 0116 m.setValue( 6 ); 0117 m.setCalculationMode( KChartEnums::MeasureCalculationModeAbsolute ); 0118 d->textAttributes.setMinimalFontSize( m ); 0119 if ( d->diagram() ) 0120 createObserver( d->diagram() ); 0121 } 0122 0123 void AbstractAxis::delayedInit() 0124 { 0125 // We call setDiagram() here, because the c'tor of Private 0126 // only has stored the pointers, but it did not call setDiagram(). 0127 if ( d ) 0128 d->setDiagram( nullptr, true /* delayedInit */ ); 0129 } 0130 0131 bool AbstractAxis::compare( const AbstractAxis* other ) const 0132 { 0133 if ( other == this ) { 0134 return true; 0135 } 0136 if ( !other ) { 0137 return false; 0138 } 0139 0140 return ( static_cast<const AbstractAreaBase*>(this)->compare( other ) ) && 0141 (textAttributes() == other->textAttributes()) && 0142 (labels() == other->labels()) && 0143 (shortLabels() == other->shortLabels()); 0144 } 0145 0146 0147 const QString AbstractAxis::customizedLabel( const QString& label ) const 0148 { 0149 return label; 0150 } 0151 0152 0153 void AbstractAxis::createObserver( AbstractDiagram* diagram ) 0154 { 0155 d->setDiagram( diagram ); 0156 } 0157 0158 void AbstractAxis::deleteObserver( AbstractDiagram* diagram ) 0159 { 0160 d->unsetDiagram( diagram ); 0161 } 0162 0163 void AbstractAxis::connectSignals() 0164 { 0165 if ( d->observer ) { 0166 const bool con = connect( d->observer, &DiagramObserver::diagramDataChanged, 0167 this, &AbstractAxis::coordinateSystemChanged ); 0168 Q_UNUSED( con ); 0169 Q_ASSERT( con ); 0170 } 0171 } 0172 0173 void AbstractAxis::setTextAttributes( const TextAttributes &a ) 0174 { 0175 if ( d->textAttributes == a ) 0176 return; 0177 0178 d->textAttributes = a; 0179 d->updateLayouts(); 0180 } 0181 0182 TextAttributes AbstractAxis::textAttributes() const 0183 { 0184 return d->textAttributes; 0185 } 0186 0187 0188 void AbstractAxis::setRulerAttributes( const RulerAttributes &a ) 0189 { 0190 d->rulerAttributes = a; 0191 d->updateLayouts(); 0192 } 0193 0194 RulerAttributes AbstractAxis::rulerAttributes() const 0195 { 0196 return d->rulerAttributes; 0197 } 0198 0199 void AbstractAxis::setLabels( const QStringList& list ) 0200 { 0201 if ( d->hardLabels == list ) 0202 return; 0203 0204 d->hardLabels = list; 0205 d->updateLayouts(); 0206 } 0207 0208 QStringList AbstractAxis::labels() const 0209 { 0210 return d->hardLabels; 0211 } 0212 0213 void AbstractAxis::setShortLabels( const QStringList& list ) 0214 { 0215 if ( d->hardShortLabels == list ) 0216 return; 0217 0218 d->hardShortLabels = list; 0219 d->updateLayouts(); 0220 } 0221 0222 QStringList AbstractAxis::shortLabels() const 0223 { 0224 return d->hardShortLabels; 0225 } 0226 0227 const AbstractCoordinatePlane* AbstractAxis::coordinatePlane() const 0228 { 0229 if ( d->diagram() ) 0230 return d->diagram()->coordinatePlane(); 0231 return nullptr; 0232 } 0233 0234 const AbstractDiagram * KChart::AbstractAxis::diagram() const 0235 { 0236 return d->diagram(); 0237 } 0238 0239 bool KChart::AbstractAxis::observedBy( AbstractDiagram * diagram ) const 0240 { 0241 return d->hasDiagram( diagram ); 0242 } 0243 0244 void KChart::AbstractAxis::update() 0245 { 0246 if ( d->diagram() ) 0247 d->diagram()->update(); 0248 }