00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <QGridLayout>
00028 #include <QRubberBand>
00029 #include <QMouseEvent>
00030
00031 #include "KDChartChart.h"
00032 #include "KDChartAbstractCoordinatePlane.h"
00033 #include "KDChartAbstractCoordinatePlane_p.h"
00034 #include "KDChartGridAttributes.h"
00035
00036 #include <KDABLibFakes>
00037
00038
00039 using namespace KDChart;
00040
00041 #define d d_func()
00042
00043 AbstractCoordinatePlane::Private::Private()
00044 : AbstractArea::Private()
00045 , parent( 0 )
00046 , grid( 0 )
00047 , referenceCoordinatePlane( 0 )
00048 , enableRubberBandZooming( false )
00049 , rubberBand( 0 )
00050 {
00051
00052 }
00053
00054
00055 AbstractCoordinatePlane::AbstractCoordinatePlane ( KDChart::Chart* parent )
00056 : AbstractArea ( new Private() )
00057 {
00058 d->parent = parent;
00059 d->init();
00060 }
00061
00062 AbstractCoordinatePlane::~AbstractCoordinatePlane()
00063 {
00064 emit destroyedCoordinatePlane( this );
00065 }
00066
00067 void AbstractCoordinatePlane::init()
00068 {
00069 d->initialize();
00070 }
00071
00072 void AbstractCoordinatePlane::addDiagram ( AbstractDiagram* diagram )
00073 {
00074
00075 diagram->hide();
00076
00077 d->diagrams.append( diagram );
00078 diagram->setParent( d->parent );
00079 diagram->setCoordinatePlane( this );
00080 layoutDiagrams();
00081 layoutPlanes();
00082 update();
00083 }
00084
00085
00086 void AbstractCoordinatePlane::replaceDiagram ( AbstractDiagram* diagram, AbstractDiagram* oldDiagram_ )
00087 {
00088 if( diagram && oldDiagram_ != diagram ){
00089 AbstractDiagram* oldDiagram = oldDiagram_;
00090 if( d->diagrams.count() ){
00091 if( ! oldDiagram )
00092 oldDiagram = d->diagrams.first();
00093 takeDiagram( oldDiagram );
00094 }
00095 delete oldDiagram;
00096 addDiagram( diagram );
00097 layoutDiagrams();
00098 layoutPlanes();
00099 update();
00100 }
00101 }
00102
00103
00104 void AbstractCoordinatePlane::takeDiagram ( AbstractDiagram* diagram )
00105 {
00106 const int idx = d->diagrams.indexOf( diagram );
00107 if( idx != -1 ){
00108 d->diagrams.removeAt( idx );
00109 diagram->setParent( 0 );
00110 diagram->setCoordinatePlane( 0 );
00111 layoutDiagrams();
00112 update();
00113 }
00114 }
00115
00116
00117 AbstractDiagram* AbstractCoordinatePlane::diagram()
00118 {
00119 if ( d->diagrams.isEmpty() )
00120 {
00121 return 0;
00122 } else {
00123 return d->diagrams.first();
00124 }
00125 }
00126
00127 AbstractDiagramList AbstractCoordinatePlane::diagrams()
00128 {
00129 return d->diagrams;
00130 }
00131
00132 ConstAbstractDiagramList AbstractCoordinatePlane::diagrams() const
00133 {
00134 ConstAbstractDiagramList list;
00135 #ifndef QT_NO_STL
00136 qCopy( d->diagrams.begin(), d->diagrams.end(), std::back_inserter( list ) );
00137 #else
00138 Q_FOREACH( AbstractDiagram * a, d->diagrams )
00139 list.push_back( a );
00140 #endif
00141 return list;
00142 }
00143
00144 QSize KDChart::AbstractCoordinatePlane::minimumSizeHint() const
00145 {
00146 return QSize( 200, 200 );
00147 }
00148
00149
00150 QSizePolicy KDChart::AbstractCoordinatePlane::sizePolicy() const
00151 {
00152 return QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
00153 }
00154
00155 void KDChart::AbstractCoordinatePlane::setGlobalGridAttributes( const GridAttributes& a )
00156 {
00157 d->gridAttributes = a;
00158 update();
00159 }
00160
00161 GridAttributes KDChart::AbstractCoordinatePlane::globalGridAttributes() const
00162 {
00163 return d->gridAttributes;
00164 }
00165
00166 KDChart::DataDimensionsList KDChart::AbstractCoordinatePlane::gridDimensionsList()
00167 {
00168
00169
00170
00171 return d->grid->updateData( this );
00172 }
00173
00174 void KDChart::AbstractCoordinatePlane::setGridNeedsRecalculate()
00175 {
00176 d->grid->setNeedRecalculate();
00177 }
00178
00179 void KDChart::AbstractCoordinatePlane::setReferenceCoordinatePlane( AbstractCoordinatePlane * plane )
00180 {
00181 d->referenceCoordinatePlane = plane;
00182 }
00183
00184 AbstractCoordinatePlane * KDChart::AbstractCoordinatePlane::referenceCoordinatePlane( ) const
00185 {
00186 return d->referenceCoordinatePlane;
00187 }
00188
00189 void KDChart::AbstractCoordinatePlane::setParent( KDChart::Chart* parent )
00190 {
00191 d->parent = parent;
00192 }
00193
00194 const KDChart::Chart* KDChart::AbstractCoordinatePlane::parent() const
00195 {
00196 return d->parent;
00197 }
00198
00199 KDChart::Chart* KDChart::AbstractCoordinatePlane::parent()
00200 {
00201 return d->parent;
00202 }
00203
00204
00205 bool KDChart::AbstractCoordinatePlane::isEmpty() const
00206 {
00207 return false;
00208
00209
00210 }
00211
00212 Qt::Orientations KDChart::AbstractCoordinatePlane::expandingDirections() const
00213 {
00214 return Qt::Vertical | Qt::Horizontal;
00215 }
00216
00217 QSize KDChart::AbstractCoordinatePlane::maximumSize() const
00218 {
00219
00220
00221 return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
00222 }
00223
00224 QSize KDChart::AbstractCoordinatePlane::minimumSize() const
00225 {
00226 return QSize(60, 60);
00227 }
00228
00229 QSize KDChart::AbstractCoordinatePlane::sizeHint() const
00230 {
00231
00232
00233 return maximumSize();
00234 }
00235
00236 void KDChart::AbstractCoordinatePlane::setGeometry( const QRect& r )
00237 {
00238
00239 if( d->geometry != r ){
00240 d->geometry = r;
00241
00242
00243 }
00244 }
00245
00246 QRect KDChart::AbstractCoordinatePlane::geometry() const
00247 {
00248 return d->geometry;
00249 }
00250
00251 void KDChart::AbstractCoordinatePlane::update()
00252 {
00253
00254 emit needUpdate();
00255 }
00256
00257 void KDChart::AbstractCoordinatePlane::relayout()
00258 {
00259
00260 emit needRelayout();
00261 }
00262
00263 void KDChart::AbstractCoordinatePlane::layoutPlanes()
00264 {
00265
00266 emit needLayoutPlanes();
00267 }
00268
00269 void KDChart::AbstractCoordinatePlane::setRubberBandZoomingEnabled( bool enable )
00270 {
00271 d->enableRubberBandZooming = enable;
00272
00273 if( !enable && d->rubberBand != 0 )
00274 {
00275 delete d->rubberBand;
00276 d->rubberBand = 0;
00277 }
00278 }
00279
00280 bool KDChart::AbstractCoordinatePlane::isRubberBandZoomingEnabled() const
00281 {
00282 return d->enableRubberBandZooming;
00283 }
00284
00285 void KDChart::AbstractCoordinatePlane::mousePressEvent( QMouseEvent* event )
00286 {
00287 if( event->button() == Qt::LeftButton )
00288 {
00289 if( d->enableRubberBandZooming && d->rubberBand == 0 )
00290 d->rubberBand = new QRubberBand( QRubberBand::Rectangle, qobject_cast< QWidget* >( parent() ) );
00291
00292 if( d->rubberBand != 0 )
00293 {
00294 d->rubberBandOrigin = event->pos();
00295 d->rubberBand->setGeometry( QRect( event->pos(), QSize() ) );
00296 d->rubberBand->show();
00297
00298 event->accept();
00299 }
00300 }
00301 else if( event->button() == Qt::RightButton )
00302 {
00303 if( d->enableRubberBandZooming && !d->rubberBandZoomConfigHistory.isEmpty() )
00304 {
00305
00306 ZoomParameters config = d->rubberBandZoomConfigHistory.pop();
00307 setZoomFactorX( config.xFactor );
00308 setZoomFactorY( config.yFactor );
00309 setZoomCenter( config.center() );
00310
00311 QWidget* const p = qobject_cast< QWidget* >( parent() );
00312 if( p != 0 )
00313 p->update();
00314
00315 event->accept();
00316 }
00317 }
00318
00319 KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
00320 {
00321 a->mousePressEvent( event );
00322 }
00323 }
00324
00325 void KDChart::AbstractCoordinatePlane::mouseDoubleClickEvent( QMouseEvent* event )
00326 {
00327 if( event->button() == Qt::RightButton )
00328 {
00329
00330
00331 mousePressEvent( event );
00332 }
00333 KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
00334 {
00335 a->mouseDoubleClickEvent( event );
00336 }
00337 }
00338
00339 void KDChart::AbstractCoordinatePlane::mouseReleaseEvent( QMouseEvent* event )
00340 {
00341 if( d->rubberBand != 0 )
00342 {
00343
00344 d->rubberBandZoomConfigHistory.push( ZoomParameters( zoomFactorX(), zoomFactorY(), zoomCenter() ) );
00345
00346
00347 const double rubberWidth = static_cast< double >( d->rubberBand->width() );
00348 const double rubberHeight = static_cast< double >( d->rubberBand->height() );
00349
00350
00351 const double rubberCenterX = static_cast< double >( d->rubberBand->geometry().center().x() - geometry().x() );
00352 const double rubberCenterY = static_cast< double >( d->rubberBand->geometry().center().y() - geometry().y() );
00353
00354
00355 const double myWidth = static_cast< double >( geometry().width() );
00356 const double myHeight = static_cast< double >( geometry().height() );
00357
00358
00359 const double newCenterX = rubberCenterX / myWidth / zoomFactorX() + zoomCenter().x() - 0.5 / zoomFactorX();
00360 const double newCenterY = rubberCenterY / myHeight / zoomFactorY() + zoomCenter().y() - 0.5 / zoomFactorY();
00361
00362
00363 const double newZoomFactorX = zoomFactorX() * myWidth / rubberWidth;
00364 const double newZoomFactorY = zoomFactorY() * myHeight / rubberHeight;
00365
00366
00367 const QPointF newZoomCenter( newCenterX, newCenterY );
00368
00369 setZoomFactorX( newZoomFactorX );
00370 setZoomFactorY( newZoomFactorY );
00371 setZoomCenter( newZoomCenter );
00372
00373
00374 d->rubberBand->parentWidget()->update();
00375 delete d->rubberBand;
00376 d->rubberBand = 0;
00377
00378 event->accept();
00379 }
00380
00381 KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
00382 {
00383 a->mouseReleaseEvent( event );
00384 }
00385 }
00386
00387 void KDChart::AbstractCoordinatePlane::mouseMoveEvent( QMouseEvent* event )
00388 {
00389 if( d->rubberBand != 0 )
00390 {
00391 const QRect normalized = QRect( d->rubberBandOrigin, event->pos() ).normalized();
00392 d->rubberBand->setGeometry( normalized & geometry() );
00393
00394 event->accept();
00395 }
00396
00397 KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
00398 {
00399 a->mouseMoveEvent( event );
00400 }
00401 }
00402
00403 const bool KDChart::AbstractCoordinatePlane::isVisiblePoint( const QPointF& point ) const
00404 {
00405 return d->isVisiblePoint( this, point );
00406 }
00407
00408 AbstractCoordinatePlane* KDChart::AbstractCoordinatePlane::sharedAxisMasterPlane( QPainter* p )
00409 {
00410 Q_UNUSED( p );
00411 return this;
00412 }
00413
00414 #if !defined(QT_NO_DEBUG_STREAM)
00415 #include "KDChartEnums.h"
00416
00417 QDebug KDChart::operator<<( QDebug stream, const DataDimension& r )
00418 {
00419 stream << "DataDimension("
00420 << " start=" << r.start
00421 << " end=" << r.end
00422 << " sequence=" << KDChartEnums::granularitySequenceToString( r.sequence )
00423 << " isCalculated=" << r.isCalculated
00424 << " calcMode=" << ( r.calcMode == AbstractCoordinatePlane::Logarithmic ? "Logarithmic" : "Linear" )
00425 << " stepWidth=" << r.stepWidth
00426 << " subStepWidth=" << r.subStepWidth
00427 << " )";
00428 return stream;
00429 }
00430 #endif
00431
00432 #undef d