summaryrefslogtreecommitdiff
path: root/noncore/graphics/drawpad/drawpadcanvas.cpp
Unidiff
Diffstat (limited to 'noncore/graphics/drawpad/drawpadcanvas.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/graphics/drawpad/drawpadcanvas.cpp339
1 files changed, 339 insertions, 0 deletions
diff --git a/noncore/graphics/drawpad/drawpadcanvas.cpp b/noncore/graphics/drawpad/drawpadcanvas.cpp
new file mode 100644
index 0000000..f02f478
--- a/dev/null
+++ b/noncore/graphics/drawpad/drawpadcanvas.cpp
@@ -0,0 +1,339 @@
1/***************************************************************************
2 * *
3 * DrawPad - a drawing program for Opie Environment *
4 * *
5 * (C) 2002 by S. Prud'homme <prudhomme@laposte.net> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 ***************************************************************************/
13
14#include "drawpadcanvas.h"
15
16#include "drawmode.h"
17#include "drawpad.h"
18
19#include <qbuffer.h>
20#include <qimage.h>
21#include <qpainter.h>
22#include <qpixmap.h>
23#include <qtextcodec.h>
24#include <qtextstream.h>
25#include <qxml.h>
26
27#include <zlib.h>
28
29class DrawPadCanvasXmlHandler: public QXmlDefaultHandler
30{
31public:
32 DrawPadCanvasXmlHandler();
33 ~DrawPadCanvasXmlHandler();
34
35 QList<QPixmap> pixmaps();
36
37 bool startElement(const QString& namespaceURI, const QString& localName,
38 const QString& qName, const QXmlAttributes& atts);
39 bool endElement(const QString& namespaceURI, const QString& localName,
40 const QString& qName);
41 bool characters(const QString& ch);
42
43private:
44 enum State {
45 Unknown,
46 InData
47 };
48
49 State m_state;
50 ulong m_dataLenght;
51 QList<QPixmap> m_pixmaps;
52};
53
54DrawPadCanvasXmlHandler::DrawPadCanvasXmlHandler()
55{
56 m_state = Unknown;
57}
58
59DrawPadCanvasXmlHandler::~DrawPadCanvasXmlHandler()
60{
61}
62
63QList<QPixmap> DrawPadCanvasXmlHandler::pixmaps()
64{
65 return m_pixmaps;
66}
67
68bool DrawPadCanvasXmlHandler::startElement(const QString& namespaceURI, const QString& localName,
69 const QString& qName, const QXmlAttributes& atts)
70{
71 Q_CONST_UNUSED(namespaceURI)
72 Q_CONST_UNUSED(localName)
73
74 if (qName.compare("data") == 0) {
75 m_state = InData;
76 m_dataLenght = atts.value("length").toULong();
77 }
78
79 return true;
80}
81
82bool DrawPadCanvasXmlHandler::endElement(const QString& namespaceURI, const QString& localName,
83 const QString& qName)
84{
85 Q_CONST_UNUSED(namespaceURI)
86 Q_CONST_UNUSED(localName)
87
88 if (qName.compare("data") == 0) {
89 m_state = Unknown;
90 }
91
92 return true;
93}
94
95bool DrawPadCanvasXmlHandler::characters(const QString& ch)
96{
97 if (m_state == InData) {
98 QByteArray byteArray(ch.length() / 2);
99
100 for (int i = 0; i < (int)ch.length() / 2; i++) {
101 char h = ch[2 * i].latin1();
102 char l = ch[2 * i + 1].latin1();
103 uchar r = 0;
104
105 if (h <= '9') {
106 r += h - '0';
107 } else {
108 r += h - 'a' + 10;
109 }
110
111 r = r << 4;
112
113 if (l <= '9') {
114 r += l - '0';
115 } else {
116 r += l - 'a' + 10;
117 }
118
119 byteArray[i] = r;
120 }
121
122 if (m_dataLenght < ch.length() * 5) {
123 m_dataLenght = ch.length() * 5;
124 }
125
126 QByteArray byteArrayUnzipped(m_dataLenght);
127 ::uncompress((uchar*)byteArrayUnzipped.data(), &m_dataLenght, (uchar*)byteArray.data(), byteArray.size());
128
129 QImage image;
130 image.loadFromData((const uchar*)byteArrayUnzipped.data(), m_dataLenght, "XPM");
131
132 QPixmap* pixmap = new QPixmap(image.width(), image.height());
133 pixmap->convertFromImage(image);
134 m_pixmaps.append(pixmap);
135 }
136
137 return true;
138}
139
140DrawPadCanvas::DrawPadCanvas(DrawPad* drawPad, QWidget* parent, const char* name, WFlags f)
141 : QWidget(parent, name, f)
142{
143 setBackgroundMode(QWidget::PaletteBase);
144
145 m_pDrawPad = drawPad;
146 m_buffers.setAutoDelete(true);
147 m_buffers.append(new QPixmap(width(), height()));
148 m_buffers.current()->fill(Qt::white);
149}
150
151DrawPadCanvas::~DrawPadCanvas()
152{
153}
154
155void DrawPadCanvas::load(QIODevice* ioDevice)
156{
157 QTextStream textStream(ioDevice);
158 textStream.setCodec(QTextCodec::codecForName("UTF-8"));
159
160 QXmlInputSource xmlInputSource(textStream);
161 QXmlSimpleReader xmlSimpleReader;
162 DrawPadCanvasXmlHandler drawPadCanvasXmlHandler;
163
164 xmlSimpleReader.setContentHandler(&drawPadCanvasXmlHandler);
165 xmlSimpleReader.parse(xmlInputSource);
166
167 m_buffers = drawPadCanvasXmlHandler.pixmaps();
168
169 if (m_buffers.isEmpty()) {
170 m_buffers.append(new QPixmap(width(), height()));
171 m_buffers.current()->fill(Qt::white);
172 }
173
174 repaint();
175}
176
177void DrawPadCanvas::save(QIODevice* ioDevice)
178{
179 QTextStream textStream(ioDevice);
180 textStream.setCodec(QTextCodec::codecForName("UTF-8"));
181
182 textStream << "<drawpad>" << endl;
183 textStream << " <images>" << endl;
184
185 QListIterator<QPixmap> bufferIterator(m_buffers);
186
187 for (bufferIterator.toFirst(); bufferIterator.current() != 0; ++bufferIterator) {
188 textStream << " <image>" << endl;
189
190 QImage image = bufferIterator.current()->convertToImage();
191 QByteArray byteArray;
192 QBuffer buffer(byteArray);
193 QImageIO imageIO(&buffer, "XPM");
194
195 buffer.open(IO_WriteOnly);
196 imageIO.setImage(image);
197 imageIO.write();
198 buffer.close();
199
200 ulong size = byteArray.size() * 2;
201 QByteArray byteArrayZipped(size);
202 ::compress((uchar*)byteArrayZipped.data(), &size, (uchar*)byteArray.data(), byteArray.size());
203
204 textStream << " <data length=\"" << byteArray.size() << "\">";
205
206 static const char hexchars[] = "0123456789abcdef";
207
208 for (int i = 0; i < (int)size; i++ ) {
209 uchar s = (uchar)byteArrayZipped[i];
210 textStream << hexchars[s >> 4];
211 textStream << hexchars[s & 0x0f];
212 }
213
214 textStream << "</data>" << endl;
215 textStream << " </image>" << endl;
216 }
217
218 textStream << " </images>" << endl;
219 textStream << "</drawpad>";
220}
221
222QPixmap* DrawPadCanvas::currentPage()
223{
224 return m_buffers.current();
225}
226
227void DrawPadCanvas::clearAll()
228{
229 m_buffers.clear();
230
231 m_buffers.append(new QPixmap(width(), height()));
232 m_buffers.current()->fill(Qt::white);
233
234 repaint();
235}
236
237void DrawPadCanvas::newPage()
238{
239 m_buffers.insert(m_buffers.at() + 1, new QPixmap(width(), height()));
240 m_buffers.current()->fill(Qt::white);
241 repaint();
242}
243
244void DrawPadCanvas::clearPage()
245{
246 m_buffers.current()->fill(Qt::white);
247 repaint();
248}
249
250void DrawPadCanvas::deletePage()
251{
252 m_buffers.remove(m_buffers.current());
253
254 if (m_buffers.isEmpty()) {
255 m_buffers.append(new QPixmap(width(), height()));
256 m_buffers.current()->fill(Qt::white);
257 }
258
259 repaint();
260}
261
262bool DrawPadCanvas::goPreviousPageEnabled()
263{
264 return (m_buffers.current() != m_buffers.getFirst());
265}
266
267bool DrawPadCanvas::goNextPageEnabled()
268{
269 return (m_buffers.current() != m_buffers.getLast());
270}
271
272void DrawPadCanvas::goFirstPage()
273{
274 m_buffers.first();
275 repaint();
276}
277
278void DrawPadCanvas::goPreviousPage()
279{
280 m_buffers.prev();
281 repaint();
282}
283
284void DrawPadCanvas::goNextPage()
285{
286 m_buffers.next();
287 repaint();
288}
289
290void DrawPadCanvas::goLastPage()
291{
292 m_buffers.last();
293 repaint();
294}
295
296void DrawPadCanvas::mousePressEvent(QMouseEvent* e)
297{
298 m_pDrawPad->drawMode()->mousePressEvent(e);
299}
300
301void DrawPadCanvas::mouseReleaseEvent(QMouseEvent* e)
302{
303 m_pDrawPad->drawMode()->mouseReleaseEvent(e);
304}
305
306void DrawPadCanvas::mouseMoveEvent(QMouseEvent* e)
307{
308 m_pDrawPad->drawMode()->mouseMoveEvent(e);
309}
310
311void DrawPadCanvas::resizeEvent(QResizeEvent* e)
312{
313 QWidget::resizeEvent(e);
314
315 QListIterator<QPixmap> bufferIterator(m_buffers);
316
317 for (bufferIterator.toFirst(); bufferIterator.current() != 0; ++bufferIterator) {
318 int w = width() > bufferIterator.current()->width() ? width() : bufferIterator.current()->width();
319 int h = height() > bufferIterator.current()->height() ? height() : bufferIterator.current()->height();
320
321 QPixmap tmpPixmap(*(bufferIterator.current()));
322 bufferIterator.current()->resize(w, h);
323 bufferIterator.current()->fill(Qt::white);
324
325 bitBlt(bufferIterator.current(), 0, 0, &tmpPixmap, 0, 0, tmpPixmap.width(), tmpPixmap.height());
326 }
327}
328
329void DrawPadCanvas::paintEvent(QPaintEvent* e)
330{
331 QWidget::paintEvent(e);
332
333 QArray<QRect> rects = e->region().rects();
334
335 for (uint i = 0; i < rects.count(); i++) {
336 QRect r = rects[i];
337 bitBlt(this, r.x(), r.y(), m_buffers.current(), r.x(), r.y(), r.width(), r.height());
338 }
339}