2 * Copyright (C) 2007, 2008 Petri Damsten <damu@iki.fi>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <QGraphicsLinearLayout>
24 #include <QtGui/qgraphicssceneevent.h>
26 #include <QtXml/qdom.h>
29 #include <KDecompressor>
30 #include <Plasma/Theme>
42 QMap<QString, QStringList> groups;
43 QHash<QString, QDomText> texts;
44 QStringList clickable;
47 static const QString A;
48 static const QString B;
49 static const QString C;
50 static const QString D;
51 static const QString E;
52 static const QString F;
53 static const QString G;
54 static const QString DP;
55 static QMap<QChar, QStringList> sevenSegmentDigits;
59 Private(LCD* lcd) : l(lcd), dirty(false), xScale(1.0), yScale(1.0)
61 // http://en.wikipedia.org/wiki/Seven-segment_display_character_representations
62 if (sevenSegmentDigits.isEmpty()) {
63 sevenSegmentDigits[' '] = QStringList();
64 sevenSegmentDigits['-'] = QStringList() << G;
65 sevenSegmentDigits['0'] = QStringList() << A << B << C << D << E << F;
66 sevenSegmentDigits['1'] = QStringList() << B << C;
67 sevenSegmentDigits['2'] = QStringList() << A << B << D << E << G;
68 sevenSegmentDigits['3'] = QStringList() << A << B << C << D << G;
69 sevenSegmentDigits['4'] = QStringList() << B << C << F << G;
70 sevenSegmentDigits['5'] = QStringList() << A << C << D << F << G;
71 sevenSegmentDigits['6'] = QStringList() << A << C << D << E << F << G;
72 sevenSegmentDigits['7'] = QStringList() << A << B << C;
73 sevenSegmentDigits['8'] = QStringList() << A << B << C << D << E << F << G;
74 sevenSegmentDigits['9'] = QStringList() << A << B << C << D << F << G;
75 sevenSegmentDigits['A'] = QStringList() << A << B << C << E << F << G;
76 sevenSegmentDigits['B'] = QStringList() << A << B << C << D << E << F << G;
77 sevenSegmentDigits['C'] = QStringList() << A << D << E << F;
78 sevenSegmentDigits['D'] = QStringList() << A << B << C << D << E << F;
79 sevenSegmentDigits['E'] = QStringList() << A << D << E << F << G;
80 sevenSegmentDigits['F'] = QStringList() << A << E << F << G;
81 sevenSegmentDigits['G'] = QStringList() << A << C << D << E << F;
82 sevenSegmentDigits['H'] = QStringList() << B << C << E << F << G;
83 sevenSegmentDigits['I'] = QStringList() << B << C;
84 sevenSegmentDigits['J'] = QStringList() << B << C << D << E;
85 sevenSegmentDigits['K'] = QStringList() << E << F << G;
86 sevenSegmentDigits['L'] = QStringList() << D << E << F;
87 sevenSegmentDigits['M'] = QStringList() << A << B << D << F;
88 sevenSegmentDigits['N'] = QStringList() << A << B << C << E << F;
89 sevenSegmentDigits['O'] = QStringList() << A << B << C << D << E << F;
90 sevenSegmentDigits['P'] = QStringList() << A << B << E << F << G;
91 sevenSegmentDigits['Q'] = QStringList() << A << B << D << F << G;
92 sevenSegmentDigits['R'] = QStringList() << A << E << F;
93 sevenSegmentDigits['S'] = QStringList() << A << C << D << F << G;
94 sevenSegmentDigits['T'] = QStringList() << A << E << F;
95 sevenSegmentDigits['U'] = QStringList() << B << C << D << E << F;
96 sevenSegmentDigits['V'] = QStringList() << B << C << D << E << F;
97 sevenSegmentDigits['W'] = QStringList() << B << D << F << G;
98 sevenSegmentDigits['X'] = QStringList() << B << C << E << F << G;
99 sevenSegmentDigits['Y'] = QStringList() << B << C << F << G;
100 sevenSegmentDigits['Z'] = QStringList() << A << B << D << E << G;
101 sevenSegmentDigits['a'] = QStringList() << A << B << C << D << E << G;
102 sevenSegmentDigits['b'] = QStringList() << C << D << E << F << G;
103 sevenSegmentDigits['c'] = QStringList() << D << E << G;
104 sevenSegmentDigits['d'] = QStringList() << B << C << D << E << G;
105 sevenSegmentDigits['e'] = QStringList() << A << B << E << F << G;
106 sevenSegmentDigits['f'] = QStringList() << A << E << F << G;
107 sevenSegmentDigits['g'] = QStringList() << A << B << C << D << F << G;
108 sevenSegmentDigits['h'] = QStringList() << C << E << F << G;
109 sevenSegmentDigits['i'] = QStringList() << C;
110 sevenSegmentDigits['j'] = QStringList() << C << D;
111 sevenSegmentDigits['k'] = QStringList() << A << C << E << F << G;
112 sevenSegmentDigits['l'] = QStringList() << E << F;
113 sevenSegmentDigits['m'] = QStringList() << A << C << E << G;
114 sevenSegmentDigits['n'] = QStringList() << C << E << G;
115 sevenSegmentDigits[QChar(0x00F1)] = QStringList() << A << C << E << G; // ñ
116 sevenSegmentDigits['o'] = QStringList() << C << D << E << G;
117 sevenSegmentDigits['p'] = QStringList() << A << B << E << F << G;
118 sevenSegmentDigits['q'] = QStringList() << A << B << C << F << G;
119 sevenSegmentDigits['r'] = QStringList() << E << G;
120 sevenSegmentDigits['s'] = QStringList() << E << G;
121 sevenSegmentDigits['t'] = QStringList() << D << E << F << G;
122 sevenSegmentDigits['u'] = QStringList() << C << D << E;
123 sevenSegmentDigits['v'] = QStringList() << E << G;
124 sevenSegmentDigits['w'] = QStringList() << E << G;
125 sevenSegmentDigits['x'] = QStringList() << E << G;
126 sevenSegmentDigits['y'] = QStringList() << E << G;
127 sevenSegmentDigits['z'] = QStringList() << E << G;
128 sevenSegmentDigits[QChar(0x00F6)] = QStringList() << A << C << D << E << G; // ö
132 int digits(const QString& name)
134 return groups[name].count();
137 void paint(QPainter* p, const QString& item)
139 QRectF r = svg.elementRect(item);
140 svg.paint(p, r, item);
143 QRectF scaledRect(const QString& item)
145 QRectF r = svg.elementRect(item);
146 r.setRect(r.x() * xScale, r.y() * yScale, r.width() * xScale, r.height() * yScale);
152 const QSize lsize = l->size().toSize();
153 if ((dirty || lsize != img.size()) && lsize != QSize(0, 0)) {
154 // kDebug() << "Making bitmap" << l->size();
155 if (lsize != img.size()) {
156 img = QPixmap(lsize);
158 img.fill(Qt::transparent);
162 xScale = l->size().width() / svg.size().width();
163 yScale = l->size().height() / svg.size().height();
164 p.setRenderHint(QPainter::TextAntialiasing, true);
165 p.setRenderHint(QPainter::Antialiasing, true);
166 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
169 p.scale(l->size().width() / svg.size().width(),
170 l->size().height() / svg.size().height());
172 foreach (const QString& item, items) {
182 // kDebug() << content;
183 KDecompressor kdecompressor;
184 if (!kdecompressor.setType(KDecompressor::TypeGZip)) {
185 kWarning() << "Could not set decompressor type" << kdecompressor.errorString();
189 QFile contentFile(content);
190 if (!contentFile.open(QFile::ReadOnly)) {
191 kWarning() << "Could open content file" << content << contentFile.errorString();
195 if (!kdecompressor.process(contentFile.readAll())) {
196 kWarning() << "Could not decompress content" << kdecompressor.errorString();
200 doc.setContent(kdecompressor.result());
201 QList<QDomNodeList> lists;
203 lists << doc.elementsByTagName("g");
204 lists << doc.elementsByTagName("path");
205 lists << doc.elementsByTagName("rect");
206 foreach (const QDomNodeList& list, lists) {
207 for (int i = 0; i < list.count(); ++i) {
208 QDomElement element = list.item(i).toElement();
209 QString id = element.attribute("id");
210 if ((pos = id.lastIndexOf(':')) > -1) {
211 groups[id.left(pos)] << id.mid(pos + 1);
215 QDomNodeList list = doc.elementsByTagName("text");
216 for (int i = 0; i < list.count(); ++i) {
217 QDomElement element = list.item(i).toElement();
218 QDomNodeList l = element.elementsByTagName("tspan");
219 QDomElement e = l.item(0).toElement();
220 for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
221 QDomText t = n.toText();
223 texts[element.attribute("id")] = t;
228 // kDebug() << groups;
232 QMap<QChar, QStringList> LCD::Private::sevenSegmentDigits;
233 const QString LCD::Private::A("A");
234 const QString LCD::Private::B("B");
235 const QString LCD::Private::C("C");
236 const QString LCD::Private::D("D");
237 const QString LCD::Private::E("E");
238 const QString LCD::Private::F("F");
239 const QString LCD::Private::G("G");
240 const QString LCD::Private::DP("DP");
242 LCD::LCD(QGraphicsItem *parent) :
243 QGraphicsWidget(parent),
246 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
254 QString LCD::svg() const
259 void LCD::setSvg(const QString &svg)
261 d->content = Plasma::Theme::defaultTheme()->imagePath(svg);
262 d->svg.setImagePath(d->content);
268 QStringList LCD::groupItems(const QString &name)
270 return d->groups[name];
273 void LCD::paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *widget)
279 p->drawPixmap(0, 0, d->img);
282 void LCD::setDigit(const QString &name, QChar digit, bool dot)
284 QStringList segments;
286 // kDebug() << name << digit << dot;
287 if (d->sevenSegmentDigits.keys().contains(digit)) {
288 segments = d->sevenSegmentDigits[digit];
293 setGroup(name, segments);
296 void LCD::setNumber(const QString &name, const QString& number)
299 int digits = d->digits(name);
302 // kDebug() << name << number << digits;
303 for (int i = number.length() - 1; i >= 0; --i) {
304 if (number[i] == '.') {
307 setDigit(name + QString(":%1").arg(j++), number[i], dot);
314 for (int i = j; i < digits; ++i) {
315 setDigit(name + QString(":%1").arg(i), ' ', false);
319 void LCD::setGroup(const QString &name, const QStringList& on)
321 QStringList all = d->groups[name];
322 foreach (const QString& item, all) {
323 if (on.contains(item)) {
324 setItemOn(name + ':' + item);
326 setItemOff(name + ':' + item);
336 void LCD::setItemOn(const QString &name)
338 if (!d->items.contains(name)) {
339 // kDebug() << "++++++++++" << name;
346 void LCD::setItemOff(const QString &name)
348 if (d->items.contains(name)) {
349 // kDebug() << "----------" << name;
350 d->items.removeAll(name);
356 void LCD::setLabel(const QString &name, const QString &text)
358 if (d->texts[name].data() != text) {
359 d->texts[name].setData(text);
363 QString LCD::label(const QString &name) const
365 return d->texts[name].data();
368 QPixmap LCD::toPixmap()
374 void LCD::setItemClickable(const QString &name, bool clickable)
376 d->clickable.removeAll(name);
378 setAcceptHoverEvents(true);
379 d->clickable << name;
383 void LCD::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
385 foreach (const QString& name, d->clickable) {
386 if (d->scaledRect(name).contains(event->pos())) {
387 setCursor(QCursor(Qt::PointingHandCursor));
394 void LCD::mousePressEvent(QGraphicsSceneMouseEvent* event)
396 foreach (const QString& name, d->clickable) {
397 if (d->scaledRect(name).contains(event->pos())) {
403 QSizeF LCD::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
405 QSizeF s = QGraphicsWidget::sizeHint(which, constraint);
407 if (which == Qt::PreferredSize) {
409 } else if (which == Qt::MinimumSize) {
410 s = d->svg.size() / 2;
412 s = QGraphicsWidget::sizeHint(which, constraint);
417 #include "moc_lcd.cpp"