author | leseb <leseb> | 2002-03-17 15:31:12 (UTC) |
---|---|---|
committer | leseb <leseb> | 2002-03-17 15:31:12 (UTC) |
commit | 378db8490c6c80ced939622605be1500fa126a2d (patch) (side-by-side diff) | |
tree | b39bbe287f70a1e867060eb14b86536e7d727d17 | |
parent | 31e0537b3406d3e89df6424cded2570d28d61df4 (diff) | |
download | opie-378db8490c6c80ced939622605be1500fa126a2d.zip opie-378db8490c6c80ced939622605be1500fa126a2d.tar.gz opie-378db8490c6c80ced939622605be1500fa126a2d.tar.bz2 |
Basic undo/redo
-rw-r--r-- | noncore/graphics/drawpad/drawmode.h | 6 | ||||
-rw-r--r-- | noncore/graphics/drawpad/drawpad.cpp | 81 | ||||
-rw-r--r-- | noncore/graphics/drawpad/drawpad.h | 17 | ||||
-rw-r--r-- | noncore/graphics/drawpad/drawpadcanvas.cpp | 135 | ||||
-rw-r--r-- | noncore/graphics/drawpad/drawpadcanvas.h | 12 |
5 files changed, 159 insertions, 92 deletions
diff --git a/noncore/graphics/drawpad/drawmode.h b/noncore/graphics/drawpad/drawmode.h index d4ecadd..4e80fe2 100644 --- a/noncore/graphics/drawpad/drawmode.h +++ b/noncore/graphics/drawpad/drawmode.h @@ -1,37 +1,39 @@ /*************************************************************************** * * * DrawPad - a drawing program for Opie Environment * * * * (C) 2002 by S. Prud'homme <prudhomme@laposte.net> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DRAWMODE_H #define DRAWMODE_H #include <qobject.h> class DrawPad; class DrawPadCanvas; class DrawMode : QObject { -public: +protected: DrawMode(DrawPad* drawPad, DrawPadCanvas* drawPadCanvas); - ~DrawMode(); + +public: + virtual ~DrawMode(); virtual void mousePressEvent(QMouseEvent* e) = 0; virtual void mouseReleaseEvent(QMouseEvent* e) = 0; virtual void mouseMoveEvent(QMouseEvent* e) = 0; protected: DrawPad* m_pDrawPad; DrawPadCanvas* m_pDrawPadCanvas; }; #endif // DRAWMODE_H diff --git a/noncore/graphics/drawpad/drawpad.cpp b/noncore/graphics/drawpad/drawpad.cpp index 3c593b6..5cc2197 100644 --- a/noncore/graphics/drawpad/drawpad.cpp +++ b/noncore/graphics/drawpad/drawpad.cpp @@ -1,390 +1,369 @@ /*************************************************************************** * * * DrawPad - a drawing program for Opie Environment * * * * (C) 2002 by S. Prud'homme <prudhomme@laposte.net> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "drawpad.h" #include "drawpadcanvas.h" #include "ellipsedrawmode.h" #include "erasedrawmode.h" #include "filldrawmode.h" #include "linedrawmode.h" #include "pointdrawmode.h" #include "rectangledrawmode.h" #include <qpe/global.h> #include <qpe/qpemenubar.h> #include <qpe/qpetoolbar.h> #include <qpe/resource.h> #include <qaction.h> #include <qfile.h> #include <qpainter.h> #include <qspinbox.h> #include <qtoolbutton.h> #include <qtooltip.h> DrawPad::DrawPad(QWidget* parent, const char* name, WFlags f) : QMainWindow(parent, name, f) { setCaption(tr("DrawPad")); // init members m_pDrawPadCanvas = new DrawPadCanvas(this, this); + connect(m_pDrawPadCanvas, SIGNAL(pagesChanged()), this, SLOT(updateNavigationToolButtons())); + connect(m_pDrawPadCanvas, SIGNAL(pageBackupsChanged()), this, SLOT(updateUndoRedoToolButtons())); QFile file(Global::applicationFileName("drawpad", "drawpad.xml")); if (file.open(IO_ReadOnly)) { m_pDrawPadCanvas->load(&file); file.close(); } setCentralWidget(m_pDrawPadCanvas); m_colors.resize(8); m_colors.at(0) = Qt::black; m_colors.at(1) = Qt::white; m_colors.at(2) = Qt::red; m_colors.at(3) = Qt::green; m_colors.at(4) = Qt::blue; m_colors.at(5) = Qt::cyan; m_colors.at(6) = Qt::magenta; m_colors.at(7) = Qt::yellow; // init menu setToolBarsMovable(false); QPEToolBar* menuToolBar = new QPEToolBar(this); QPEMenuBar* menuBar = new QPEMenuBar(menuToolBar); QPopupMenu *toolsPopupMenu = new QPopupMenu(menuBar); QAction* clearAllAction = new QAction(tr("Clear All"), QString::null, 0, this); - connect(clearAllAction, SIGNAL(activated()), this, SLOT(clearAll())); + connect(clearAllAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(clearAll())); clearAllAction->addTo(toolsPopupMenu); toolsPopupMenu->insertSeparator(); QAction* setOptionsAction = new QAction(tr("Options"), tr("Options..."), 0, this); setOptionsAction->addTo(toolsPopupMenu); menuBar->insertItem(tr("Tools"), toolsPopupMenu); // init page toolbar QPEToolBar* pageToolBar = new QPEToolBar(this); QAction* newPageAction = new QAction(tr("New Page"), Resource::loadIconSet("new"), QString::null, 0, this); - connect(newPageAction, SIGNAL(activated()), this, SLOT(newPage())); + connect(newPageAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(newPage())); newPageAction->addTo(pageToolBar); QAction* clearPageAction = new QAction(tr("Clear Page"), Resource::loadIconSet("drawpad/clear"), QString::null, 0, this); connect(clearPageAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(clearPage())); clearPageAction->addTo(pageToolBar); QAction* deletePageAction = new QAction(tr("Delete Page"), Resource::loadIconSet("trash"), QString::null, 0, this); - connect(deletePageAction, SIGNAL(activated()), this, SLOT(deletePage())); + connect(deletePageAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(deletePage())); deletePageAction->addTo(pageToolBar); QPEToolBar* emptyToolBar = new QPEToolBar(this); emptyToolBar->setHorizontalStretchable(true); // init navigation toolbar QPEToolBar* navigationToolBar = new QPEToolBar(this); + m_pUndoAction = new QAction(tr("Undo"), Resource::loadIconSet("drawpad/undo"), QString::null, 0, this); + connect(m_pUndoAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(undo())); + m_pUndoAction->addTo(navigationToolBar); + + m_pRedoAction = new QAction(tr("Redo"), Resource::loadIconSet("drawpad/redo"), QString::null, 0, this); + connect(m_pRedoAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(redo())); + m_pRedoAction->addTo(navigationToolBar); + + updateUndoRedoToolButtons(); + m_pFirstPageAction = new QAction(tr("First Page"), Resource::loadIconSet("fastback"), QString::null, 0, this); - connect(m_pFirstPageAction, SIGNAL(activated()), this, SLOT(goFirstPage())); + connect(m_pFirstPageAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(goFirstPage())); m_pFirstPageAction->addTo(navigationToolBar); m_pPreviousPageAction = new QAction(tr("Previous Page"), Resource::loadIconSet("back"), QString::null, 0, this); - connect(m_pPreviousPageAction, SIGNAL(activated()), this, SLOT(goPreviousPage())); + connect(m_pPreviousPageAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(goPreviousPage())); m_pPreviousPageAction->addTo(navigationToolBar); m_pNextPageAction = new QAction(tr("Next Page"), Resource::loadIconSet("forward"), QString::null, 0, this); - connect(m_pNextPageAction, SIGNAL(activated()), this, SLOT(goNextPage())); + connect(m_pNextPageAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(goNextPage())); m_pNextPageAction->addTo(navigationToolBar); m_pLastPageAction = new QAction(tr("Last Page"), Resource::loadIconSet("fastforward"), QString::null, 0, this); - connect(m_pLastPageAction, SIGNAL(activated()), this, SLOT(goLastPage())); + connect(m_pLastPageAction, SIGNAL(activated()), m_pDrawPadCanvas, SLOT(goLastPage())); m_pLastPageAction->addTo(navigationToolBar); - updateNavigationToolBar(); + updateNavigationToolButtons(); // init draw mode toolbar QPEToolBar* drawModeToolBar = new QPEToolBar(this); m_pPointDrawModeAction = new QAction(tr("Draw Point"), Resource::loadIconSet("drawpad/point.png"), QString::null, 0, this); m_pPointDrawModeAction->setToggleAction(true); connect(m_pPointDrawModeAction, SIGNAL(activated()), this, SLOT(setPointDrawMode())); m_pPointDrawModeAction->addTo(drawModeToolBar); m_pLineDrawModeAction = new QAction(tr("Draw Line"), Resource::loadIconSet("drawpad/line.png"), QString::null, 0, this); m_pLineDrawModeAction->setToggleAction(true); connect(m_pLineDrawModeAction, SIGNAL(activated()), this, SLOT(setLineDrawMode())); m_pLineDrawModeAction->addTo(drawModeToolBar); m_pRectangleDrawModeAction = new QAction(tr("Draw Rectangle"), Resource::loadIconSet("drawpad/rectangle.png"), QString::null, 0, this); m_pRectangleDrawModeAction->setToggleAction(true); connect(m_pRectangleDrawModeAction, SIGNAL(activated()), this, SLOT(setRectangleDrawMode())); m_pRectangleDrawModeAction->addTo(drawModeToolBar); m_pEllipseDrawModeAction = new QAction(tr("Draw Ellipse"), Resource::loadIconSet("drawpad/ellipse.png"), QString::null, 0, this); m_pEllipseDrawModeAction->setToggleAction(true); connect(m_pEllipseDrawModeAction, SIGNAL(activated()), this, SLOT(setEllipseDrawMode())); m_pEllipseDrawModeAction->addTo(drawModeToolBar); m_pFillDrawModeAction = new QAction(tr("Fill Region"), Resource::loadIconSet("drawpad/fill.png"), QString::null, 0, this); m_pFillDrawModeAction->setToggleAction(true); connect(m_pFillDrawModeAction, SIGNAL(activated()), this, SLOT(setFillDrawMode())); m_pFillDrawModeAction->addTo(drawModeToolBar); m_pEraseDrawModeAction = new QAction(tr("Erase Point"), Resource::loadIconSet("drawpad/erase.png"), QString::null, 0, this); m_pEraseDrawModeAction->setToggleAction(true); connect(m_pEraseDrawModeAction, SIGNAL(activated()), this, SLOT(setEraseDrawMode())); m_pEraseDrawModeAction->addTo(drawModeToolBar); m_pDrawMode = 0; setPointDrawMode(); emptyToolBar = new QPEToolBar(this); emptyToolBar->setHorizontalStretchable(true); + emptyToolBar->addSeparator(); + + // init draw parameters toolbar QPEToolBar* drawParametersToolBar = new QPEToolBar(this); QSpinBox* penWidthSpinBox = new QSpinBox(1, 9, 1, drawParametersToolBar); connect(penWidthSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changePenWidth(int))); penWidthSpinBox->setValue(1); m_pPenColorToolButton = new QToolButton(drawParametersToolBar); m_pPenColorToolButton->setPixmap(Resource::loadPixmap("drawpad/pencolor.png")); QPopupMenu* penColorPopupMenu = new QPopupMenu(m_pPenColorToolButton); connect(penColorPopupMenu, SIGNAL(activated(int)), this, SLOT(changePenColor(int))); QPixmap penColorPixmap(14, 14); for (uint i = 0; i < m_colors.size(); i++) { penColorPixmap.fill(m_colors.at(i)); penColorPopupMenu->insertItem(penColorPixmap, i); } QToolTip::add(m_pPenColorToolButton, tr("Pen Color")); m_pPenColorToolButton->setPopup(penColorPopupMenu); m_pPenColorToolButton->setPopupDelay(0); penColorPopupMenu->activateItemAt(0); m_pBrushColorToolButton = new QToolButton(drawParametersToolBar); m_pBrushColorToolButton->setPixmap(Resource::loadPixmap("drawpad/brushcolor.png")); QPopupMenu* brushColorPopupMenu = new QPopupMenu(m_pBrushColorToolButton); connect(brushColorPopupMenu, SIGNAL(activated(int)), this, SLOT(changeBrushColor(int))); QPixmap brushColorPixmap(14, 14); for (uint i = 0; i < m_colors.size(); i++) { brushColorPixmap.fill(m_colors.at(i)); brushColorPopupMenu->insertItem(brushColorPixmap, i); } QToolTip::add(m_pBrushColorToolButton, tr("Fill Color")); m_pBrushColorToolButton->setPopup(brushColorPopupMenu); m_pBrushColorToolButton->setPopupDelay(0); brushColorPopupMenu->activateItemAt(1); } DrawPad::~DrawPad() { QFile file(Global::applicationFileName("drawpad", "drawpad.xml")); if (file.open(IO_WriteOnly)) { m_pDrawPadCanvas->save(&file); file.close(); } } -void DrawPad::clearAll() -{ - m_pDrawPadCanvas->clearAll(); - updateNavigationToolBar(); -} - -void DrawPad::newPage() -{ - m_pDrawPadCanvas->newPage(); - updateNavigationToolBar(); -} - -void DrawPad::deletePage() -{ - m_pDrawPadCanvas->deletePage(); - updateNavigationToolBar(); -} - -void DrawPad::goFirstPage() -{ - m_pDrawPadCanvas->goFirstPage(); - updateNavigationToolBar(); -} - -void DrawPad::goPreviousPage() -{ - m_pDrawPadCanvas->goPreviousPage(); - updateNavigationToolBar(); -} - -void DrawPad::goNextPage() -{ - m_pDrawPadCanvas->goNextPage(); - updateNavigationToolBar(); -} - -void DrawPad::goLastPage() -{ - m_pDrawPadCanvas->goLastPage(); - updateNavigationToolBar(); -} - void DrawPad::setPointDrawMode() { if (m_pDrawMode) { delete m_pDrawMode; } m_pDrawMode = new PointDrawMode(this, m_pDrawPadCanvas); m_pPointDrawModeAction->setOn(true); m_pLineDrawModeAction->setOn(false); m_pRectangleDrawModeAction->setOn(false); m_pEllipseDrawModeAction->setOn(false); m_pFillDrawModeAction->setOn(false); m_pEraseDrawModeAction->setOn(false); } void DrawPad::setLineDrawMode() { if (m_pDrawMode) { delete m_pDrawMode; } m_pDrawMode = new LineDrawMode(this, m_pDrawPadCanvas); m_pPointDrawModeAction->setOn(false); m_pLineDrawModeAction->setOn(true); m_pRectangleDrawModeAction->setOn(false); m_pEllipseDrawModeAction->setOn(false); m_pFillDrawModeAction->setOn(false); m_pEraseDrawModeAction->setOn(false); } void DrawPad::setRectangleDrawMode() { if (m_pDrawMode) { delete m_pDrawMode; } m_pDrawMode = new RectangleDrawMode(this, m_pDrawPadCanvas); m_pPointDrawModeAction->setOn(false); m_pLineDrawModeAction->setOn(false); m_pRectangleDrawModeAction->setOn(true); m_pEllipseDrawModeAction->setOn(false); m_pFillDrawModeAction->setOn(false); m_pEraseDrawModeAction->setOn(false); } void DrawPad::setEllipseDrawMode() { if (m_pDrawMode) { delete m_pDrawMode; } m_pDrawMode = new EllipseDrawMode(this, m_pDrawPadCanvas); m_pPointDrawModeAction->setOn(false); m_pLineDrawModeAction->setOn(false); m_pRectangleDrawModeAction->setOn(false); m_pEllipseDrawModeAction->setOn(true); m_pFillDrawModeAction->setOn(false); m_pEraseDrawModeAction->setOn(false); } void DrawPad::setFillDrawMode() { if (m_pDrawMode) { delete m_pDrawMode; } m_pDrawMode = new FillDrawMode(this, m_pDrawPadCanvas); m_pPointDrawModeAction->setOn(false); m_pLineDrawModeAction->setOn(false); m_pRectangleDrawModeAction->setOn(false); m_pEllipseDrawModeAction->setOn(false); m_pFillDrawModeAction->setOn(true); m_pEraseDrawModeAction->setOn(false); } void DrawPad::setEraseDrawMode() { if (m_pDrawMode) { delete m_pDrawMode; } m_pDrawMode = new EraseDrawMode(this, m_pDrawPadCanvas); m_pPointDrawModeAction->setOn(false); m_pLineDrawModeAction->setOn(false); m_pRectangleDrawModeAction->setOn(false); m_pEllipseDrawModeAction->setOn(false); m_pFillDrawModeAction->setOn(false); m_pEraseDrawModeAction->setOn(true); } void DrawPad::changePenWidth(int value) { m_pen.setWidth(value); } void DrawPad::changePenColor(int index) { m_pen.setColor(m_colors.at(index)); QPainter painter; painter.begin(m_pPenColorToolButton->pixmap()); painter.fillRect(QRect(0, 12, 14, 2), m_pen.color()); painter.end(); } void DrawPad::changeBrushColor(int index) { m_brush = QBrush(m_colors.at(index)); QPainter painter; painter.begin(m_pBrushColorToolButton->pixmap()); painter.fillRect(QRect(0, 12, 14, 2), m_brush.color()); painter.end(); } -void DrawPad::updateNavigationToolBar() +void DrawPad::updateUndoRedoToolButtons() +{ + m_pUndoAction->setEnabled(m_pDrawPadCanvas->undoEnabled()); + m_pRedoAction->setEnabled(m_pDrawPadCanvas->redoEnabled()); +} + +void DrawPad::updateNavigationToolButtons() { m_pFirstPageAction->setEnabled(m_pDrawPadCanvas->goPreviousPageEnabled()); m_pPreviousPageAction->setEnabled(m_pDrawPadCanvas->goPreviousPageEnabled()); m_pNextPageAction->setEnabled(m_pDrawPadCanvas->goNextPageEnabled()); m_pLastPageAction->setEnabled(m_pDrawPadCanvas->goNextPageEnabled()); } diff --git a/noncore/graphics/drawpad/drawpad.h b/noncore/graphics/drawpad/drawpad.h index 0ece408..ee81ddf 100644 --- a/noncore/graphics/drawpad/drawpad.h +++ b/noncore/graphics/drawpad/drawpad.h @@ -1,88 +1,83 @@ /*************************************************************************** * * * DrawPad - a drawing program for Opie Environment * * * * (C) 2002 by S. Prud'homme <prudhomme@laposte.net> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DRAWPAD_H #define DRAWPAD_H #include <qmainwindow.h> #include <qpen.h> class DrawMode; class DrawPadCanvas; class QAction; class QColor; class QToolButton; class QWidgetStack; class DrawPad : public QMainWindow { Q_OBJECT public: DrawPad(QWidget* parent = 0, const char* name = 0, WFlags f = WType_TopLevel); ~DrawPad(); DrawMode* drawMode() { return m_pDrawMode; } QPen pen() { return m_pen; } QBrush brush() { return m_brush; } private slots: - void clearAll(); - void newPage(); - void deletePage(); - - void goFirstPage(); - void goPreviousPage(); - void goNextPage(); - void goLastPage(); - void setPointDrawMode(); void setLineDrawMode(); void setRectangleDrawMode(); void setEllipseDrawMode(); void setFillDrawMode(); void setEraseDrawMode(); void changePenWidth(int value); void changePenColor(int index); void changeBrushColor(int index); -private: - void updateNavigationToolBar(); + void updateUndoRedoToolButtons(); + void updateNavigationToolButtons(); +private: DrawPadCanvas* m_pDrawPadCanvas; QArray<QColor> m_colors; DrawMode* m_pDrawMode; QPen m_pen; QBrush m_brush; + QAction* m_pUndoAction; + QAction* m_pRedoAction; + QAction* m_pFirstPageAction; QAction* m_pPreviousPageAction; QAction* m_pNextPageAction; QAction* m_pLastPageAction; QAction* m_pPointDrawModeAction; QAction* m_pLineDrawModeAction; QAction* m_pRectangleDrawModeAction; QAction* m_pEllipseDrawModeAction; QAction* m_pFillDrawModeAction; QAction* m_pEraseDrawModeAction; QToolButton* m_pPenColorToolButton; QToolButton* m_pBrushColorToolButton; }; #endif // DRAWPAD_H diff --git a/noncore/graphics/drawpad/drawpadcanvas.cpp b/noncore/graphics/drawpad/drawpadcanvas.cpp index f02f478..08f7b66 100644 --- a/noncore/graphics/drawpad/drawpadcanvas.cpp +++ b/noncore/graphics/drawpad/drawpadcanvas.cpp @@ -1,339 +1,420 @@ /*************************************************************************** * * * DrawPad - a drawing program for Opie Environment * * * * (C) 2002 by S. Prud'homme <prudhomme@laposte.net> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "drawpadcanvas.h" #include "drawmode.h" #include "drawpad.h" #include <qbuffer.h> #include <qimage.h> #include <qpainter.h> #include <qpixmap.h> #include <qtextcodec.h> #include <qtextstream.h> #include <qxml.h> #include <zlib.h> class DrawPadCanvasXmlHandler: public QXmlDefaultHandler { public: DrawPadCanvasXmlHandler(); ~DrawPadCanvasXmlHandler(); QList<QPixmap> pixmaps(); bool startElement(const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts); bool endElement(const QString& namespaceURI, const QString& localName, const QString& qName); bool characters(const QString& ch); private: enum State { Unknown, InData }; State m_state; ulong m_dataLenght; QList<QPixmap> m_pixmaps; }; DrawPadCanvasXmlHandler::DrawPadCanvasXmlHandler() { m_state = Unknown; } DrawPadCanvasXmlHandler::~DrawPadCanvasXmlHandler() { } QList<QPixmap> DrawPadCanvasXmlHandler::pixmaps() { return m_pixmaps; } bool DrawPadCanvasXmlHandler::startElement(const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts) { Q_CONST_UNUSED(namespaceURI) Q_CONST_UNUSED(localName) if (qName.compare("data") == 0) { m_state = InData; m_dataLenght = atts.value("length").toULong(); } return true; } bool DrawPadCanvasXmlHandler::endElement(const QString& namespaceURI, const QString& localName, const QString& qName) { Q_CONST_UNUSED(namespaceURI) Q_CONST_UNUSED(localName) if (qName.compare("data") == 0) { m_state = Unknown; } return true; } bool DrawPadCanvasXmlHandler::characters(const QString& ch) { if (m_state == InData) { QByteArray byteArray(ch.length() / 2); for (int i = 0; i < (int)ch.length() / 2; i++) { char h = ch[2 * i].latin1(); char l = ch[2 * i + 1].latin1(); uchar r = 0; if (h <= '9') { r += h - '0'; } else { r += h - 'a' + 10; } r = r << 4; if (l <= '9') { r += l - '0'; } else { r += l - 'a' + 10; } byteArray[i] = r; } if (m_dataLenght < ch.length() * 5) { m_dataLenght = ch.length() * 5; } QByteArray byteArrayUnzipped(m_dataLenght); ::uncompress((uchar*)byteArrayUnzipped.data(), &m_dataLenght, (uchar*)byteArray.data(), byteArray.size()); QImage image; image.loadFromData((const uchar*)byteArrayUnzipped.data(), m_dataLenght, "XPM"); QPixmap* pixmap = new QPixmap(image.width(), image.height()); pixmap->convertFromImage(image); m_pixmaps.append(pixmap); } return true; } DrawPadCanvas::DrawPadCanvas(DrawPad* drawPad, QWidget* parent, const char* name, WFlags f) : QWidget(parent, name, f) { setBackgroundMode(QWidget::PaletteBase); m_pDrawPad = drawPad; - m_buffers.setAutoDelete(true); - m_buffers.append(new QPixmap(width(), height())); - m_buffers.current()->fill(Qt::white); + m_pages.setAutoDelete(true); + m_pages.append(new QPixmap(width(), height())); + m_pages.current()->fill(Qt::white); + m_pageBackups.setAutoDelete(true); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); } DrawPadCanvas::~DrawPadCanvas() { } void DrawPadCanvas::load(QIODevice* ioDevice) { QTextStream textStream(ioDevice); textStream.setCodec(QTextCodec::codecForName("UTF-8")); QXmlInputSource xmlInputSource(textStream); QXmlSimpleReader xmlSimpleReader; DrawPadCanvasXmlHandler drawPadCanvasXmlHandler; xmlSimpleReader.setContentHandler(&drawPadCanvasXmlHandler); xmlSimpleReader.parse(xmlInputSource); - m_buffers = drawPadCanvasXmlHandler.pixmaps(); + m_pages = drawPadCanvasXmlHandler.pixmaps(); - if (m_buffers.isEmpty()) { - m_buffers.append(new QPixmap(width(), height())); - m_buffers.current()->fill(Qt::white); + if (m_pages.isEmpty()) { + m_pages.append(new QPixmap(width(), height())); + m_pages.current()->fill(Qt::white); } + m_pageBackups.clear(); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); + repaint(); } void DrawPadCanvas::save(QIODevice* ioDevice) { QTextStream textStream(ioDevice); textStream.setCodec(QTextCodec::codecForName("UTF-8")); textStream << "<drawpad>" << endl; textStream << " <images>" << endl; - QListIterator<QPixmap> bufferIterator(m_buffers); + QListIterator<QPixmap> bufferIterator(m_pages); for (bufferIterator.toFirst(); bufferIterator.current() != 0; ++bufferIterator) { textStream << " <image>" << endl; QImage image = bufferIterator.current()->convertToImage(); QByteArray byteArray; QBuffer buffer(byteArray); QImageIO imageIO(&buffer, "XPM"); buffer.open(IO_WriteOnly); imageIO.setImage(image); imageIO.write(); buffer.close(); ulong size = byteArray.size() * 2; QByteArray byteArrayZipped(size); ::compress((uchar*)byteArrayZipped.data(), &size, (uchar*)byteArray.data(), byteArray.size()); textStream << " <data length=\"" << byteArray.size() << "\">"; static const char hexchars[] = "0123456789abcdef"; for (int i = 0; i < (int)size; i++ ) { uchar s = (uchar)byteArrayZipped[i]; textStream << hexchars[s >> 4]; textStream << hexchars[s & 0x0f]; } textStream << "</data>" << endl; textStream << " </image>" << endl; } textStream << " </images>" << endl; textStream << "</drawpad>"; } QPixmap* DrawPadCanvas::currentPage() { - return m_buffers.current(); + return m_pages.current(); } void DrawPadCanvas::clearAll() { - m_buffers.clear(); + m_pages.clear(); + + m_pages.append(new QPixmap(width(), height())); + m_pages.current()->fill(Qt::white); - m_buffers.append(new QPixmap(width(), height())); - m_buffers.current()->fill(Qt::white); + m_pageBackups.clear(); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); repaint(); + + emit pagesChanged(); + emit pageBackupsChanged(); } void DrawPadCanvas::newPage() { - m_buffers.insert(m_buffers.at() + 1, new QPixmap(width(), height())); - m_buffers.current()->fill(Qt::white); + m_pages.insert(m_pages.at() + 1, new QPixmap(width(), height())); + m_pages.current()->fill(Qt::white); + m_pageBackups.clear(); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); repaint(); + + emit pagesChanged(); + emit pageBackupsChanged(); } void DrawPadCanvas::clearPage() { - m_buffers.current()->fill(Qt::white); + m_pages.current()->fill(Qt::white); repaint(); } void DrawPadCanvas::deletePage() { - m_buffers.remove(m_buffers.current()); + m_pages.remove(m_pages.current()); - if (m_buffers.isEmpty()) { - m_buffers.append(new QPixmap(width(), height())); - m_buffers.current()->fill(Qt::white); + if (m_pages.isEmpty()) { + m_pages.append(new QPixmap(width(), height())); + m_pages.current()->fill(Qt::white); } + m_pageBackups.clear(); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); + repaint(); + + emit pagesChanged(); + emit pageBackupsChanged(); +} + +bool DrawPadCanvas::undoEnabled() +{ + return (m_pageBackups.current() != m_pageBackups.getFirst()); +} + +bool DrawPadCanvas::redoEnabled() +{ + return (m_pageBackups.current() != m_pageBackups.getLast()); } bool DrawPadCanvas::goPreviousPageEnabled() { - return (m_buffers.current() != m_buffers.getFirst()); + return (m_pages.current() != m_pages.getFirst()); } bool DrawPadCanvas::goNextPageEnabled() { - return (m_buffers.current() != m_buffers.getLast()); + return (m_pages.current() != m_pages.getLast()); +} + +void DrawPadCanvas::undo() +{ + *(m_pages.current()) = *(m_pageBackups.prev()); + repaint(); + + emit pageBackupsChanged(); +} + +void DrawPadCanvas::redo() +{ + *(m_pages.current()) = *(m_pageBackups.next()); + repaint(); + + emit pageBackupsChanged(); } void DrawPadCanvas::goFirstPage() { - m_buffers.first(); + m_pages.first(); + m_pageBackups.clear(); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); repaint(); + + emit pagesChanged(); + emit pageBackupsChanged(); } void DrawPadCanvas::goPreviousPage() { - m_buffers.prev(); + m_pages.prev(); + m_pageBackups.clear(); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); repaint(); + + emit pagesChanged(); + emit pageBackupsChanged(); } void DrawPadCanvas::goNextPage() { - m_buffers.next(); + m_pages.next(); + m_pageBackups.clear(); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); repaint(); + + emit pagesChanged(); + emit pageBackupsChanged(); } void DrawPadCanvas::goLastPage() { - m_buffers.last(); + m_pages.last(); + m_pageBackups.clear(); + m_pageBackups.append(new QPixmap(*(m_pages.current()))); repaint(); + + emit pagesChanged(); + emit pageBackupsChanged(); } void DrawPadCanvas::mousePressEvent(QMouseEvent* e) { m_pDrawPad->drawMode()->mousePressEvent(e); } void DrawPadCanvas::mouseReleaseEvent(QMouseEvent* e) { m_pDrawPad->drawMode()->mouseReleaseEvent(e); + + QPixmap* currentBackup = m_pageBackups.current(); + while (m_pageBackups.last() != currentBackup) { + m_pageBackups.removeLast(); + } + + while (m_pageBackups.count() >= (5 + 1)) { + m_pageBackups.removeFirst(); + } + + m_pageBackups.append(new QPixmap(*(m_pages.current()))); + + emit pageBackupsChanged(); } void DrawPadCanvas::mouseMoveEvent(QMouseEvent* e) { m_pDrawPad->drawMode()->mouseMoveEvent(e); } void DrawPadCanvas::resizeEvent(QResizeEvent* e) { QWidget::resizeEvent(e); - QListIterator<QPixmap> bufferIterator(m_buffers); + QListIterator<QPixmap> bufferIterator(m_pages); for (bufferIterator.toFirst(); bufferIterator.current() != 0; ++bufferIterator) { int w = width() > bufferIterator.current()->width() ? width() : bufferIterator.current()->width(); int h = height() > bufferIterator.current()->height() ? height() : bufferIterator.current()->height(); QPixmap tmpPixmap(*(bufferIterator.current())); bufferIterator.current()->resize(w, h); bufferIterator.current()->fill(Qt::white); bitBlt(bufferIterator.current(), 0, 0, &tmpPixmap, 0, 0, tmpPixmap.width(), tmpPixmap.height()); } } void DrawPadCanvas::paintEvent(QPaintEvent* e) { QWidget::paintEvent(e); QArray<QRect> rects = e->region().rects(); for (uint i = 0; i < rects.count(); i++) { QRect r = rects[i]; - bitBlt(this, r.x(), r.y(), m_buffers.current(), r.x(), r.y(), r.width(), r.height()); + bitBlt(this, r.x(), r.y(), m_pages.current(), r.x(), r.y(), r.width(), r.height()); } } diff --git a/noncore/graphics/drawpad/drawpadcanvas.h b/noncore/graphics/drawpad/drawpadcanvas.h index 2ec9298..eddcb43 100644 --- a/noncore/graphics/drawpad/drawpadcanvas.h +++ b/noncore/graphics/drawpad/drawpadcanvas.h @@ -1,65 +1,75 @@ /*************************************************************************** * * * DrawPad - a drawing program for Opie Environment * * * * (C) 2002 by S. Prud'homme <prudhomme@laposte.net> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DRAWPADCANVAS_H #define DRAWPADCANVAS_H #include <qwidget.h> #include <qlist.h> #include <qpointarray.h> class DrawPad; class QPixmap; class DrawPadCanvas : public QWidget { Q_OBJECT public: DrawPadCanvas(DrawPad* drawPad, QWidget* parent = 0, const char* name = 0, WFlags f = 0); ~DrawPadCanvas(); void load(QIODevice* ioDevice); void save(QIODevice* ioDevice); + bool undoEnabled(); + bool redoEnabled(); bool goPreviousPageEnabled(); bool goNextPageEnabled(); QPixmap* currentPage(); public slots: void clearAll(); void newPage(); void clearPage(); void deletePage(); + void undo(); + void redo(); + void goFirstPage(); void goPreviousPage(); void goNextPage(); void goLastPage(); +signals: + void pagesChanged(); + void pageBackupsChanged(); + protected: void mousePressEvent(QMouseEvent* e); void mouseReleaseEvent(QMouseEvent* e); void mouseMoveEvent(QMouseEvent* e); void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); private: DrawPad* m_pDrawPad; - QList<QPixmap> m_buffers; + QList<QPixmap> m_pages; + QList<QPixmap> m_pageBackups; }; #endif // DRAWPADCANVAS_H |