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