*Fix Speed-resizing of applet
[kdenetwork.git] / kget / plasma / applet / piechartwidget.cpp
blobedca9e6f18368ca1e07809f3ce426d21e189b853
1 /***************************************************************************
2 * *
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>
9 * *
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. *
14 * *
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"
23 #include <math.h>
25 #include <QPainter>
26 #include <QFontMetrics>
27 #include <QStyleOptionGraphicsItem>
29 #include <KDebug>
30 #include <KLocale>
31 #include <KGlobal>
32 #include <KColorCollection>
34 #define TOP_MARGIN 10
35 #define LEFT_MARGIN 15
36 #define PIE_SIZE 140
38 class PieChartWidget::PrivateData
40 public:
41 PrivateData()
44 QString name;
45 bool isActive;
46 int length;
47 int activeLength;
50 class PieChartWidget::Private : public Plasma::Widget
52 public:
53 Private(Plasma::Widget *parent) : Plasma::Widget(parent),
54 m_colors("Oxygen.colors"),
55 size(QSize(300, 200)),
56 bottomMargin(10),
57 totalSize(0),
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,
71 QWidget *widget)
73 Q_UNUSED(option)
74 Q_UNUSED(widget)
76 if(totalSize > 0) {
77 kDebug() << "About to repaint the inner widget" << endl;
79 p->save();
80 p->setRenderHint(QPainter::Antialiasing);
82 QRect rect(2, 2, PIE_SIZE -2, PIE_SIZE - 2);
83 int angle = 90 * 16; // 0
85 QPen totalPen;
86 QPen activePen;
88 // total pen
89 totalPen.setWidth(2);
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;
106 p->save();
108 if (portion.isActive) {
109 p->setPen(activePen);
111 else {
112 p->setPen(totalPen);
115 p->setOpacity(pieOpacity);
117 int totalPercent = (int) portion.length * 100/ totalSize;
118 angle = drawPie(p, rect, angle, totalPercent, brush);
119 p->restore();
121 p->save();
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);
129 p->restore();
132 p->restore();
134 else {
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;
144 p->setBrush(brush);
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)
153 p->save();
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);
160 // the data name
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));
162 // the data percent
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));
166 p->restore();
169 KColorCollection m_colors;
170 QSize size;
171 QMap <QString, PrivateData> data;
172 int bottomMargin;
173 int totalSize;
174 bool emitUpdateGeometrySignal;
177 PieChartWidget::PieChartWidget(Widget *parent)
178 : Plasma::Widget(parent),
179 d(new Private(this))
183 PieChartWidget::~PieChartWidget()
185 delete d;
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)
220 d->data.remove(key);
221 emit geometryChanged();
224 void PieChartWidget::clear()
226 d->totalSize = 0;
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();
237 d->updateGeometry();
240 QSizeF PieChartWidget::sizeHint() const
242 return d->size;
245 void PieChartWidget::paintWidget(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *widget)
247 Q_UNUSED(option)
248 Q_UNUSED(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);