9#include "KChartLayoutItems.h"
11#include "KTextDocument.h"
12#include "KChartAbstractArea.h"
13#include "KChartAbstractDiagram.h"
14#include "KChartBackgroundAttributes.h"
15#include "KChartFrameAttributes.h"
16#include "KChartPaintContext.h"
17#include "KChartPainterSaver_p.h"
18#include "KChartPrintingParameters.h"
19#include "KChartMath_p.h"
22#include <QTextBlockFormat>
23#include <QTextDocumentFragment>
24#include <QAbstractTextDocumentLayout>
27#include <QCoreApplication>
28#include <QApplication>
48 paint( context->painter() );
56 if ( mParent->layout() )
57 mParent->layout()->invalidate();
63KChart::TextBubbleLayoutItem::TextBubbleLayoutItem(
const QString& text,
69 m_text( new
TextLayoutItem( text, attributes, area, orientation, alignment ) )
73KChart::TextBubbleLayoutItem::TextBubbleLayoutItem()
74 : AbstractLayoutItem(
Qt::AlignLeft ),
75 m_text( new TextLayoutItem() )
79KChart::TextBubbleLayoutItem::~TextBubbleLayoutItem()
84void KChart::TextBubbleLayoutItem::setAutoReferenceArea(
const QObject* area )
86 m_text->setAutoReferenceArea( area );
89const QObject* KChart::TextBubbleLayoutItem::autoReferenceArea()
const
91 return m_text->autoReferenceArea();
94void KChart::TextBubbleLayoutItem::setText(
const QString& text )
96 m_text->setText( text );
99QString KChart::TextBubbleLayoutItem::text()
const
101 return m_text->text();
104void KChart::TextBubbleLayoutItem::setTextAttributes(
const TextAttributes& a )
106 m_text->setTextAttributes( a );
111 return m_text->textAttributes();
114bool KChart::TextBubbleLayoutItem::isEmpty()
const
116 return m_text->isEmpty();
121 return m_text->expandingDirections();
124QSize KChart::TextBubbleLayoutItem::maximumSize()
const
126 const int border = borderWidth();
127 return m_text->maximumSize() +
QSize( 2 * border, 2 * border );
130QSize KChart::TextBubbleLayoutItem::minimumSize()
const
132 const int border = borderWidth();
133 return m_text->minimumSize() +
QSize( 2 * border, 2 * border );
136QSize KChart::TextBubbleLayoutItem::sizeHint()
const
138 const int border = borderWidth();
139 return m_text->sizeHint() +
QSize( 2 * border, 2 * border );
142void KChart::TextBubbleLayoutItem::setGeometry(
const QRect& r )
144 const int border = borderWidth();
145 m_text->setGeometry( r.
adjusted( border, border, -border, -border ) );
148QRect KChart::TextBubbleLayoutItem::geometry()
const
150 const int border = borderWidth();
151 return m_text->geometry().adjusted( -border, -border, border, border );
154void KChart::TextBubbleLayoutItem::paint(
QPainter* painter )
156 const QPen oldPen = painter->
pen();
161 painter->
setPen( oldPen );
163 m_text->paint( painter );
166int KChart::TextBubbleLayoutItem::borderWidth()
const
171KChart::TextLayoutItem::TextLayoutItem(
const QString& text,
176 : AbstractLayoutItem( alignment )
178 , mTextAlignment( alignment )
179 , mAttributes( attributes )
180 , mAutoReferenceArea( area )
181 , mAutoReferenceOrientation( orientation )
183 , cachedFontSize( 0.0 )
184 , cachedFont( mAttributes.font() )
188KChart::TextLayoutItem::TextLayoutItem()
193 , mAutoReferenceArea( nullptr )
194 , mAutoReferenceOrientation(
KChartEnums::MeasureOrientationHorizontal )
196 , cachedFontSize( 0.0 )
197 , cachedFont( mAttributes.font() )
202void KChart::TextLayoutItem::setAutoReferenceArea(
const QObject* area )
204 mAutoReferenceArea = area;
205 cachedSizeHint =
QSize();
209const QObject* KChart::TextLayoutItem::autoReferenceArea()
const
211 return mAutoReferenceArea;
214void KChart::TextLayoutItem::setText(
const QString & text)
217 cachedSizeHint =
QSize();
223QString KChart::TextLayoutItem::text()
const
228void KChart::TextLayoutItem::setTextAlignment(
Qt::Alignment alignment)
230 if ( mTextAlignment == alignment )
232 mTextAlignment = alignment;
239 return mTextAlignment;
245 cachedFont = a.
font();
246 cachedSizeHint =
QSize();
299qreal KChart::TextLayoutItem::fitFontSizeToGeometry()
const
301 QFont f = realFont();
303 qreal result = origResult;
304 const qreal minSize = mAttributes.minimalFontSize().value();
305 const QSize mySize = geometry().size();
312 const QSizeF textSize = rotatedRect( fm.boundingRect( mText ), mAttributes.rotation() ).
normalized().
size();
319 if ( minSize > 0 && result < minSize ) {
321 }
else if ( result <= 0.0 ) {
329qreal KChart::TextLayoutItem::realFontSize()
const
331 return mAttributes.calculatedFontSize( mAutoReferenceArea, mAutoReferenceOrientation );
334bool KChart::TextLayoutItem::maybeUpdateRealFont()
const
336 const qreal fntSiz = realFontSize();
337 const bool doUpdate = !cachedSizeHint.isValid() || cachedFontSize != fntSiz;
339 if ( doUpdate && fntSiz > 0.0 ) {
340 cachedFontSize = fntSiz;
341 cachedFont.setPointSizeF( fntSiz );
346QFont KChart::TextLayoutItem::realFont()
const
348 maybeUpdateRealFont();
352QPolygon KChart::TextLayoutItem::boundingPolygon()
const
355 return mCachedBoundingPolygon;
358bool KChart::TextLayoutItem::intersects(
const TextLayoutItem& other,
const QPointF& myPos,
const QPointF& otherPos )
const
363bool KChart::TextLayoutItem::intersects(
const TextLayoutItem& other,
const QPoint& myPos,
const QPoint& otherPos )
const
365 QRegion myRegion( boundingPolygon().translated( myPos - otherPos ) );
366 QRegion otherRegion( other.boundingPolygon() );
368 return myRegion.intersects( otherRegion );
374 if ( maybeUpdateRealFont() || mAttributes.rotation() || !cachedSizeHint.isValid() ) {
375 const QSize newSizeHint( calcSizeHint( cachedFont ) );
376 Q_ASSERT( newSizeHint.
isValid() );
377 if ( newSizeHint != cachedSizeHint ) {
378 cachedSizeHint = newSizeHint;
382 return cachedSizeHint;
385QSize KChart::TextLayoutItem::sizeHintUnrotated()
const
387 maybeUpdateRealFont();
388 return unrotatedSizeHint( cachedFont );
395QSize KChart::TextLayoutItem::unrotatedTextSize(
QFont fnt )
const
397 if ( fnt ==
QFont() ) {
402 QRect veryLarge( 0, 0, 100000, 100000 );
407int KChart::TextLayoutItem::marginWidth()
const
409 return marginWidth( unrotatedTextSize() );
412int KChart::TextLayoutItem::marginWidth(
const QSize& textSize )
const
416 textSize.
height() * 2 / 3 );
419QSize KChart::TextLayoutItem::unrotatedSizeHint(
const QFont& fnt )
const
421 QSize ret = unrotatedTextSize( fnt );
422 const int margin = marginWidth( ret );
423 ret +=
QSize( margin, margin );
427QSize KChart::TextLayoutItem::calcSizeHint(
const QFont& font )
const
429 const QSize size = unrotatedSizeHint( font );
431 if ( !mAttributes.rotation() ) {
432 mCachedBoundingPolygon.resize( 4 );
435 mCachedBoundingPolygon[ 0 ] = topLeft;
436 mCachedBoundingPolygon[ 1 ] = topLeft +
QPoint( size.
width(), 0 );
438 mCachedBoundingPolygon[ 3 ] = topLeft +
QPoint( 0, size.
height() );
442 const QRect rect( topLeft, size );
444 t.
rotate( mAttributes.rotation() );
450void KChart::TextLayoutItem::paint(
QPainter* painter )
452 if ( !mRect.isValid() ) {
455 const PainterSaver painterSaver( painter );
456 QFont f = realFont();
457 if ( mAttributes.autoShrink() ) {
462 QSize innerSize = unrotatedTextSize();
466 painter->
rotate( mAttributes.rotation() );
467#ifdef DEBUG_ITEMS_PAINT
472 painter->
setPen( PrintingParameters::scalePen( mAttributes.pen() ) );
480 paintcontext.clip = rect;
483 painter->
drawText( rect, mTextAlignment, mText );
487KChart::HorizontalLineLayoutItem::HorizontalLineLayoutItem()
492Qt::Orientations KChart::HorizontalLineLayoutItem::expandingDirections()
const
497QRect KChart::HorizontalLineLayoutItem::geometry()
const
502bool KChart::HorizontalLineLayoutItem::isEmpty()
const
507QSize KChart::HorizontalLineLayoutItem::maximumSize()
const
509 return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
512QSize KChart::HorizontalLineLayoutItem::minimumSize()
const
514 return QSize( 0, 0 );
517void KChart::HorizontalLineLayoutItem::setGeometry(
const QRect& r )
522QSize KChart::HorizontalLineLayoutItem::sizeHint()
const
524 return QSize( -1, 3 );
528void KChart::HorizontalLineLayoutItem::paint(
QPainter* painter )
530 if ( !mRect.isValid() )
534 QPointF( mRect.right(), mRect.center().y() ) );
538KChart::VerticalLineLayoutItem::VerticalLineLayoutItem()
548QRect KChart::VerticalLineLayoutItem::geometry()
const
553bool KChart::VerticalLineLayoutItem::isEmpty()
const
558QSize KChart::VerticalLineLayoutItem::maximumSize()
const
560 return QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
563QSize KChart::VerticalLineLayoutItem::minimumSize()
const
565 return QSize( 0, 0 );
568void KChart::VerticalLineLayoutItem::setGeometry(
const QRect& r )
573QSize KChart::VerticalLineLayoutItem::sizeHint()
const
575 return QSize( 3, -1 );
579void KChart::VerticalLineLayoutItem::paint(
QPainter* painter )
581 if ( !mRect.isValid() )
585 QPointF( mRect.center().x(), mRect.bottom() ) );
591 const MarkerAttributes& marker,
594 : AbstractLayoutItem( alignment )
595 , mDiagram( diagram )
607QRect KChart::MarkerLayoutItem::geometry()
const
612bool KChart::MarkerLayoutItem::isEmpty()
const
617QSize KChart::MarkerLayoutItem::maximumSize()
const
622QSize KChart::MarkerLayoutItem::minimumSize()
const
627void KChart::MarkerLayoutItem::setGeometry(
const QRect& r )
632QSize KChart::MarkerLayoutItem::sizeHint()
const
635 return mMarker.markerSize().toSize();
638void KChart::MarkerLayoutItem::paint(
QPainter* painter )
640 paintIntoRect( painter, mRect, mDiagram, mMarker, mBrush, mPen );
643void KChart::MarkerLayoutItem::paintIntoRect(
646 AbstractDiagram* diagram,
647 const MarkerAttributes& marker,
656 const QSize siz = marker.markerSize().toSize();
659 static_cast<qreal
>(( rect.
height() - siz.
height()) / 2.0 ) );
661#ifdef DEBUG_ITEMS_PAINT
667 pos +=
QPointF(
static_cast<qreal
>( siz.
width() ) / 2.0,
668 static_cast<qreal
>( siz.
height() )/ 2.0 );
670 diagram->paintMarker( painter, marker, brush, pen, pos.
toPoint(), siz );
672#ifdef DEBUG_ITEMS_PAINT
673 const QPen oldPen( painter->
pen() );
676 painter->
setPen( oldPen );
686 : AbstractLayoutItem( alignment )
687 , mDiagram( diagram )
690 , mLegendLineSymbolAlignment(legendLineSymbolAlignment)
693 if ( pen.
width() < 2 )
702QRect KChart::LineLayoutItem::geometry()
const
707bool KChart::LineLayoutItem::isEmpty()
const
712QSize KChart::LineLayoutItem::maximumSize()
const
717QSize KChart::LineLayoutItem::minimumSize()
const
722void KChart::LineLayoutItem::setGeometry(
const QRect& r )
727QSize KChart::LineLayoutItem::sizeHint()
const
729 return QSize( mLength, mPen.width() + 2 );
733void KChart::LineLayoutItem::setLegendLineSymbolAlignment(
Qt::Alignment legendLineSymbolAlignment)
735 if (mLegendLineSymbolAlignment == legendLineSymbolAlignment)
738 mLegendLineSymbolAlignment = legendLineSymbolAlignment;
741Qt::Alignment KChart::LineLayoutItem::legendLineSymbolAlignment()
const
743 return mLegendLineSymbolAlignment;
746void KChart::LineLayoutItem::paint(
QPainter* painter )
748 paintIntoRect( painter, mRect, mPen, mLegendLineSymbolAlignment );
751void KChart::LineLayoutItem::paintIntoRect(
760 const QPen oldPen = painter->
pen();
761 painter->
setPen( PrintingParameters::scalePen( pen ) );
772 painter->
setPen( oldPen );
776KChart::LineWithMarkerLayoutItem::LineWithMarkerLayoutItem(
781 const MarkerAttributes& marker,
782 const QBrush& markerBrush,
783 const QPen& markerPen,
785 : AbstractLayoutItem( alignment )
786 , mDiagram( diagram )
787 , mLineLength( lineLength )
788 , mLinePen( linePen )
789 , mMarkerOffs( markerOffs )
791 , mMarkerBrush( markerBrush )
792 , mMarkerPen( markerPen )
796Qt::Orientations KChart::LineWithMarkerLayoutItem::expandingDirections()
const
801QRect KChart::LineWithMarkerLayoutItem::geometry()
const
806bool KChart::LineWithMarkerLayoutItem::isEmpty()
const
811QSize KChart::LineWithMarkerLayoutItem::maximumSize()
const
816QSize KChart::LineWithMarkerLayoutItem::minimumSize()
const
821void KChart::LineWithMarkerLayoutItem::setGeometry(
const QRect& r )
826QSize KChart::LineWithMarkerLayoutItem::sizeHint()
const
828 const QSize lineSize( mLineLength, mLinePen.width() + 2 );
829 return lineSize.expandedTo( mMarker.markerSize().toSize() );
832void KChart::LineWithMarkerLayoutItem::paint(
QPainter* painter )
835 LineLayoutItem::paintIntoRect( painter, mRect, mLinePen,
Qt::AlignCenter );
839 QPoint( mRect.x()+mMarkerOffs, mRect.y() ),
840 QSize( mMarker.markerSize().toSize().width(), mRect.height() ) );
841 MarkerLayoutItem::paintIntoRect(
842 painter, r, mDiagram, mMarker, mMarkerBrush, mMarkerPen );
845KChart::AutoSpacerLayoutItem::AutoSpacerLayoutItem(
846 bool layoutIsAtTopPosition,
QHBoxLayout *rightLeftLayout,
847 bool layoutIsAtLeftPosition,
QVBoxLayout *topBottomLayout )
849 , mLayoutIsAtTopPosition( layoutIsAtTopPosition )
850 , mRightLeftLayout( rightLeftLayout )
851 , mLayoutIsAtLeftPosition( layoutIsAtLeftPosition )
852 , mTopBottomLayout( topBottomLayout )
861QRect KChart::AutoSpacerLayoutItem::geometry()
const
866bool KChart::AutoSpacerLayoutItem::isEmpty()
const
871QSize KChart::AutoSpacerLayoutItem::maximumSize()
const
876QSize KChart::AutoSpacerLayoutItem::minimumSize()
const
881void KChart::AutoSpacerLayoutItem::setGeometry(
const QRect& r )
890 const bool hasSimpleBrush = (
891 ! area.frameAttributes().isVisible() &&
893 ba.pixmapMode() == KChart::BackgroundAttributes::BackgroundPixmapModeNone &&
894 ba.brush().gradient() ==
nullptr );
897 commonBrush = hasSimpleBrush ? ba.brush() :
QBrush();
899 if ( ! hasSimpleBrush || ba.brush() != commonBrush )
906QSize KChart::AutoSpacerLayoutItem::sizeHint()
const
911 int topBottomOverlap = 0;
912 if ( mTopBottomLayout ) {
913 for (
int i = 0; i < mTopBottomLayout->count(); ++i) {
914 AbstractArea* area =
dynamic_cast<AbstractArea*
>(mTopBottomLayout->itemAt(i));
917 topBottomOverlap = qMax( topBottomOverlap,
918 mLayoutIsAtLeftPosition ? area->rightOverlap()
919 : area->leftOverlap() );
920 updateCommonBrush( commonBrush, bStart, *area );
925 int leftRightOverlap = 0;
926 if ( mRightLeftLayout ) {
927 for (
int i = 0; i < mRightLeftLayout->count(); ++i) {
928 AbstractArea* area =
dynamic_cast<AbstractArea*
>(mRightLeftLayout->itemAt(i));
931 leftRightOverlap = qMax( leftRightOverlap,
932 mLayoutIsAtTopPosition ? area->bottomOverlap()
933 : area->topOverlap() );
934 updateCommonBrush( commonBrush, bStart, *area );
938 if ( topBottomOverlap > 0 && leftRightOverlap > 0 )
939 mCommonBrush = commonBrush;
942 mCachedSize =
QSize( topBottomOverlap, leftRightOverlap );
948void KChart::AutoSpacerLayoutItem::paint(
QPainter* painter )
950 if ( mParentLayout && mRect.isValid() && mCachedSize.isValid() &&
953 QPoint p1( mRect.topLeft() );
954 QPoint p2( mRect.bottomRight() );
955 if ( mLayoutIsAtLeftPosition )
956 p1.rx() += mCachedSize.width() - mParentLayout->spacing();
958 p2.rx() -= mCachedSize.width() - mParentLayout->spacing();
959 if ( mLayoutIsAtTopPosition ) {
960 p1.ry() += mCachedSize.height() - mParentLayout->spacing() - 1;
963 p2.ry() -= mCachedSize.height() - mParentLayout->spacing() - 1;
970 const QPen oldPen( painter->
pen() );
978 painter->
setPen( oldPen );
983 if ( !mRect.isValid() )
Project global class providing some enums needed both by KChartParams and by KChartCustomBox.
MeasureOrientation
Measure orientation mode: the way how the absolute value of a KChart::Measure is determined during KC...
An area in the chart with a background, a frame, etc.
AbstractDiagram defines the interface for diagram classes.
Base class for all layout items of KChart.
virtual void setParentWidget(QWidget *widget)
Inform the item about its widget: This enables the item, to trigger that widget's update,...
virtual void paintAll(QPainter &painter)
Default impl: just call paint.
virtual void sizeHintChanged() const
Report changed size hint: ask the parent widget to recalculate the layout.
virtual void paintCtx(PaintContext *context)
Default impl: Paint the complete item using its layouted position and size.
Set of attributes usable for background pixmaps.
static QPaintDevice * paintDevice()
Return the paint device to use for calculating font metrics.
Stores information about painting diagrams.
A set of text attributes.
Layout item showing a text.
QSize sizeHint() const override
pure virtual in QLayoutItem
Qt::Orientations expandingDirections() const override
pure virtual in QLayoutItem
void setTextAttributes(const TextAttributes &a)
Use this to specify the text attributes to be used for this item.
QRect geometry() const override
pure virtual in QLayoutItem
bool isEmpty() const override
pure virtual in QLayoutItem
QSize minimumSize() const override
pure virtual in QLayoutItem
void setGeometry(const QRect &r) override
pure virtual in QLayoutItem
TextAttributes textAttributes() const
Returns the text attributes to be used for this item.
QSize maximumSize() const override
pure virtual in QLayoutItem
virtual void draw(QPainter *painter, const PaintContext &context)=0
void postEvent(QObject *receiver, QEvent *event, int priority)
qreal pointSizeF() const const
void setPointSizeF(qreal pointSize)
const QBrush & brush() const const
QPoint brushOrigin() const const
void drawLine(const QLine &line)
void drawRect(const QRect &rectangle)
void drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
void drawText(const QPoint &position, const QString &text)
const QPen & pen() const const
void setBrush(Qt::BrushStyle style)
void setBrushOrigin(const QPoint &position)
void setFont(const QFont &font)
void setPen(Qt::PenStyle style)
void translate(const QPoint &offset)
QPoint toPoint() const const
QRect boundingRect() const const
QRect adjusted(int dx1, int dy1, int dx2, int dy2) const const
QPoint center() const const
bool isValid() const const
QPoint topLeft() const const
QPointF center() const const
QRectF normalized() const const
QSizeF size() const const
void translate(const QPointF &offset)
bool isNull() const const
bool isValid() const const
qreal height() const const
qreal width() const const
QAbstractTextDocumentLayout * documentLayout() const const
void setPageSize(const QSizeF &size)
void setHtml(const QString &html)