1 /*
2  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB.  All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "KChartAbstractArea.h"
21 #include "KChartAbstractArea_p.h"
22 
23 #include "KChartMath_p.h"
24 
25 #include <qglobal.h>
26 
27 #include <QPainter>
28 #include <QRect>
29 
30 
31 using namespace KChart;
32 
33 #define d (d_func())
34 
Private()35 AbstractArea::Private::Private() :
36     AbstractAreaBase::Private()
37 {
38     // this bloc left empty intentionally
39 }
40 
41 
~Private()42 AbstractArea::Private::~Private()
43 {
44     // this bloc left empty intentionally
45 }
46 
47 
AbstractArea()48 AbstractArea::AbstractArea()
49     : QObject()
50     , KChart::AbstractAreaBase()
51     , KChart::AbstractLayoutItem()
52 {
53     init();
54 }
55 
~AbstractArea()56 AbstractArea::~AbstractArea()
57 {
58     // this bloc left empty intentionally
59 }
60 
61 
init()62 void AbstractArea::init()
63 {
64     d->amountOfLeftOverlap = 0;
65     d->amountOfRightOverlap = 0;
66     d->amountOfTopOverlap = 0;
67     d->amountOfBottomOverlap = 0;
68 }
69 
70 
leftOverlap(bool doNotRecalculate) const71 int AbstractArea::leftOverlap( bool doNotRecalculate ) const
72 {
73     // Re-calculate the sizes,
74     // so we also get the amountOf..Overlap members set newly:
75     if ( ! doNotRecalculate )
76         sizeHint();
77     return d->amountOfLeftOverlap;
78 }
rightOverlap(bool doNotRecalculate) const79 int AbstractArea::rightOverlap( bool doNotRecalculate ) const
80 {
81     // Re-calculate the sizes,
82     // so we also get the amountOf..Overlap members set newly:
83     if ( ! doNotRecalculate )
84         sizeHint();
85     return d->amountOfRightOverlap;
86 }
topOverlap(bool doNotRecalculate) const87 int AbstractArea::topOverlap( bool doNotRecalculate ) const
88 {
89     // Re-calculate the sizes,
90     // so we also get the amountOf..Overlap members set newly:
91     if ( ! doNotRecalculate )
92         sizeHint();
93     return d->amountOfTopOverlap;
94 }
bottomOverlap(bool doNotRecalculate) const95 int AbstractArea::bottomOverlap( bool doNotRecalculate ) const
96 {
97     // Re-calculate the sizes,
98     // so we also get the amountOf..Overlap members set newly:
99     if ( ! doNotRecalculate )
100         sizeHint();
101     return d->amountOfBottomOverlap;
102 }
103 
104 
paintIntoRect(QPainter & painter,const QRect & rect)105 void AbstractArea::paintIntoRect( QPainter& painter, const QRect& rect )
106 {
107     const QRect oldGeometry( geometry() );
108     if ( oldGeometry != rect )
109         setGeometry( rect );
110     painter.translate( rect.left(), rect.top() );
111     paintAll( painter );
112     painter.translate( -rect.left(), -rect.top() );
113     if ( oldGeometry != rect )
114         setGeometry( oldGeometry );
115 }
116 
paintAll(QPainter & painter)117 void AbstractArea::paintAll( QPainter& painter )
118 {
119     // Paint the background and frame
120     const QRect overlappingArea( geometry().adjusted( -d->amountOfLeftOverlap, -d->amountOfTopOverlap,
121                                                       d->amountOfRightOverlap, d->amountOfBottomOverlap ) );
122     paintBackground( painter, overlappingArea );
123     paintFrame( painter, overlappingArea );
124 
125     // temporarily adjust the widget size, to be sure all content gets calculated
126     // to fit into the inner rectangle
127     const QRect oldGeometry( areaGeometry() );
128     QRect inner( innerRect() );
129     inner.moveTo( oldGeometry.left() + inner.left(), oldGeometry.top() + inner.top() );
130     const bool needAdjustGeometry = oldGeometry != inner;
131     if ( needAdjustGeometry ) {
132         // don't notify others of this change for internal purposes
133         bool prevSignalBlocked = signalsBlocked();
134         blockSignals( true );
135         setGeometry( inner );
136         blockSignals( prevSignalBlocked );
137     }
138     paint( &painter );
139     if ( needAdjustGeometry ) {
140         bool prevSignalBlocked = signalsBlocked();
141         blockSignals( true );
142         setGeometry( oldGeometry );
143         blockSignals( prevSignalBlocked );
144     }
145     //qDebug() << "AbstractAreaWidget::paintAll() done.";
146 }
147 
areaGeometry() const148 QRect AbstractArea::areaGeometry() const
149 {
150     return geometry();
151 }
152 
positionHasChanged()153 void AbstractArea::positionHasChanged()
154 {
155     Q_EMIT positionChanged( this );
156 }
157 
158