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 #include "KDChartLayoutItems.h"
00027 #include "KDTextDocument.h"
00028 #include "KDChartAbstractArea.h"
00029 #include "KDChartAbstractDiagram.h"
00030 #include "KDChartBackgroundAttributes.h"
00031 #include "KDChartFrameAttributes.h"
00032 #include "KDChartPaintContext.h"
00033 #include "KDChartPainterSaver_p.h"
00034 #include <QTextCursor>
00035 #include <QTextBlockFormat>
00036 #include <QTextDocumentFragment>
00037 #include <QAbstractTextDocumentLayout>
00038 #include <QLayout>
00039 #include <QPainter>
00040 #include <QDebug>
00041 #include <QCoreApplication>
00042 #include <QApplication>
00043 #include <QStringList>
00044 #include <QStyle>
00045
00046 #include <KDABLibFakes>
00047
00048 #include <math.h>
00049
00050 #define PI 3.141592653589793
00051
00052
00053
00054
00055
00064 void KDChart::AbstractLayoutItem::setParentWidget( QWidget* widget )
00065 {
00066 mParent = widget;
00067 }
00068
00069 void KDChart::AbstractLayoutItem::paintAll( QPainter& painter )
00070 {
00071 paint( &painter );
00072 }
00073
00077 void KDChart::AbstractLayoutItem::paintCtx( PaintContext* context )
00078 {
00079 if( context )
00080 paint( context->painter() );
00081 }
00082
00086 void KDChart::AbstractLayoutItem::sizeHintChanged()const
00087 {
00088
00089
00090 if( mParent ) {
00091 if ( mParent->layout() )
00092 mParent->layout()->invalidate();
00093 else
00094 QApplication::postEvent( mParent, new QEvent( QEvent::LayoutRequest ) );
00095 }
00096 }
00097
00098
00099 KDChart::TextLayoutItem::TextLayoutItem( const QString& text,
00100 const KDChart::TextAttributes& attributes,
00101 const QObject* area,
00102 KDChartEnums::MeasureOrientation orientation,
00103 Qt::Alignment alignment )
00104 : AbstractLayoutItem( alignment )
00105 , mText( text )
00106 , mAttributes( attributes )
00107 , mAutoReferenceArea( area )
00108 , mAutoReferenceOrientation( orientation )
00109 , cachedSizeHint()
00110 , cachedFontSize( 0.0 )
00111 , cachedFont( mAttributes.font() )
00112 {
00113 }
00114
00115 KDChart::TextLayoutItem::TextLayoutItem()
00116 : AbstractLayoutItem( Qt::AlignLeft )
00117 , mText()
00118 , mAttributes()
00119 , mAutoReferenceArea( 0 )
00120 , mAutoReferenceOrientation( KDChartEnums::MeasureOrientationHorizontal )
00121 , cachedSizeHint()
00122 , cachedFontSize( 0.0 )
00123 , cachedFont( mAttributes.font() )
00124 {
00125
00126 }
00127
00128 void KDChart::TextLayoutItem::setAutoReferenceArea( const QObject* area )
00129 {
00130 mAutoReferenceArea = area;
00131 cachedSizeHint = QSize();
00132 sizeHint();
00133 }
00134
00135 const QObject* KDChart::TextLayoutItem::autoReferenceArea() const
00136 {
00137 return mAutoReferenceArea;
00138 }
00139
00140 void KDChart::TextLayoutItem::setText(const QString & text)
00141 {
00142 mText = text;
00143 cachedSizeHint = QSize();
00144 sizeHint();
00145 }
00146
00147 QString KDChart::TextLayoutItem::text() const
00148 {
00149 return mText;
00150 }
00151
00157 void KDChart::TextLayoutItem::setTextAttributes( const TextAttributes &a )
00158 {
00159 mAttributes = a;
00160 cachedSizeHint = QSize();
00161 sizeHint();
00162 }
00163
00169 KDChart::TextAttributes KDChart::TextLayoutItem::textAttributes() const
00170 {
00171 return mAttributes;
00172 }
00173
00174
00175 Qt::Orientations KDChart::TextLayoutItem::expandingDirections() const
00176 {
00177 return 0;
00178 }
00179
00180 QRect KDChart::TextLayoutItem::geometry() const
00181 {
00182 return mRect;
00183 }
00184
00185 bool KDChart::TextLayoutItem::isEmpty() const
00186 {
00187 return false;
00188 }
00189
00190 QSize KDChart::TextLayoutItem::maximumSize() const
00191 {
00192 return sizeHint();
00193 }
00194
00195 QSize KDChart::TextLayoutItem::minimumSize() const
00196 {
00197 return sizeHint();
00198 }
00199
00200 void KDChart::TextLayoutItem::setGeometry( const QRect& r )
00201 {
00202 mRect = r;
00203 }
00204
00205
00206 qreal KDChart::TextLayoutItem::realFontSize() const
00207 {
00208 return mAttributes.calculatedFontSize( mAutoReferenceArea, mAutoReferenceOrientation );
00209 }
00210
00211
00212 bool KDChart::TextLayoutItem::realFontWasRecalculated() const
00213 {
00214 const qreal fntSiz = realFontSize();
00215 const bool bRecalcDone =
00216 ( ( ! cachedSizeHint.isValid() ) || ( cachedFontSize != fntSiz ) );
00217
00218 if( bRecalcDone && fntSiz > 0.0 ){
00219 cachedFontSize = fntSiz;
00220 cachedFont.setPointSizeF( fntSiz );
00221 }
00222 return bRecalcDone;
00223 }
00224
00225
00226 QFont KDChart::TextLayoutItem::realFont() const
00227 {
00228 realFontWasRecalculated();
00229 return cachedFont;
00230 }
00231
00232 QPolygon KDChart::TextLayoutItem::rotatedCorners() const
00233 {
00234
00235 const qreal angle = mAttributes.rotation() * PI / 180.0;
00236 QSize size = unrotatedSizeHint();
00237
00238
00239 QPointF P1( size.height() * sin( angle ), 0 );
00240 QPointF P2( size.height() * sin( angle ) + size.width() * cos( angle ), size.width() * sin( angle ) );
00241 QPointF P3( size.width() * cos( angle ), size.width() * sin( angle ) + size.height() * cos( angle ) );
00242 QPointF P4( 0, size.height() * cos( angle ) );
00243
00244 QPolygon result;
00245 result << P1.toPoint() << P2.toPoint() << P3.toPoint() << P4.toPoint();
00246 return result;
00247 }
00248
00249 bool KDChart::TextLayoutItem::intersects( const TextLayoutItem& other, const QPointF& myPos, const QPointF& otherPos ) const
00250 {
00251 return intersects( other, myPos.toPoint(), otherPos.toPoint() );
00252 }
00253
00254 bool KDChart::TextLayoutItem::intersects( const TextLayoutItem& other, const QPoint& myPos, const QPoint& otherPos ) const
00255 {
00256 if ( mAttributes.rotation() != other.mAttributes.rotation() )
00257 {
00258
00259 QPolygon myPolygon( rotatedCorners() );
00260 QPolygon otherPolygon( other.rotatedCorners() );
00261
00262
00263 myPolygon.translate( myPos );
00264 otherPolygon.translate( otherPos );
00265
00266
00267 QRegion myRegion( myPolygon );
00268 QRegion otherRegion( otherPolygon );
00269
00270
00271 return ! myRegion.intersect( otherRegion ).isEmpty();
00272
00273 } else {
00274
00275 const qreal angle = mAttributes.rotation() * PI / 180.0;
00276
00277 const QSizeF mySize( unrotatedSizeHint() );
00278 const QSizeF otherSize( other.unrotatedSizeHint() );
00279
00280
00281 QPointF myP1( mySize.height() * sin( angle ), 0.0 );
00282
00283 QPointF otherP1 = QPointF( otherSize.height() * sin( angle ), 0.0 ) + otherPos - myPos;
00284
00285
00286 myP1 = QPointF( myP1.x() * cos( -angle ), myP1.x() * sin( -angle ) );
00287 qreal r = sqrt( otherP1.x() * otherP1.x() + otherP1.y() * otherP1.y() );
00288 otherP1 = QPointF( r * cos( -angle ), r * sin( -angle ) );
00289
00290
00291 return QRectF( myP1, mySize ).intersects( QRectF( otherP1, otherSize ) );
00292 }
00293 }
00294
00295 QSize KDChart::TextLayoutItem::sizeHint() const
00296 {
00297 if( realFontWasRecalculated() )
00298 {
00299 const QSize newSizeHint( calcSizeHint( cachedFont ) );
00300 if( newSizeHint != cachedSizeHint ){
00301 cachedSizeHint = newSizeHint;
00302 sizeHintChanged();
00303 }
00304 }
00305
00306 return cachedSizeHint;
00307 }
00308
00309
00310
00311
00312
00313 QSize KDChart::TextLayoutItem::unrotatedSizeHint( QFont fnt ) const
00314 {
00315 if ( fnt == QFont() )
00316 fnt = cachedFont;
00317
00318 const QFontMetricsF met( fnt, mParent );
00319 QSize ret(0, 0);
00320
00321
00322
00323
00324 QStringList lines = mText.split(QString::fromAscii("\n"));
00325 for (int i = 0; i < lines.size(); ++i){
00326 const QSize lSize = met.boundingRect(lines.at(i) ).toRect().size();
00327 ret.setWidth(qMax( ret.width(), lSize.width() ));
00328 ret.rheight() += lSize.height();
00329 }
00330
00331 int frame = QApplication::style()->pixelMetric( QStyle::PM_ButtonMargin, 0, 0 );
00332
00333 frame = qMin( frame, ret.height() * 2 / 3 );
00334
00335 ret += QSize( frame, frame );
00336 return ret;
00337
00338
00339
00340
00341 }
00342
00343
00344 QSize KDChart::TextLayoutItem::calcSizeHint( QFont fnt ) const
00345 {
00346 QSize ret = unrotatedSizeHint( fnt );
00347
00348 const qreal angle = PI * mAttributes.rotation() / 180.0;
00349 const qreal cosAngle = cos( angle );
00350 const qreal sinAngle = sin( angle );
00351 QSize rotated( qAbs(static_cast<int>( cosAngle * ret.width() + sinAngle * ret.height() )),
00352 qAbs(static_cast<int>( cosAngle * ret.height() + sinAngle * ret.width() )) );
00353
00354 return rotated;
00355 }
00356
00357 static QPointF rotatedPoint( const QPointF& pt, qreal rotation )
00358 {
00359 const qreal angle = PI * rotation / 180.0;
00360 const qreal cosAngle = cos( angle );
00361 const qreal sinAngle = sin( angle );
00362 return QPointF(
00363 (cosAngle * pt.x() + sinAngle * pt.y() ),
00364 (cosAngle * pt.y() + sinAngle * pt.x() ) );
00365 }
00366
00367 static QRectF rotatedRect( const QRectF& rect, qreal angle )
00368 {
00369 const QPointF topLeft( rotatedPoint( rect.topLeft(), angle ) );
00370
00371
00372
00373 const QPointF siz( rotatedPoint( QPointF( rect.size().width(), rect.size().height() ), angle ) );
00374 const QRectF result(
00375 topLeft,
00376 QSizeF( siz.x(),
00377 siz.y() ) );
00378
00379 return result;
00380 }
00381
00382 void KDChart::TextLayoutItem::paint( QPainter* painter )
00383 {
00384
00385
00386
00387 if( !mRect.isValid() )
00388 return;
00389
00390 PainterSaver painterSaver( painter );
00391 painter->setFont( cachedFont );
00392 QRectF rect( geometry() );
00393
00394
00395
00396
00397
00398 painter->translate( rect.center() );
00399 rect.moveTopLeft( QPointF( - rect.width() / 2, - rect.height() / 2 ) );
00400 #ifdef DEBUG_ITEMS_PAINT
00401 painter->setPen( Qt::blue );
00402 painter->drawRect( rect );
00403 #endif
00404 painter->rotate( mAttributes.rotation() );
00405 rect = rotatedRect( rect, mAttributes.rotation() );
00406 #ifdef DEBUG_ITEMS_PAINT
00407 painter->setPen( Qt::red );
00408 painter->drawRect( rect );
00409 #endif
00410 painter->setPen( mAttributes.pen() );
00411 painter->drawText( rect, Qt::AlignHCenter | Qt::AlignVCenter, mText );
00412
00413
00414
00415
00416 }
00417
00418 KDChart::HorizontalLineLayoutItem::HorizontalLineLayoutItem()
00419 : AbstractLayoutItem( Qt::AlignCenter )
00420 {
00421 }
00422
00423 Qt::Orientations KDChart::HorizontalLineLayoutItem::expandingDirections() const
00424 {
00425 return Qt::Vertical|Qt::Horizontal;
00426 }
00427
00428 QRect KDChart::HorizontalLineLayoutItem::geometry() const
00429 {
00430 return mRect;
00431 }
00432
00433 bool KDChart::HorizontalLineLayoutItem::isEmpty() const
00434 {
00435 return false;
00436 }
00437
00438 QSize KDChart::HorizontalLineLayoutItem::maximumSize() const
00439 {
00440 return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
00441 }
00442
00443 QSize KDChart::HorizontalLineLayoutItem::minimumSize() const
00444 {
00445 return QSize( 0, 0 );
00446 }
00447
00448 void KDChart::HorizontalLineLayoutItem::setGeometry( const QRect& r )
00449 {
00450 mRect = r;
00451 }
00452
00453 QSize KDChart::HorizontalLineLayoutItem::sizeHint() const
00454 {
00455 return QSize( -1, 3 );
00456 }
00457
00458
00459 void KDChart::HorizontalLineLayoutItem::paint( QPainter* painter )
00460 {
00461 if( !mRect.isValid() )
00462 return;
00463
00464 painter->drawLine( QPointF( mRect.left(), mRect.center().y() ),
00465 QPointF( mRect.right(), mRect.center().y() ) );
00466 }
00467
00468
00469 KDChart::VerticalLineLayoutItem::VerticalLineLayoutItem()
00470 : AbstractLayoutItem( Qt::AlignCenter )
00471 {
00472 }
00473
00474 Qt::Orientations KDChart::VerticalLineLayoutItem::expandingDirections() const
00475 {
00476 return Qt::Vertical|Qt::Vertical;
00477 }
00478
00479 QRect KDChart::VerticalLineLayoutItem::geometry() const
00480 {
00481 return mRect;
00482 }
00483
00484 bool KDChart::VerticalLineLayoutItem::isEmpty() const
00485 {
00486 return false;
00487 }
00488
00489 QSize KDChart::VerticalLineLayoutItem::maximumSize() const
00490 {
00491 return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
00492 }
00493
00494 QSize KDChart::VerticalLineLayoutItem::minimumSize() const
00495 {
00496 return QSize( 0, 0 );
00497 }
00498
00499 void KDChart::VerticalLineLayoutItem::setGeometry( const QRect& r )
00500 {
00501 mRect = r;
00502 }
00503
00504 QSize KDChart::VerticalLineLayoutItem::sizeHint() const
00505 {
00506 return QSize( 3, -1 );
00507 }
00508
00509
00510 void KDChart::VerticalLineLayoutItem::paint( QPainter* painter )
00511 {
00512 if( !mRect.isValid() )
00513 return;
00514
00515 painter->drawLine( QPointF( mRect.center().x(), mRect.top() ),
00516 QPointF( mRect.center().x(), mRect.bottom() ) );
00517 }
00518
00519
00520
00521 KDChart::MarkerLayoutItem::MarkerLayoutItem( KDChart::AbstractDiagram* diagram,
00522 const MarkerAttributes& marker,
00523 const QBrush& brush, const QPen& pen,
00524 Qt::Alignment alignment )
00525 : AbstractLayoutItem( alignment )
00526 , mDiagram( diagram )
00527 , mMarker( marker )
00528 , mBrush( brush )
00529 , mPen( pen )
00530 {
00531 }
00532
00533 Qt::Orientations KDChart::MarkerLayoutItem::expandingDirections() const
00534 {
00535 return 0;
00536 }
00537
00538 QRect KDChart::MarkerLayoutItem::geometry() const
00539 {
00540 return mRect;
00541 }
00542
00543 bool KDChart::MarkerLayoutItem::isEmpty() const
00544 {
00545 return false;
00546 }
00547
00548 QSize KDChart::MarkerLayoutItem::maximumSize() const
00549 {
00550 return sizeHint();
00551 }
00552
00553 QSize KDChart::MarkerLayoutItem::minimumSize() const
00554 {
00555 return sizeHint();
00556 }
00557
00558 void KDChart::MarkerLayoutItem::setGeometry( const QRect& r )
00559 {
00560 mRect = r;
00561 }
00562
00563 QSize KDChart::MarkerLayoutItem::sizeHint() const
00564 {
00565
00566 return mMarker.markerSize().toSize();
00567 }
00568
00569 void KDChart::MarkerLayoutItem::paint( QPainter* painter )
00570 {
00571 paintIntoRect( painter, mRect, mDiagram, mMarker, mBrush, mPen );
00572 }
00573
00574 void KDChart::MarkerLayoutItem::paintIntoRect(
00575 QPainter* painter,
00576 const QRect& rect,
00577 AbstractDiagram* diagram,
00578 const MarkerAttributes& marker,
00579 const QBrush& brush,
00580 const QPen& pen )
00581 {
00582 if( ! rect.isValid() )
00583 return;
00584
00585
00586
00587 const QSize siz = marker.markerSize().toSize();
00588 QPointF pos = rect.topLeft();
00589 pos += QPointF( static_cast<qreal>(( rect.width() - siz.width()) / 2.0 ),
00590 static_cast<qreal>(( rect.height() - siz.height()) / 2.0 ) );
00591
00592 #ifdef DEBUG_ITEMS_PAINT
00593 QPointF oldPos = pos;
00594 #endif
00595
00596
00597
00598 pos += QPointF( static_cast<qreal>( siz.width() ) / 2.0,
00599 static_cast<qreal>( siz.height() )/ 2.0 );
00600
00601 diagram->paintMarker( painter, marker, brush, pen, pos.toPoint(), siz );
00602
00603 #ifdef DEBUG_ITEMS_PAINT
00604 const QPen oldPen( painter->pen() );
00605 painter->setPen( Qt::red );
00606 painter->drawRect( QRect(oldPos.toPoint(), siz) );
00607 painter->setPen( oldPen );
00608 #endif
00609 }
00610
00611
00612 KDChart::LineLayoutItem::LineLayoutItem( KDChart::AbstractDiagram* diagram,
00613 int length,
00614 const QPen& pen,
00615 Qt::Alignment alignment )
00616 : AbstractLayoutItem( alignment )
00617 , mDiagram( diagram )
00618 , mLength( length )
00619 , mPen( pen )
00620 {
00621
00622 if ( pen.width() < 2 )
00623 mPen.setWidth( 2 );
00624 }
00625
00626 Qt::Orientations KDChart::LineLayoutItem::expandingDirections() const
00627 {
00628 return 0;
00629 }
00630
00631 QRect KDChart::LineLayoutItem::geometry() const
00632 {
00633 return mRect;
00634 }
00635
00636 bool KDChart::LineLayoutItem::isEmpty() const
00637 {
00638 return false;
00639 }
00640
00641 QSize KDChart::LineLayoutItem::maximumSize() const
00642 {
00643 return sizeHint();
00644 }
00645
00646 QSize KDChart::LineLayoutItem::minimumSize() const
00647 {
00648 return sizeHint();
00649 }
00650
00651 void KDChart::LineLayoutItem::setGeometry( const QRect& r )
00652 {
00653 mRect = r;
00654 }
00655
00656 QSize KDChart::LineLayoutItem::sizeHint() const
00657 {
00658 return QSize( mLength, mPen.width()+2 );
00659 }
00660
00661 void KDChart::LineLayoutItem::paint( QPainter* painter )
00662 {
00663 paintIntoRect( painter, mRect, mPen );
00664 }
00665
00666 void KDChart::LineLayoutItem::paintIntoRect(
00667 QPainter* painter,
00668 const QRect& rect,
00669 const QPen& pen )
00670 {
00671 if( ! rect.isValid() )
00672 return;
00673
00674 const QPen oldPen = painter->pen();
00675 painter->setPen( pen );
00676 const qreal y = rect.center().y();
00677 painter->drawLine( QPointF( rect.left(), y ),
00678 QPointF( rect.right(), y ) );
00679 painter->setPen( oldPen );
00680 }
00681
00682
00683 KDChart::LineWithMarkerLayoutItem::LineWithMarkerLayoutItem(
00684 KDChart::AbstractDiagram* diagram,
00685 int lineLength,
00686 const QPen& linePen,
00687 int markerOffs,
00688 const MarkerAttributes& marker,
00689 const QBrush& markerBrush,
00690 const QPen& markerPen,
00691 Qt::Alignment alignment )
00692 : AbstractLayoutItem( alignment )
00693 , mDiagram( diagram )
00694 , mLineLength( lineLength )
00695 , mLinePen( linePen )
00696 , mMarkerOffs( markerOffs )
00697 , mMarker( marker )
00698 , mMarkerBrush( markerBrush )
00699 , mMarkerPen( markerPen )
00700 {
00701 }
00702
00703 Qt::Orientations KDChart::LineWithMarkerLayoutItem::expandingDirections() const
00704 {
00705 return 0;
00706 }
00707
00708 QRect KDChart::LineWithMarkerLayoutItem::geometry() const
00709 {
00710 return mRect;
00711 }
00712
00713 bool KDChart::LineWithMarkerLayoutItem::isEmpty() const
00714 {
00715 return false;
00716 }
00717
00718 QSize KDChart::LineWithMarkerLayoutItem::maximumSize() const
00719 {
00720 return sizeHint();
00721 }
00722
00723 QSize KDChart::LineWithMarkerLayoutItem::minimumSize() const
00724 {
00725 return sizeHint();
00726 }
00727
00728 void KDChart::LineWithMarkerLayoutItem::setGeometry( const QRect& r )
00729 {
00730 mRect = r;
00731 }
00732
00733 QSize KDChart::LineWithMarkerLayoutItem::sizeHint() const
00734 {
00735 const QSize sizeM = mMarker.markerSize().toSize();
00736 const QSize sizeL = QSize( mLineLength, mLinePen.width()+2 );
00737 return QSize( qMax(sizeM.width(), sizeL.width()),
00738 qMax(sizeM.height(), sizeL.height()) );
00739 }
00740
00741 void KDChart::LineWithMarkerLayoutItem::paint( QPainter* painter )
00742 {
00743
00744 LineLayoutItem::paintIntoRect( painter, mRect, mLinePen );
00745
00746
00747 const QRect r(
00748 QPoint( mRect.x()+mMarkerOffs, mRect.y() ),
00749 QSize( mMarker.markerSize().toSize().width(), mRect.height() ) );
00750 MarkerLayoutItem::paintIntoRect(
00751 painter, r, mDiagram, mMarker, mMarkerBrush, mMarkerPen );
00752 }
00753
00754
00755
00756 KDChart::AutoSpacerLayoutItem::AutoSpacerLayoutItem(
00757 bool layoutIsAtTopPosition, QHBoxLayout *rightLeftLayout,
00758 bool layoutIsAtLeftPosition, QVBoxLayout *topBottomLayout )
00759 : AbstractLayoutItem( Qt::AlignCenter )
00760 , mLayoutIsAtTopPosition( layoutIsAtTopPosition )
00761 , mRightLeftLayout( rightLeftLayout )
00762 , mLayoutIsAtLeftPosition( layoutIsAtLeftPosition )
00763 , mTopBottomLayout( topBottomLayout )
00764 {
00765 }
00766
00767 Qt::Orientations KDChart::AutoSpacerLayoutItem::expandingDirections() const
00768 {
00769 return 0;
00770 }
00771
00772 QRect KDChart::AutoSpacerLayoutItem::geometry() const
00773 {
00774 return mRect;
00775 }
00776
00777 bool KDChart::AutoSpacerLayoutItem::isEmpty() const
00778 {
00779 return true;
00780 }
00781
00782 QSize KDChart::AutoSpacerLayoutItem::maximumSize() const
00783 {
00784 return sizeHint();
00785 }
00786
00787 QSize KDChart::AutoSpacerLayoutItem::minimumSize() const
00788 {
00789 return sizeHint();
00790 }
00791
00792 void KDChart::AutoSpacerLayoutItem::setGeometry( const QRect& r )
00793 {
00794 mRect = r;
00795 }
00796
00797
00798 static void updateCommonBrush( QBrush& commonBrush, bool& bStart, const KDChart::AbstractArea& area )
00799 {
00800 const KDChart::BackgroundAttributes ba( area.backgroundAttributes() );
00801 const bool hasSimpleBrush = (
00802 ! area.frameAttributes().isVisible() &&
00803 ba.isVisible() &&
00804 ba.pixmapMode() == KDChart::BackgroundAttributes::BackgroundPixmapModeNone &&
00805 ba.brush().gradient() == 0 );
00806 if( bStart ){
00807 bStart = false;
00808 commonBrush = hasSimpleBrush ? ba.brush() : QBrush();
00809 }else{
00810 if( ! hasSimpleBrush || ba.brush() != commonBrush )
00811 {
00812 commonBrush = QBrush();
00813 }
00814 }
00815 }
00816
00817 QSize KDChart::AutoSpacerLayoutItem::sizeHint() const
00818 {
00819 QBrush commonBrush;
00820 bool bStart=true;
00821
00822 int topBottomOverlap = 0;
00823 if( mTopBottomLayout ){
00824 for (int i = 0; i < mTopBottomLayout->count(); ++i){
00825 AbstractArea* area = dynamic_cast<AbstractArea*>(mTopBottomLayout->itemAt(i));
00826 if( area ){
00827
00828 topBottomOverlap =
00829 mLayoutIsAtLeftPosition
00830 ? qMax( topBottomOverlap, area->rightOverlap() )
00831 : qMax( topBottomOverlap, area->leftOverlap() );
00832 updateCommonBrush( commonBrush, bStart, *area );
00833 }
00834 }
00835 }
00836
00837 int leftRightOverlap = 0;
00838 if( mRightLeftLayout ){
00839 for (int i = 0; i < mRightLeftLayout->count(); ++i){
00840 AbstractArea* area = dynamic_cast<AbstractArea*>(mRightLeftLayout->itemAt(i));
00841 if( area ){
00842
00843 leftRightOverlap =
00844 mLayoutIsAtTopPosition
00845 ? qMax( leftRightOverlap, area->bottomOverlap() )
00846 : qMax( leftRightOverlap, area->topOverlap() );
00847 updateCommonBrush( commonBrush, bStart, *area );
00848 }
00849 }
00850 }
00851 if( topBottomOverlap > 0 && leftRightOverlap > 0 )
00852 mCommonBrush = commonBrush;
00853 else
00854 mCommonBrush = QBrush();
00855 mCachedSize = QSize( topBottomOverlap, leftRightOverlap );
00856
00857 return mCachedSize;
00858 }
00859
00860
00861 void KDChart::AutoSpacerLayoutItem::paint( QPainter* painter )
00862 {
00863 if( mParentLayout && mRect.isValid() && mCachedSize.isValid() &&
00864 mCommonBrush.style() != Qt::NoBrush )
00865 {
00866 QPoint p1( mRect.topLeft() );
00867 QPoint p2( mRect.bottomRight() );
00868 if( mLayoutIsAtLeftPosition )
00869 p1.rx() += mCachedSize.width() - mParentLayout->spacing();
00870 else
00871 p2.rx() -= mCachedSize.width() - mParentLayout->spacing();
00872 if( mLayoutIsAtTopPosition ){
00873 p1.ry() += mCachedSize.height() - mParentLayout->spacing() - 1;
00874 p2.ry() -= 1;
00875 }else
00876 p2.ry() -= mCachedSize.height() - mParentLayout->spacing() - 1;
00877
00878
00879
00880
00881 const QPoint oldBrushOrigin( painter->brushOrigin() );
00882 const QBrush oldBrush( painter->brush() );
00883 const QPen oldPen( painter->pen() );
00884 const QPointF newTopLeft( painter->deviceMatrix().map( p1 ) );
00885 painter->setBrushOrigin( newTopLeft );
00886 painter->setBrush( mCommonBrush );
00887 painter->setPen( Qt::NoPen );
00888 painter->drawRect( QRect( p1, p2 ) );
00889 painter->setBrushOrigin( oldBrushOrigin );
00890 painter->setBrush( oldBrush );
00891 painter->setPen( oldPen );
00892 }
00893
00894 #if 0
00895
00896 if( !mRect.isValid() )
00897 return;
00898
00899 painter->drawRect( mRect );
00900 painter->drawLine( QPointF( mRect.x(), mRect.top() ),
00901 QPointF( mRect.right(), mRect.bottom() ) );
00902 painter->drawLine( QPointF( mRect.right(), mRect.top() ),
00903 QPointF( mRect.x(), mRect.bottom() ) );
00904 #endif
00905 }