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 #ifndef KCHARTCHART_P_H
21 #define KCHARTCHART_P_H
22 
23 //
24 //  W A R N I N G
25 //  -------------
26 //
27 // This file is not part of the KD Chart API.  It exists purely as an
28 // implementation detail.  This header file may change from version to
29 // version without notice, or even be removed.
30 //
31 // We mean it.
32 //
33 
34 #include <QObject>
35 #include <QHBoxLayout>
36 #include <QVBoxLayout>
37 
38 #include "KChartChart.h"
39 #include "KChartAbstractArea.h"
40 #include "KChartTextArea.h"
41 #include "KChartFrameAttributes.h"
42 #include "KChartBackgroundAttributes.h"
43 #include "KChartLayoutItems.h"
44 #include "KChartMath_p.h"
45 
46 
47 namespace KChart {
48 
49 class AbstractAreaWidget;
50 class CartesianAxis;
51 
52 /*
53   struct PlaneInfo can't be declared inside Chart::Private, otherwise MSVC.net says:
54   qhash.h(195) : error C2248: 'KChart::Chart::Private' : cannot access protected class declared in class 'KChart::Chart'
55   KChartChart_p.h(58) : see declaration of 'KChart::Chart::Private'
56   KChartChart.h(61) : see declaration of 'KChart::Chart'
57   KChartChart.cpp(262) : see reference to class template instantiation 'QHash<Key,T>' being compiled, with
58             Key=KChart::AbstractCoordinatePlane *,
59             T=KChart::Chart::Private::PlaneInfo
60 */
61 /**
62  * \internal
63  */
64 struct PlaneInfo {
PlaneInfoPlaneInfo65     PlaneInfo()
66         : referencePlane( nullptr ),
67           horizontalOffset( 1 ),
68           verticalOffset( 1 ),
69           gridLayout( nullptr ),
70           topAxesLayout( nullptr ),
71           bottomAxesLayout( nullptr ),
72           leftAxesLayout( nullptr ),
73           rightAxesLayout( nullptr )
74     {}
75     AbstractCoordinatePlane *referencePlane;
76     int horizontalOffset;
77     int verticalOffset;
78     QGridLayout* gridLayout;
79     QVBoxLayout* topAxesLayout;
80     QVBoxLayout* bottomAxesLayout;
81     QHBoxLayout* leftAxesLayout;
82     QHBoxLayout* rightAxesLayout;
83 };
84 
85 struct LayoutGraphNode
86 {
LayoutGraphNodeLayoutGraphNode87     LayoutGraphNode()
88         : diagramPlane( nullptr )
89         , leftSuccesor( nullptr )
90         , bottomSuccesor( nullptr )
91         , sharedSuccesor( nullptr )
92         , gridLayout( nullptr )
93         , topAxesLayout( false )
94         , bottomAxesLayout( false )
95         , leftAxesLayout( false )
96         , rightAxesLayout( false )
97         , priority( -1 )
98     {}
99     AbstractCoordinatePlane* diagramPlane;
100     LayoutGraphNode* leftSuccesor;
101     LayoutGraphNode* bottomSuccesor;
102     LayoutGraphNode* sharedSuccesor;
103     QGridLayout* gridLayout;
104     bool topAxesLayout;
105     bool bottomAxesLayout;
106     bool leftAxesLayout;
107     bool rightAxesLayout;
108     int priority;
109     bool operator<( const LayoutGraphNode &other ) const
110     {
111         return priority < other.priority;
112     }
113 };
114 
115 
116 /**
117  * \internal
118  */
119 class Q_DECL_HIDDEN Chart::Private : public QObject
120 {
121     Q_OBJECT
122     public:
123         Chart* chart;
124 
125         enum AxisType { Abscissa, Ordinate };
126         bool useNewLayoutSystem;
127         CoordinatePlaneList coordinatePlanes;
128         HeaderFooterList headerFooters;
129         LegendList legends;
130 
131         QHBoxLayout* layout;
132         QVBoxLayout* vLayout;
133         QBoxLayout*  planesLayout;
134         QGridLayout* gridPlaneLayout;
135         QGridLayout* headerLayout;
136         QGridLayout* footerLayout;
137         QGridLayout* dataAndLegendLayout;
138         QSpacerItem* leftOuterSpacer;
139         QSpacerItem* rightOuterSpacer;
140         QSpacerItem* topOuterSpacer;
141         QSpacerItem* bottomOuterSpacer;
142 
143         QVBoxLayout* innerHdFtLayouts[2][3][3];
144 
145         QVector<KChart::TextArea*> textLayoutItems;
146         QVector<KChart::AbstractLayoutItem*> planeLayoutItems;
147         QVector<KChart::Legend*> legendLayoutItems;
148 
149         QSize overrideSize;
150         bool isFloatingLegendsLayoutDirty;
151         bool isPlanesLayoutDirty;
152 
153         // since we do not want to derive Chart from AbstractAreaBase, we store the attributes
154         // here and call two static painting methods to draw the background and frame.
155         KChart::FrameAttributes frameAttributes;
156         KChart::BackgroundAttributes backgroundAttributes;
157 
158         // ### wrong names, "leading" means inter-line distance of text. spacing? margin?
159         int globalLeadingLeft, globalLeadingRight, globalLeadingTop, globalLeadingBottom;
160 
161         QList< AbstractCoordinatePlane* > mouseClickedPlanes;
162 
163         Qt::LayoutDirection layoutDirection;
164 
165         Private( Chart* );
166 
167         virtual ~Private();
168 
169         void createLayouts();
170         void updateDirtyLayouts();
171         void reapplyInternalLayouts(); // TODO: see if this can be merged with updateDirtyLayouts()
172         void paintAll( QPainter* painter );
173 
174         struct AxisInfo {
AxisInfoAxisInfo175             AxisInfo()
176                 :plane(nullptr)
177             {}
178             AbstractCoordinatePlane *plane;
179         };
180         QHash<AbstractCoordinatePlane*, PlaneInfo> buildPlaneLayoutInfos();
181         QVector< LayoutGraphNode* > buildPlaneLayoutGraph();
182 
183     public Q_SLOTS:
184         void slotLayoutPlanes();
185         void slotResizePlanes();
186         void slotLegendPositionChanged( AbstractAreaWidget* legend );
187         void slotHeaderFooterPositionChanged( HeaderFooter* hf );
188         void slotUnregisterDestroyedLegend( Legend * legend );
189         void slotUnregisterDestroyedHeaderFooter( HeaderFooter* headerFooter );
190         void slotUnregisterDestroyedPlane( AbstractCoordinatePlane* plane );
191 };
192 
193 }
194 
195 #endif
196