00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "drawpadcanvas.h"
00015
00016 #include "drawpad.h"
00017 #include "page.h"
00018 #include "tool.h"
00019
00020 #include <qpe/applnk.h>
00021 #include <qpe/filemanager.h>
00022 #include <qpe/mimetype.h>
00023
00024 #include <qbuffer.h>
00025 #include <qimage.h>
00026 #include <qtextcodec.h>
00027 #include <qxml.h>
00028
00029 class DrawPadCanvasXmlHandler: public QXmlDefaultHandler
00030 {
00031 public:
00032 DrawPadCanvasXmlHandler();
00033 ~DrawPadCanvasXmlHandler();
00034
00035 QList<Page> pages();
00036
00037 bool startElement(const QString& namespaceURI, const QString& localName,
00038 const QString& qName, const QXmlAttributes& atts);
00039 bool endElement(const QString& namespaceURI, const QString& localName,
00040 const QString& qName);
00041 bool characters(const QString& ch);
00042
00043 private:
00044 enum State {
00045 Unknown,
00046 InTitle,
00047 InDate,
00048 InData
00049 };
00050
00051 State m_state;
00052 QString m_title;
00053 QDateTime m_date;
00054 ulong m_dataLenght;
00055 QString m_dataFormat;
00056 QList<Page> m_pages;
00057 };
00058
00059 DrawPadCanvasXmlHandler::DrawPadCanvasXmlHandler()
00060 {
00061 m_state = Unknown;
00062 }
00063
00064 DrawPadCanvasXmlHandler::~DrawPadCanvasXmlHandler()
00065 {
00066 }
00067
00068 QList<Page> DrawPadCanvasXmlHandler::pages()
00069 {
00070 return m_pages;
00071 }
00072
00073 bool DrawPadCanvasXmlHandler::startElement(const QString& namespaceURI, const QString& localName,
00074 const QString& qName, const QXmlAttributes& atts)
00075 {
00076 Q_CONST_UNUSED(namespaceURI)
00077 Q_CONST_UNUSED(localName)
00078
00079 if (qName == "image") {
00080 m_title = QString();
00081 m_date = QDateTime::currentDateTime();
00082 } else if (qName == "title") {
00083 m_state = InTitle;
00084 } else if (qName == "date") {
00085 m_state = InDate;
00086 } else if (qName == "data") {
00087 m_state = InData;
00088 m_dataLenght = atts.value("length").toULong();
00089 m_dataFormat = atts.value("format");
00090 }
00091
00092 return true;
00093 }
00094
00095 bool DrawPadCanvasXmlHandler::endElement(const QString& namespaceURI, const QString& localName,
00096 const QString& qName)
00097 {
00098 Q_CONST_UNUSED(namespaceURI)
00099 Q_CONST_UNUSED(localName)
00100
00101 if (qName == "title") {
00102 m_state = Unknown;
00103 } else if (qName == "date") {
00104 m_state = Unknown;
00105 } else if (qName == "data") {
00106 m_state = Unknown;
00107 }
00108
00109 return true;
00110 }
00111
00112 bool DrawPadCanvasXmlHandler::characters(const QString& ch)
00113 {
00114 if (m_state == InTitle) {
00115 m_title = ch;
00116 } else if (m_state == InDate) {
00117 m_date = QDateTime(QDate(1970, 1, 1)).addSecs(ch.toInt());
00118 } else if (m_state == InData) {
00119 QByteArray byteArray(ch.length() / 2);
00120
00121 for (int i = 0; i < (int)ch.length() / 2; i++) {
00122 char h = ch[2 * i].latin1();
00123 char l = ch[2 * i + 1].latin1();
00124 uchar r = 0;
00125
00126 if (h <= '9') {
00127 r += h - '0';
00128 } else {
00129 r += h - 'a' + 10;
00130 }
00131
00132 r = r << 4;
00133
00134 if (l <= '9') {
00135 r += l - '0';
00136 } else {
00137 r += l - 'a' + 10;
00138 }
00139
00140 byteArray[i] = r;
00141 }
00142
00143 QImage image;
00144 image.loadFromData((const uchar*)byteArray.data(), m_dataLenght, m_dataFormat);
00145
00146 Page* page = new Page(m_title, image.width(), image.height());
00147 page->setLastModified(m_date);
00148 page->pixmap()->convertFromImage(image);
00149 m_pages.append(page);
00150 }
00151
00152 return true;
00153 }
00154
00155 DrawPadCanvas::DrawPadCanvas(DrawPad* drawPad, QWidget* parent, const char* name)
00156 : QScrollView(parent, name)
00157 {
00158 m_pDrawPad = drawPad;
00159 m_pages.setAutoDelete(true);
00160
00161 viewport()->setBackgroundMode(QWidget::NoBackground);
00162 }
00163
00164 DrawPadCanvas::~DrawPadCanvas()
00165 {
00166 }
00167
00168 void DrawPadCanvas::load(QIODevice* ioDevice)
00169 {
00170 QTextStream textStream(ioDevice);
00171 textStream.setCodec(QTextCodec::codecForName("UTF-8"));
00172
00173 QXmlInputSource xmlInputSource(textStream);
00174 QXmlSimpleReader xmlSimpleReader;
00175 DrawPadCanvasXmlHandler drawPadCanvasXmlHandler;
00176
00177 xmlSimpleReader.setContentHandler(&drawPadCanvasXmlHandler);
00178 xmlSimpleReader.parse(xmlInputSource);
00179
00180
00181
00182
00183
00184
00185 if ( !m_pages.isEmpty() ) {
00186 QList<Page> pages = drawPadCanvasXmlHandler.pages();
00187 QListIterator<Page> it( pages );
00188 Page *p;
00189 while ( ( p = it.current() ) ) {
00190 ++it;
00191 m_pages.append( p );
00192 }
00193 }else
00194 m_pages = drawPadCanvasXmlHandler.pages();
00195
00196
00197
00198 if (m_pages.isEmpty()) {
00199 m_pages.append(new Page("",
00200 clipper()->width()+(verticalScrollBar()->isVisible()?verticalScrollBar()->width():0),
00201 clipper()->height()+(horizontalScrollBar()->isVisible()?horizontalScrollBar()->height():0)));
00202 m_pages.current()->pixmap()->fill(Qt::white);
00203 }
00204
00205 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00206 viewport()->update();
00207
00208 emit pagesChanged();
00209 }
00210
00211 void DrawPadCanvas::initialPage()
00212 {
00213
00214
00215
00216
00217 if (!m_pages.isEmpty() )
00218 return;
00219
00220 m_pages.append(new Page("",
00221 clipper()->width()+(verticalScrollBar()->isVisible()?verticalScrollBar()->width():0),
00222 clipper()->height()+(horizontalScrollBar()->isVisible()?horizontalScrollBar()->height():0)));
00223
00224
00225 m_pages.current()->pixmap()->fill(Qt::white);
00226
00227 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00228 viewport()->update();
00229
00230 emit pagesChanged();
00231 }
00232
00233 void DrawPadCanvas::save(QIODevice* ioDevice)
00234 {
00235 QTextStream textStream(ioDevice);
00236 textStream.setCodec(QTextCodec::codecForName("UTF-8"));
00237
00238 textStream << "<drawpad>" << endl;
00239 textStream << " <images>" << endl;
00240
00241 QListIterator<Page> bufferIterator(m_pages);
00242
00243 for (bufferIterator.toFirst(); bufferIterator.current() != 0; ++bufferIterator) {
00244 textStream << " <image>" << endl;
00245 textStream << " <title>" << bufferIterator.current()->title() << "</title>" << endl;
00246
00247 int intDate = QDateTime(QDate(1970, 1, 1)).secsTo(bufferIterator.current()->lastModified());
00248 textStream << " <date>" << intDate << "</date>" << endl;
00249
00250 QImage image = bufferIterator.current()->pixmap()->convertToImage();
00251 QByteArray byteArray;
00252 QBuffer buffer(byteArray);
00253 QImageIO imageIO(&buffer, "PNG");
00254
00255 buffer.open(IO_WriteOnly);
00256 imageIO.setImage(image);
00257 imageIO.write();
00258 buffer.close();
00259
00260 textStream << " <data length=\"" << byteArray.size() << "\" format=\"PNG\">";
00261
00262 static const char hexchars[] = "0123456789abcdef";
00263
00264 for (int i = 0; i < (int)byteArray.size(); i++ ) {
00265 uchar s = (uchar)byteArray[i];
00266 textStream << hexchars[s >> 4];
00267 textStream << hexchars[s & 0x0f];
00268 }
00269
00270 textStream << "</data>" << endl;
00271 textStream << " </image>" << endl;
00272 }
00273
00274 textStream << " </images>" << endl;
00275 textStream << "</drawpad>";
00276 }
00277
00278 void DrawPadCanvas::importPage(const QString& fileName)
00279 {
00280 Page* importedPage = new Page();
00281
00282 importedPage->pixmap()->load(fileName);
00283 m_pages.insert(m_pages.at() + 1, importedPage);
00284
00285 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00286 viewport()->update();
00287
00288 emit pagesChanged();
00289 }
00290
00291 void DrawPadCanvas::importPixmap( const QPixmap& pix ) {
00292 Page* importedPage = new Page();
00293
00294 (*importedPage->pixmap()) = pix;
00295 m_pages.insert(m_pages.at()+1, importedPage );
00296 resizeContents(m_pages.current()->pixmap()->width(),
00297 m_pages.current()->pixmap()->height() );
00298 viewport()->update();
00299
00300 emit pagesChanged();
00301 }
00302
00303 void DrawPadCanvas::exportPage(uint fromPage, uint toPage, const QString& name,const QString& format)
00304 {
00305 if (fromPage == toPage) {
00306 DocLnk docLnk;
00307 MimeType mimeType(format);
00308
00309 docLnk.setName(name);
00310 docLnk.setType(mimeType.id());
00311
00312 FileManager fileManager;
00313 QIODevice* ioDevice = fileManager.saveFile(docLnk);
00314 QImageIO imageIO(ioDevice, format);
00315
00316 QImage image = m_pages.current()->pixmap()->convertToImage();
00317 imageIO.setImage(image);
00318 imageIO.write();
00319 delete ioDevice;
00320 } else {
00321 for (uint i = fromPage; i <= toPage; i++) {
00322 DocLnk docLnk;
00323 MimeType mimeType(format);
00324
00325 docLnk.setName(name + QString::number(i));
00326 docLnk.setType(mimeType.id());
00327
00328 FileManager fileManager;
00329 QIODevice* ioDevice = fileManager.saveFile(docLnk);
00330 QImageIO imageIO(ioDevice, format);
00331
00332 QImage image = m_pages.at(i - 1)->pixmap()->convertToImage();
00333 imageIO.setImage(image);
00334 imageIO.write();
00335 delete ioDevice;
00336 }
00337 }
00338 }
00339
00340 Page* DrawPadCanvas::currentPage()
00341 {
00342 return m_pages.current();
00343 }
00344
00345 QList<Page> DrawPadCanvas::pages()
00346 {
00347 return m_pages;
00348 }
00349
00350 uint DrawPadCanvas::pagePosition()
00351 {
00352 return (m_pages.at() + 1);
00353 }
00354
00355 uint DrawPadCanvas::pageCount()
00356 {
00357 return m_pages.count();
00358 }
00359
00360 void DrawPadCanvas::selectPage(Page* page)
00361 {
00362 m_pages.findRef(page);
00363
00364 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00365 viewport()->update();
00366
00367 emit pagesChanged();
00368 }
00369
00370 void DrawPadCanvas::backupPage()
00371 {
00372 m_pages.current()->backup();
00373
00374 emit pagesChanged();
00375 }
00376
00377 void DrawPadCanvas::selectPage(uint pagePosition)
00378 {
00379 m_pages.at(pagePosition - 1);
00380
00381 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00382 viewport()->update();
00383
00384 emit pagesChanged();
00385 }
00386
00387 void DrawPadCanvas::deleteAll()
00388 {
00389 m_pages.clear();
00390
00391 m_pages.append(new Page("",
00392 clipper()->width()+(verticalScrollBar()->isVisible()?verticalScrollBar()->width():0),
00393 clipper()->height()+(horizontalScrollBar()->isVisible()?horizontalScrollBar()->height():0)));
00394
00395 m_pages.current()->pixmap()->fill(Qt::white);
00396
00397 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00398 viewport()->update();
00399
00400 emit pagesChanged();
00401 }
00402
00403 void DrawPadCanvas::newPage(QString title, uint width, uint height, const QColor& color)
00404 {
00405 m_pages.insert(m_pages.at() + 1, new Page(title, width, height));
00406 m_pages.current()->pixmap()->fill(color);
00407
00408 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00409 viewport()->update();
00410
00411 emit pagesChanged();
00412 }
00413
00414 void DrawPadCanvas::clearPage()
00415 {
00416 m_pages.current()->pixmap()->fill(Qt::white);
00417
00418 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00419 viewport()->update();
00420 }
00421
00422 void DrawPadCanvas::deletePage()
00423 {
00424 m_pages.remove(m_pages.current());
00425
00426 if (m_pages.isEmpty()) {
00427 m_pages.append(new Page("",
00428 clipper()->width()+(verticalScrollBar()->isVisible()?verticalScrollBar()->width():0),
00429 clipper()->height()+(horizontalScrollBar()->isVisible()?horizontalScrollBar()->height():0)));
00430
00431 m_pages.current()->pixmap()->fill(Qt::white);
00432 }
00433
00434 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00435 viewport()->update();
00436
00437 emit pagesChanged();
00438 }
00439
00440 void DrawPadCanvas::movePageUp()
00441 {
00442 int index = m_pages.at();
00443 Page* page = m_pages.take();
00444 m_pages.insert(index - 1, page);
00445
00446 emit pagesChanged();
00447 }
00448
00449 void DrawPadCanvas::movePageDown()
00450 {
00451 int index = m_pages.at();
00452 Page* page = m_pages.take();
00453 m_pages.insert(index + 1, page);
00454
00455 emit pagesChanged();
00456 }
00457
00458 bool DrawPadCanvas::goPreviousPageEnabled()
00459 {
00460 return (m_pages.current() != m_pages.getFirst());
00461 }
00462
00463 bool DrawPadCanvas::goNextPageEnabled()
00464 {
00465 return (m_pages.current() != m_pages.getLast());
00466 }
00467
00468 void DrawPadCanvas::undo()
00469 {
00470 m_pages.current()->undo();
00471
00472 viewport()->update();
00473
00474 emit pagesChanged();
00475 }
00476
00477 void DrawPadCanvas::redo()
00478 {
00479 m_pages.current()->redo();
00480
00481 viewport()->update();
00482
00483 emit pagesChanged();
00484 }
00485
00486 void DrawPadCanvas::goFirstPage()
00487 {
00488 m_pages.first();
00489
00490 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00491 viewport()->update();
00492
00493 emit pagesChanged();
00494 }
00495
00496 void DrawPadCanvas::goPreviousPage()
00497 {
00498 m_pages.prev();
00499
00500 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00501 viewport()->update();
00502
00503 emit pagesChanged();
00504 }
00505
00506 void DrawPadCanvas::goNextPage()
00507 {
00508 m_pages.next();
00509 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00510 viewport()->update();
00511
00512 emit pagesChanged();
00513 }
00514
00515 void DrawPadCanvas::goLastPage()
00516 {
00517 m_pages.last();
00518
00519 resizeContents(m_pages.current()->pixmap()->width(), m_pages.current()->pixmap()->height());
00520 viewport()->update();
00521
00522 emit pagesChanged();
00523 }
00524
00525 void DrawPadCanvas::contentsMousePressEvent(QMouseEvent* e)
00526 {
00527 m_pDrawPad->tool()->mousePressEvent(e);
00528 }
00529
00530 void DrawPadCanvas::contentsMouseReleaseEvent(QMouseEvent* e)
00531 {
00532 m_pDrawPad->tool()->mouseReleaseEvent(e);
00533 }
00534
00535 void DrawPadCanvas::contentsMouseMoveEvent(QMouseEvent* e)
00536 {
00537 m_pDrawPad->tool()->mouseMoveEvent(e);
00538 }
00539
00540 void DrawPadCanvas::drawContents(QPainter* p, int cx, int cy, int cw, int ch)
00541 {
00542 Page* currentPage = m_pages.current();
00543 if ( !currentPage ) return;
00544 QRect clipRect(cx, cy, cw, ch);
00545 QRect pixmapRect(0, 0, currentPage->pixmap()->width(), m_pages.current()->pixmap()->height());
00546 QRect drawRect = pixmapRect.intersect(clipRect);
00547
00548 p->drawPixmap(drawRect.topLeft(), *(currentPage->pixmap()), drawRect);
00549
00550 if (drawRect.right() < clipRect.right()) {
00551 p->fillRect(drawRect.right() + 1, cy, cw - drawRect.width(), ch, colorGroup().dark());
00552 }
00553
00554 if (drawRect.bottom() < clipRect.bottom()) {
00555 p->fillRect(cx, drawRect.bottom() + 1, cw, ch - drawRect.height(), colorGroup().dark());
00556 }
00557 }