30 #include "KDChartPainterSaver_p.h" 32 #include <QTextCursor> 33 #include <QTextBlockFormat> 34 #include <QTextDocumentFragment> 35 #include <QAbstractTextDocumentLayout> 39 #include <QCoreApplication> 40 #include <QApplication> 41 #include <QStringList> 44 #include <KDABLibFakes> 87 mParent->layout()->invalidate();
89 QApplication::postEvent(
mParent,
new QEvent( QEvent::LayoutRequest ) );
97 Qt::Alignment alignment )
99 m_text( new
TextLayoutItem( text, attributes, area, orientation, alignment ) )
131 return m_text->
text();
157 return m_text->
maximumSize() + QSize( 2 * border, 2 * border );
163 return m_text->
minimumSize() + QSize( 2 * border, 2 * border );
169 return m_text->
sizeHint() + QSize( 2 * border, 2 * border );
175 m_text->
setGeometry( r.adjusted( border, border, -border, -border ) );
181 return m_text->
geometry().adjusted( -border, -border, border, border );
186 const QPen oldPen = painter->pen();
187 const QBrush oldBrush = painter->brush();
188 painter->setPen( Qt::black );
189 painter->setBrush( QColor( 255, 255, 220 ) );
190 painter->drawRoundRect(
geometry(), 10 );
191 painter->setPen( oldPen );
192 painter->setBrush( oldBrush );
193 m_text->
paint( painter );
205 Qt::Alignment alignment )
208 , mTextAlignment( alignment )
209 , mAttributes( attributes )
210 , mAutoReferenceArea( area )
211 , mAutoReferenceOrientation( orientation )
213 , cachedFontSize( 0.0 )
214 , cachedFont( mAttributes.font() )
221 , mTextAlignment( Qt::AlignLeft )
223 , mAutoReferenceArea( 0 )
224 , mAutoReferenceOrientation(
KDChartEnums::MeasureOrientationHorizontal )
226 , cachedFontSize( 0.0 )
227 , cachedFont( mAttributes.font() )
234 mAutoReferenceArea = area;
235 cachedSizeHint = QSize();
241 return mAutoReferenceArea;
247 cachedSizeHint = QSize();
260 if ( mTextAlignment == alignment )
262 mTextAlignment = alignment;
269 return mTextAlignment;
280 cachedFont = a.
font();
281 cachedSizeHint = QSize();
332 QPointF center = rect.center();
333 t.translate( center.x(), center.y() );
334 t.rotate( rotation );
335 t.translate( -center.x(), -center.y() );
336 return t.mapRect( rect );
339 qreal KDChart::TextLayoutItem::fitFontSizeToGeometry()
const 342 const qreal origResult = f.pointSizeF();
343 qreal result = origResult;
345 const QSize mySize =
geometry().size();
346 if ( mySize.isNull() ) {
350 QFontMetrics fm( f );
352 const QSizeF textSize =
rotatedRect( fm.boundingRect( mText ), mAttributes.
rotation() ).normalized().size();
354 if ( textSize.height() <= mySize.height() && textSize.width() <= mySize.width() ) {
359 if ( minSize > 0 && result < minSize ) {
361 }
else if ( result <= 0.0 ) {
364 f.setPointSizeF( result );
365 fm = QFontMetrics( f );
371 return mAttributes.
calculatedFontSize( mAutoReferenceArea, mAutoReferenceOrientation );
374 bool KDChart::TextLayoutItem::maybeUpdateRealFont()
const 377 const bool doUpdate = !cachedSizeHint.isValid() || cachedFontSize != fntSiz;
379 if ( doUpdate && fntSiz > 0.0 ) {
380 cachedFontSize = fntSiz;
381 cachedFont.setPointSizeF( fntSiz );
388 maybeUpdateRealFont();
395 return mCachedBoundingPolygon;
400 return intersects( other, myPos.toPoint(), otherPos.toPoint() );
408 return myRegion.intersects( otherRegion );
414 if ( maybeUpdateRealFont() || mAttributes.
rotation() || !cachedSizeHint.isValid() ) {
415 const QSize newSizeHint( calcSizeHint( cachedFont ) );
416 Q_ASSERT( newSizeHint.isValid() );
417 if ( newSizeHint != cachedSizeHint ) {
418 cachedSizeHint = newSizeHint;
422 return cachedSizeHint;
427 maybeUpdateRealFont();
428 return unrotatedSizeHint( cachedFont );
435 QSize KDChart::TextLayoutItem::unrotatedTextSize( QFont fnt )
const 437 if ( fnt == QFont() ) {
442 QRect veryLarge( 0, 0, 100000, 100000 );
444 return fm.boundingRect( veryLarge, Qt::AlignLeft | Qt::AlignTop, mText ).size().toSize();
454 return qMin ( QApplication::style()->pixelMetric( QStyle::PM_ButtonMargin, 0, 0 ),
456 textSize.height() * 2 / 3 );
459 QSize KDChart::TextLayoutItem::unrotatedSizeHint(
const QFont& fnt )
const 461 QSize ret = unrotatedTextSize( fnt );
463 ret += QSize( margin, margin );
467 QSize KDChart::TextLayoutItem::calcSizeHint(
const QFont& font )
const 469 const QSize size = unrotatedSizeHint( font );
470 QPoint topLeft( -size.width() * 0.5, -size.height() * 0.5 );
472 mCachedBoundingPolygon.resize( 4 );
475 mCachedBoundingPolygon[ 0 ] = topLeft;
476 mCachedBoundingPolygon[ 1 ] = topLeft + QPoint( size.width(), 0 );
477 mCachedBoundingPolygon[ 2 ] = topLeft + QPoint( size.width(), size.height() );
478 mCachedBoundingPolygon[ 3 ] = topLeft + QPoint( 0, size.height() );
482 const QRect rect( topLeft, size );
485 mCachedBoundingPolygon = t.mapToPolygon( rect );
487 return mCachedBoundingPolygon.boundingRect().size();
492 if ( !mRect.isValid() ) {
495 const PainterSaver painterSaver( painter );
498 f.setPointSizeF( fitFontSizeToGeometry() );
500 painter->setFont( f );
502 QSize innerSize = unrotatedTextSize();
503 QRectF rect = QRectF( QPointF( 0, 0 ), innerSize );
504 rect.translate( -rect.center() );
505 painter->translate( mRect.center() );
506 painter->rotate( mAttributes.
rotation() );
507 #ifdef DEBUG_ITEMS_PAINT 508 painter->setPen( Qt::red );
509 painter->drawRect( rect );
515 document->setPageSize( rect.size() );
516 document->setHtml( mText );
517 QAbstractTextDocumentLayout::PaintContext paintcontext;
520 paintcontext.clip = rect;
521 document->documentLayout()->draw( painter, paintcontext );
523 painter->drawText( rect, mTextAlignment, mText );
534 return Qt::Horizontal;
549 return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
554 return QSize( 0, 0 );
564 return QSize( -1, 3 );
570 if ( !mRect.isValid() )
573 painter->drawLine( QPointF( mRect.left(), mRect.center().y() ),
574 QPointF( mRect.right(), mRect.center().y() ) );
600 return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
605 return QSize( 0, 0 );
615 return QSize( 3, -1 );
621 if ( !mRect.isValid() )
624 painter->drawLine( QPointF( mRect.center().x(), mRect.top() ),
625 QPointF( mRect.center().x(), mRect.bottom() ) );
632 const QBrush& brush,
const QPen& pen,
633 Qt::Alignment alignment )
635 , mDiagram( diagram )
680 paintIntoRect( painter, mRect, mDiagram, mMarker, mBrush, mPen );
691 if ( !rect.isValid() )
696 const QSize siz = marker.
markerSize().toSize();
697 QPointF pos = rect.topLeft();
698 pos += QPointF( static_cast<qreal>(( rect.width() - siz.width()) / 2.0 ),
699 static_cast<qreal
>(( rect.height() - siz.height()) / 2.0 ) );
701 #ifdef DEBUG_ITEMS_PAINT 702 QPointF oldPos = pos;
707 pos += QPointF( static_cast<qreal>( siz.width() ) / 2.0,
708 static_cast<qreal>( siz.height() )/ 2.0 );
710 diagram->
paintMarker( painter, marker, brush, pen, pos.toPoint(), siz );
712 #ifdef DEBUG_ITEMS_PAINT 713 const QPen oldPen( painter->pen() );
714 painter->setPen( Qt::red );
715 painter->drawRect( QRect( oldPos.toPoint(), siz ) );
716 painter->setPen( oldPen );
724 Qt::Alignment legendLineSymbolAlignment,
725 Qt::Alignment alignment )
727 , mDiagram( diagram )
730 , mLegendLineSymbolAlignment(legendLineSymbolAlignment)
733 if ( pen.width() < 2 )
769 return QSize( mLength, mPen.width() + 2 );
775 if (mLegendLineSymbolAlignment == legendLineSymbolAlignment)
783 return mLegendLineSymbolAlignment;
788 paintIntoRect( painter, mRect, mPen, mLegendLineSymbolAlignment );
795 Qt::Alignment lineAlignment)
797 if ( ! rect.isValid() )
800 const QPen oldPen = painter->pen();
803 if (lineAlignment == Qt::AlignTop)
805 else if (lineAlignment == Qt::AlignBottom)
808 y = rect.center().y();
810 painter->drawLine( QPointF( rect.left(), y ),
811 QPointF( rect.right(), y ) );
812 painter->setPen( oldPen );
822 const QBrush& markerBrush,
823 const QPen& markerPen,
824 Qt::Alignment alignment )
826 , mDiagram( diagram )
827 , mLineLength( lineLength )
828 , mLinePen( linePen )
829 , mMarkerOffs( markerOffs )
831 , mMarkerBrush( markerBrush )
832 , mMarkerPen( markerPen )
868 const QSize lineSize( mLineLength, mLinePen.width() + 2 );
869 return lineSize.expandedTo( mMarker.
markerSize().toSize() );
879 QPoint( mRect.x()+mMarkerOffs, mRect.y() ),
880 QSize( mMarker.
markerSize().toSize().width(), mRect.height() ) );
882 painter, r, mDiagram, mMarker, mMarkerBrush, mMarkerPen );
886 bool layoutIsAtTopPosition, QHBoxLayout *rightLeftLayout,
887 bool layoutIsAtLeftPosition, QVBoxLayout *topBottomLayout )
889 , mLayoutIsAtTopPosition( layoutIsAtTopPosition )
890 , mRightLeftLayout( rightLeftLayout )
891 , mLayoutIsAtLeftPosition( layoutIsAtLeftPosition )
892 , mTopBottomLayout( topBottomLayout )
930 const bool hasSimpleBrush = (
934 ba.brush().gradient() == 0 );
937 commonBrush = hasSimpleBrush ? ba.
brush() : QBrush();
939 if ( ! hasSimpleBrush || ba.brush() != commonBrush )
941 commonBrush = QBrush();
951 int topBottomOverlap = 0;
952 if ( mTopBottomLayout ) {
953 for (
int i = 0; i < mTopBottomLayout->count(); ++i) {
957 topBottomOverlap = qMax( topBottomOverlap,
965 int leftRightOverlap = 0;
966 if ( mRightLeftLayout ) {
967 for (
int i = 0; i < mRightLeftLayout->count(); ++i) {
971 leftRightOverlap = qMax( leftRightOverlap,
978 if ( topBottomOverlap > 0 && leftRightOverlap > 0 )
979 mCommonBrush = commonBrush;
981 mCommonBrush = QBrush();
982 mCachedSize = QSize( topBottomOverlap, leftRightOverlap );
990 if (
mParentLayout && mRect.isValid() && mCachedSize.isValid() &&
991 mCommonBrush.style() != Qt::NoBrush )
993 QPoint p1( mRect.topLeft() );
994 QPoint p2( mRect.bottomRight() );
995 if ( mLayoutIsAtLeftPosition )
999 if ( mLayoutIsAtTopPosition ) {
1000 p1.ry() += mCachedSize.height() -
mParentLayout->spacing() - 1;
1003 p2.ry() -= mCachedSize.height() -
mParentLayout->spacing() - 1;
1008 const QPoint oldBrushOrigin( painter->brushOrigin() );
1009 const QBrush oldBrush( painter->brush() );
1010 const QPen oldPen( painter->pen() );
1011 const QPointF newTopLeft( painter->deviceMatrix().map( p1 ) );
1012 painter->setBrushOrigin( newTopLeft );
1013 painter->setBrush( mCommonBrush );
1014 painter->setPen( Qt::NoPen );
1015 painter->drawRect( QRect( p1, p2 ) );
1016 painter->setBrushOrigin( oldBrushOrigin );
1017 painter->setBrush( oldBrush );
1018 painter->setPen( oldPen );
1023 if ( !mRect.isValid() )
1026 painter->drawRect( mRect );
1027 painter->drawLine( QPointF( mRect.topLeft(), mRect.bottomRight() ) );
1028 painter->drawLine( QPointF( mRect.topRight(), mRect.bottomLeft() ) );
MeasureOrientation
Measure orientation mode: the way how the absolute value of a KDChart::Measure is determined during K...
bool isEmpty() const override
QSize maximumSize() const override
QSize sizeHint() const override
Qt::Orientations expandingDirections() const override
pure virtual in QLayoutItem
Project global class providing some enums needed both by KDChartParams and by KDChartCustomBox.
LineLayoutItem(AbstractDiagram *diagram, int length, const QPen &pen, Qt::Alignment mLegendLineSymbolAlignment, Qt::Alignment alignment=0)
void setGeometry(const QRect &r) override
QSize minimumSize() const override
QSize maximumSize() const override
QSize maximumSize() const override
void setLegendLineSymbolAlignment(Qt::Alignment legendLineSymbolAlignment)
An area in the chart with a background, a frame, etc.
void setGeometry(const QRect &r) override
QSize sizeHint() const override
Qt::Orientations expandingDirections() const override
BackgroundAttributes backgroundAttributes() const
void setGeometry(const QRect &r) override
pure virtual in QLayoutItem
void setAutoReferenceArea(const QObject *area)
void setTextAlignment(Qt::Alignment)
QTextDocument * textDocument() const
QSize minimumSize() const override
QPainter * painter() const
void paint(QPainter *) override
QSize maximumSize() const override
LineWithMarkerLayoutItem(AbstractDiagram *diagram, int lineLength, const QPen &linePen, int markerOffs, const MarkerAttributes &marker, const QBrush &markerBrush, const QPen &markerPen, Qt::Alignment alignment=0)
Qt::Orientations expandingDirections() const override
Layout item showing a text.
TextAttributes textAttributes() const
Returns the text attributes to be used for this item.
QSize sizeHint() const override
pure virtual in QLayoutItem
virtual void setParentWidget(QWidget *widget)
Inform the item about its widget: This enables the item, to trigger that widget's update...
QSize maximumSize() const override
virtual int leftOverlap(bool doNotRecalculate=false) const
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
Qt::Orientations expandingDirections() const override
pure virtual in QLayoutItem
void paint(QPainter *) override
const QObject * autoReferenceArea() const
virtual QSize sizeHintUnrotated() const
QSize minimumSize() const override
pure virtual in QLayoutItem
Qt::Orientations expandingDirections() const override
QRect geometry() const override
AutoSpacerLayoutItem(bool layoutIsAtTopPosition, QHBoxLayout *rightLeftLayout, bool layoutIsAtLeftPosition, QVBoxLayout *topBottomLayout)
static QPaintDevice * paintDevice()
Return the paint device to use for calculating font metrics.
QRect geometry() const override
QSize minimumSize() const override
bool isEmpty() const override
virtual int bottomOverlap(bool doNotRecalculate=false) const
This is called at layout time by KDChart:AutoSpacerLayoutItem::sizeHint().
QSize sizeHint() const override
QSize sizeHint() const override
pure virtual in QLayoutItem
QRect geometry() const override
HorizontalLineLayoutItem()
QRect geometry() const override
QSize minimumSize() const override
QRectF rotatedRect(const QRectF &rect, qreal rotation)
virtual bool intersects(const TextLayoutItem &other, const QPointF &myPos, const QPointF &otherPos) const
AbstractDiagram defines the interface for diagram classes.
QRect geometry() const override
void setText(const QString &text)
Qt::Alignment textAlignment() const
void paint(QPainter *painter) override
QSize sizeHint() const override
QSize maximumSize() const override
pure virtual in QLayoutItem
void setAutoReferenceArea(const QObject *area)
virtual void paintMarker(QPainter *painter, const MarkerAttributes &markerAttributes, const QBrush &brush, const QPen &, const QPointF &point, const QSizeF &size)
virtual int rightOverlap(bool doNotRecalculate=false) const
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
virtual Qt::Alignment legendLineSymbolAlignment() const
bool isEmpty() const override
void setGeometry(const QRect &r) override
virtual void paintAll(QPainter &painter)
Default impl: just call paint.
void setGeometry(const QRect &r) override
pure virtual in QLayoutItem
virtual QFont realFont() const
QSize minimumSize() const override
QRect geometry() const override
static void paintIntoRect(QPainter *painter, const QRect &rect, const QPen &pen, Qt::Alignment lineAlignment)
Base class for all layout items of KD Chart.
const QObject * autoReferenceArea() const
QSize sizeHint() const override
void paint(QPainter *) override
void paint(QPainter *) override
virtual void paint(QPainter *)=0
void setTextAttributes(const TextAttributes &a)
Use this to specify the text attributes to be used for this item.
void setGeometry(const QRect &r) override
QSizeF markerSize() const
static void updateCommonBrush(QBrush &commonBrush, bool &bStart, const KDChart::AbstractArea &area)
static void paintIntoRect(QPainter *painter, const QRect &rect, AbstractDiagram *diagram, const MarkerAttributes &marker, const QBrush &brush, const QPen &pen)
virtual qreal realFontSize() const
Stores information about painting diagrams.
QSize minimumSize() const override
QSize maximumSize() const override
MarkerLayoutItem(AbstractDiagram *diagram, const MarkerAttributes &marker, const QBrush &brush, const QPen &pen, Qt::Alignment alignment=0)
Class only listed here to document inheritance of some KDChart classes.
void paint(QPainter *) override
virtual int topOverlap(bool doNotRecalculate=false) const
This is called at layout time by KDChart::AutoSpacerLayoutItem::sizeHint().
~TextBubbleLayoutItem() override
virtual void sizeHintChanged() const
Report changed size hint: ask the parent widget to recalculate the layout.
void paint(QPainter *) override
bool isEmpty() const override
A set of attributes controlling the appearance of data set markers.
void setText(const QString &text)
void setGeometry(const QRect &r) override
QSize minimumSize() const override
pure virtual in QLayoutItem
virtual int marginWidth() const
QSize maximumSize() const override
pure virtual in QLayoutItem
QRect geometry() const override
pure virtual in QLayoutItem
bool isEmpty() const override
Class only listed here to document inheritance of some KDChart classes.
static QPen scalePen(const QPen &pen)
Qt::Orientations expandingDirections() const override
TextAttributes textAttributes() const
bool isEmpty() const override
pure virtual in QLayoutItem
void setTextAttributes(const TextAttributes &a)
Measure minimalFontSize() const
void paint(QPainter *) override
Qt::Orientations expandingDirections() const override
FrameAttributes frameAttributes() const
qreal calculatedFontSize(const QSizeF &referenceSize, KDChartEnums::MeasureOrientation autoReferenceOrientation) const
Returns the font size that is used at drawing time.
bool isEmpty() const override
pure virtual in QLayoutItem
virtual void paintCtx(PaintContext *context)
Default impl: Paint the complete item using its layouted position and size.
QRect geometry() const override
pure virtual in QLayoutItem
void setGeometry(const QRect &r) override
QPolygon boundingPolygon() const
A set of text attributes.
QSize sizeHint() const override
Set of attributes usable for background pixmaps.
bool isEmpty() const override
Qt::Orientations expandingDirections() const override