1 /***************************************************************************
3 * This program is free software; you can redistribute it and/or modify *
4 * it under the terms of the GNU General Public License as published by *
5 * the Free Software Foundation; either version 2 of the License, or *
6 * (at your option) any later version. *
8 * Copyright (C) 2007 by Javier Goday <jgoday@gmail.com>
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
19 ***************************************************************************/
21 #include "piechartwidget.h"
26 #include <QFontMetrics>
27 #include <QStyleOptionGraphicsItem>
32 #include <KColorCollection>
35 #define LEFT_MARGIN 15
38 class PieChartWidget::PrivateData
50 class PieChartWidget::Private
: public Plasma::Widget
53 Private(Plasma::Widget
*parent
) : Plasma::Widget(parent
),
54 m_colors("Oxygen.colors"),
55 size(QSize(300, 200)),
58 emitUpdateGeometrySignal(false)
60 setGeometry(QRect((size
.width()/2 - PIE_SIZE
/2), TOP_MARGIN
, PIE_SIZE
+ 2, PIE_SIZE
+ 2));
63 // returns the size of the private inner widget
64 QSizeF
sizeHint() const
66 return QSizeF(PIE_SIZE
+ 2, PIE_SIZE
+ 2);
69 // Paint the private widget, who cares to draw only the line items representing the data
70 void paintWidget(QPainter
*p
, const QStyleOptionGraphicsItem
*option
,
77 kDebug() << "About to repaint the inner widget" << endl
;
80 p
->setRenderHint(QPainter::Antialiasing
);
82 QRect
rect(2, 2, PIE_SIZE
-2, PIE_SIZE
- 2);
83 int angle
= 90 * 16; // 0
90 totalPen
.setColor(Qt::darkGray
);
91 totalPen
.setStyle(Qt::SolidLine
);
93 activePen
.setWidth(2);
94 activePen
.setColor(Qt::white
);
95 activePen
.setStyle(Qt::SolidLine
);
97 for(int i
= 0; i
< data
.size(); i
++) {
98 QBrush
brush(m_colors
.color(i
*6 + 4));
100 PrivateData portion
= data
[data
.keys().at(i
)];
102 float pieOpacity
= 0.67;
103 float activePieOpacity
= 0.84;
104 int current_angle
= angle
;
108 if (portion
.isActive
) {
109 p
->setPen(activePen
);
115 p
->setOpacity(pieOpacity
);
117 int totalPercent
= (int) portion
.length
* 100/ totalSize
;
118 angle
= drawPie(p
, rect
, angle
, totalPercent
, brush
);
122 // draw the active length
123 p
->setOpacity(activePieOpacity
);
124 p
->setPen(Qt::NoPen
);
125 int activePercent
= (int) portion
.activeLength
* 100/ totalSize
;
126 drawPie(p
, QRect(rect
.x() + 15, rect
.y() + 15, rect
.width() - 30, rect
.height() - 30),
127 current_angle
, activePercent
, brush
);
135 p
->setPen(Qt::white
);
136 p
->drawText(QRect(2, 2, PIE_SIZE
-2, PIE_SIZE
- 2), Qt::AlignCenter
, i18n("n/a"));
140 int drawPie(QPainter
*p
, const QRect
&rect
, int angle
, int percent
, const QBrush
&brush
)
142 int end_angle
= -1 * percent
* 36/10 * 16;
145 p
->drawPie(rect
, angle
, end_angle
);
147 return end_angle
+ angle
;
150 // Draw the graph legend with the names of the data
151 void drawLegend(const QString
&name
, QPainter
*p
, const QColor
&color
, int count
)
154 p
->setPen(Qt::NoPen
);
155 p
->setBrush(QBrush(color
));
156 p
->drawRoundRect(QRect(LEFT_MARGIN
, count
* 20 + size
.height() - bottomMargin
+ TOP_MARGIN
, 10, 10));
157 p
->setPen(Qt::SolidLine
);
158 p
->setPen(Qt::white
);
161 p
->drawText(QRect(LEFT_MARGIN
+ 14, count
* 20 + size
.height () - bottomMargin
+ TOP_MARGIN
- 5, 200, 20), Qt::AlignLeft
, p
->fontMetrics().elidedText(name
, Qt::ElideLeft
, 200));
163 p
->drawText(QRect(LEFT_MARGIN
+ 236, count
* 20 + size
.height () - bottomMargin
+ TOP_MARGIN
- 5, 70, 20), Qt::AlignLeft
,
164 KGlobal::locale()->formatByteSize(data
[name
].length
));
169 KColorCollection m_colors
;
171 QMap
<QString
, PrivateData
> data
;
174 bool emitUpdateGeometrySignal
;
177 PieChartWidget::PieChartWidget(Widget
*parent
)
178 : Plasma::Widget(parent
),
183 PieChartWidget::~PieChartWidget()
188 void PieChartWidget::addData(QString name
, int length
)
190 addData(name
, length
, 0, false);
193 void PieChartWidget::addData(QString name
, int length
, int activeLength
)
195 addData(name
, length
, activeLength
, false);
198 void PieChartWidget::addData(QString name
, int length
, int activeLength
, bool active
)
200 if (!d
->data
.contains(name
)) {
201 d
->data
[name
] = PrivateData ();
203 // update the widget size
204 d
->bottomMargin
+= 20;
205 d
->size
.setHeight (d
->size
.height() + 20);
207 d
->emitUpdateGeometrySignal
= true;
210 d
->data
[name
].name
= name
;
211 d
->data
[name
].length
= length
;
212 d
->data
[name
].activeLength
= activeLength
;
213 d
->data
[name
].isActive
= active
;
215 d
->totalSize
+= length
;
218 void PieChartWidget::removeData(const QString
&key
)
221 emit
geometryChanged();
224 void PieChartWidget::clear()
227 d
->emitUpdateGeometrySignal
= false;
230 void PieChartWidget::updateView()
232 // ensure that only the data points are repainted, called after the setData methods
233 if (d
->emitUpdateGeometrySignal
) {
234 d
->emitUpdateGeometrySignal
= false;
235 emit
geometryChanged();
240 QSizeF
PieChartWidget::sizeHint() const
245 void PieChartWidget::paintWidget(QPainter
*p
, const QStyleOptionGraphicsItem
*option
, QWidget
*widget
)
250 kDebug() << "About to draw the parent widget" ;
252 for(int i
= 0; i
< d
->data
.size(); i
++) {
253 d
->drawLegend(d
->data
.keys().at(i
), p
, d
->m_colors
.color(i
*6 + 4), i
);