Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

drawpadcanvas.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   DrawPad - a drawing program for Opie Environment                      *
00004  *                                                                         *
00005  *   (C) 2002 by S. Prud'homme <prudhomme@laposte.net>                     *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
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      * we could have loaded something from setDocument already
00182      * due the delayed loading we need to make sure we do
00183      * not lose pages
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      * by setDocument we've set a page already so
00215      * don't add an empty one. This comes due the delayed initialisation
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         //236, 232)); no more fixed sizes
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; // no page yet --> initialization not finished (Mickeyl)
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 }

Generated on Sat Nov 5 16:17:29 2005 for OPIE by  doxygen 1.4.2