From 10639af10e92f1818474da78add3bc0864b8da8e Mon Sep 17 00:00:00 2001 From: ruglory Date: Tue, 24 Mar 2009 22:26:57 +0000 Subject: [PATCH] Undo/redo implemented git-svn-id: https://svn.code.sf.net/p/qlscribe/svn/trunk@132 cac9541e-1b8d-4bfa-827e-589bba606050 --- src/mainwindow.cpp | 35 +++++++++++++++- src/mainwindow.h | 4 ++ src/qcdscene.cpp | 81 ++++++++++++++++++++++++++++++++++++- src/qcdscene.h | 31 ++++++++++---- src/qlightpixmapitem.cpp | 2 +- src/qlightroundtextitem.cpp | 2 +- src/qlighttextitem.cpp | 2 +- 7 files changed, 143 insertions(+), 14 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cc42105..b5805b1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -112,6 +112,16 @@ MainWindow::MainWindow( bool enablePrint ) m_menuEdit = menuBar()->addMenu( tr( "Edit", "Menu item \"Edit\"" ) ); + m_actionUndo = m_menuEdit->addAction( tr( "Undo", "Menu item \"Undo\"" ), + this, + SLOT(onMenuUndo()), + QKeySequence( Qt::CTRL + Qt::Key_Z ) ); + + m_actionRedo = m_menuEdit->addAction( tr( "Redo", "Menu item \"Redo\"" ), + this, + SLOT(onMenuRedo()), + QKeySequence( Qt::CTRL + Qt::Key_R ) ); + m_actionCopy = m_menuEdit->addAction( tr( "Copy", "Menu item \"Copy\"" ), this, SLOT(onMenuCopy()), @@ -244,10 +254,11 @@ void MainWindow::onMenuNewLabel( int mode ) { QCDView *newView = new QCDView; QCDScene *scene = new QCDScene( newView ); - scene->setLabelMode( LabelMode( mode ) ); + scene->start( LabelMode( mode ) ); newView->setScene( scene ); scene->setName(); connect( scene, SIGNAL(selectionChanged()), this, SLOT(updateMenu()) ); + connect( scene, SIGNAL(changed()), this, SLOT(updateMenu()) ); QMdiSubWindow *subWindow = m_mdiArea->addSubWindow( newView ); subWindow->show(); @@ -311,6 +322,7 @@ void MainWindow::onMenuOpen() return; } connect( scene, SIGNAL(selectionChanged()), this, SLOT(updateMenu()) ); + connect( scene, SIGNAL(changed()), this, SLOT(updateMenu()) ); QMdiSubWindow *subWindow = m_mdiArea->addSubWindow( newView ); subWindow->show(); @@ -377,6 +389,20 @@ void MainWindow::onMenuPrint() } } +void MainWindow::onMenuUndo() +{ + QCDScene *scene = getScene( m_mdiArea ); + if( scene ) + scene->undo(); +} + +void MainWindow::onMenuRedo() +{ + QCDScene *scene = getScene( m_mdiArea ); + if( scene ) + scene->redo(); +} + void MainWindow::onMenuCopy() { QCDScene *scene = getScene( m_mdiArea ); @@ -403,7 +429,7 @@ void MainWindow::onMenuAbout() QMessageBox::about( this, tr( "About" ), tr( "

qlscribe - Qt lisghtScribe

" - "

release 0.9 $Revision$

" + "

prerelease 0.10 $Revision$

" "

visit project at home page " "qlscribe.sourceforge.net

" ) ); } @@ -425,10 +451,15 @@ void MainWindow::updateMenu() m_menuInsert->setEnabled( scene ); if( !scene ) { + m_actionUndo->setEnabled( false ); + m_actionRedo->setEnabled( false ); m_actionCopy->setEnabled( false ); m_actionCut->setEnabled( false ); m_actionPaste->setEnabled( false ); } else { + m_actionUndo->setEnabled( scene->canUndo() ); + m_actionRedo->setEnabled( scene->canRedo() ); + const QMimeData *mdata = QApplication::clipboard()->mimeData(); m_actionPaste->setEnabled( mdata && mdata->hasFormat( itemMimeType ) ); diff --git a/src/mainwindow.h b/src/mainwindow.h index 56e54db..b2faa6b 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -48,6 +48,8 @@ private slots: void onMenuProperties(); void onMenuPrintPreview(); void onMenuPrint(); + void onMenuUndo(); + void onMenuRedo(); void onMenuCopy(); void onMenuCut(); void onMenuPaste(); @@ -72,6 +74,8 @@ private: QAction *m_actionLabelProperties; QAction *m_actionPrint; QAction *m_actionPrintPreview; + QAction *m_actionUndo; + QAction *m_actionRedo; QAction *m_actionCopy; QAction *m_actionCut; QAction *m_actionPaste; diff --git a/src/qcdscene.cpp b/src/qcdscene.cpp index 612acc3..85b55d1 100644 --- a/src/qcdscene.cpp +++ b/src/qcdscene.cpp @@ -39,10 +39,13 @@ QCDScene::QCDScene( QObject * parent ) : QGraphicsScene( parent ), m_index( 0 ), m_saved( true ), + m_itemMoved( false ), m_labelMode( modeFull ), - m_cdColor( Qt::white ) + m_cdColor( Qt::white ), + m_undoPosition( m_undoBuffer.end() ) { setSceneRect( -60.0, -60.0, 60.0 * 2, 60.0 * 2 ); + } //#include @@ -70,6 +73,12 @@ void QCDScene::replace( const QString2String &strings ) } } +void QCDScene::start( LabelMode mode ) +{ + setLabelMode( mode ); + pushUndo(); +} + bool QCDScene::load( const QString &fileName, QString *errMessage ) { QFile file( fileName ); @@ -94,9 +103,12 @@ bool QCDScene::load( const QString &fileName, QString *errMessage ) m_fileName = fileName; m_saved = true; setName(); + + pushUndo(); return true; } + bool QCDScene::save() { QFile file( m_fileName ); @@ -143,10 +155,32 @@ void QCDScene::setName() updateTitles(); } -void QCDScene::setChanged() +void QCDScene::setChanged( bool undo ) { m_saved = false; updateTitles(); + + if( undo && m_undoPosition != m_undoBuffer.end() ) + pushUndo(); + + emit changed(); +} + +void QCDScene::pushUndo() +{ + if( canRedo() ) { + UndoBuffer::iterator pos = m_undoBuffer.begin() + 1 + ( m_undoPosition - m_undoBuffer.begin() ); + m_undoBuffer.erase( pos, m_undoBuffer.end() ); + } + + QString data; + QXmlStreamWriter writer( &data ); + write( writer ); + m_undoBuffer.push_back( data ); + if( m_undoBuffer.size() > 20 ) + m_undoBuffer.pop_front(); + + m_undoPosition = m_undoBuffer.end() - 1; } void QCDScene::updateTitles() const @@ -330,6 +364,16 @@ void QCDScene::contextMenuEvent( QGraphicsSceneContextMenuEvent *mouseEvent ) menu.exec( mouseEvent->screenPos() ); } +void QCDScene::mouseReleaseEvent ( QGraphicsSceneMouseEvent *mouseEvent ) +{ + if( m_itemMoved ) { + setChanged(); + m_itemMoved = false; + } + + QGraphicsScene::mouseReleaseEvent( mouseEvent ); +} + void QCDScene::onMenuEdit() { QList list = selectedItems(); @@ -387,4 +431,37 @@ void QCDScene::sendItemTo( bool front ) zValue = item->zValue() - 0.1; } selectedItem->setZValue( zValue ); + setChanged(); +} + +bool QCDScene::canUndo() const +{ + return m_undoPosition - m_undoBuffer.begin() > 0; +} + +bool QCDScene::canRedo() const +{ + return m_undoBuffer.end() - m_undoPosition > 1; +} + +void QCDScene::unredo( bool undo ) +{ + if( undo ) { + if( !canUndo() ) + return; + --m_undoPosition; + } else { + if( !canRedo() ) + return; + ++m_undoPosition; + } + + try { + clear(); + QXmlStreamReader reader( *m_undoPosition ); + read( reader ); + } + catch(...) { + } + setChanged( false ); } diff --git a/src/qcdscene.h b/src/qcdscene.h index 6a863b5..c0a6c9e 100644 --- a/src/qcdscene.h +++ b/src/qcdscene.h @@ -44,13 +44,19 @@ public: bool isSaved() const { return m_saved; } bool isUnnamed() const { return m_fileName.isEmpty(); } + bool canUndo() const; + bool canRedo() const; - void setChanged(); + void itemMoved() { m_itemMoved = true; } + void setChanged( bool undo = true ); void setName(); + void start( LabelMode mode ); bool load( const QString &fileName, QString *errMessage = 0 ); void replace( const QString2String &strings ); bool save(); bool saveAs( const QString &fileName ); + void undo() { unredo( true ); } + void redo() { unredo( false ); } void putItemToClipboard( bool move ); void getItemFromClipboard(); @@ -59,8 +65,12 @@ public: void redrawViews() const; QString name() const { return m_name; } +signals: + void changed(); + protected: virtual void contextMenuEvent( QGraphicsSceneContextMenuEvent *contextMenuEvent ); + virtual void mouseReleaseEvent ( QGraphicsSceneMouseEvent *mouseEvent ); private slots: void onMenuEdit(); @@ -75,14 +85,21 @@ private: bool readItem( QXmlStreamReader &reader ); void read( QXmlStreamReader &reader ); void sendItemTo( bool front ); + void pushUndo(); + void unredo( bool undo ); private: - QString m_name; - QString m_fileName; - int m_index; - bool m_saved; - LabelMode m_labelMode; - QColor m_cdColor; + typedef QList UndoBuffer; + + QString m_name; + QString m_fileName; + int m_index; + bool m_saved; + bool m_itemMoved; + LabelMode m_labelMode; + QColor m_cdColor; + UndoBuffer m_undoBuffer; + UndoBuffer::const_iterator m_undoPosition; }; #endif //QCDSCENE_H diff --git a/src/qlightpixmapitem.cpp b/src/qlightpixmapitem.cpp index fce08c7..034a0c2 100644 --- a/src/qlightpixmapitem.cpp +++ b/src/qlightpixmapitem.cpp @@ -32,7 +32,7 @@ QLightPixmapItem::QLightPixmapItem() QVariant QLightPixmapItem::itemChange( GraphicsItemChange change, const QVariant & value ) { if( scene() && change == ItemPositionHasChanged ) - static_cast( scene() )->setChanged(); + static_cast( scene() )->itemMoved(); return value; } diff --git a/src/qlightroundtextitem.cpp b/src/qlightroundtextitem.cpp index b9e23ed..148d7ff 100644 --- a/src/qlightroundtextitem.cpp +++ b/src/qlightroundtextitem.cpp @@ -233,7 +233,7 @@ void QLightRoundTextItem::paint( QPainter *painter, const QStyleOptionGraphicsIt QVariant QLightRoundTextItem::itemChange( GraphicsItemChange change, const QVariant & value ) { if( scene() && change == ItemPositionHasChanged ) - static_cast( scene() )->setChanged(); + static_cast( scene() )->itemMoved(); return value; } diff --git a/src/qlighttextitem.cpp b/src/qlighttextitem.cpp index 6b89672..0f05cab 100644 --- a/src/qlighttextitem.cpp +++ b/src/qlighttextitem.cpp @@ -33,7 +33,7 @@ QLightTextItem::QLightTextItem() QVariant QLightTextItem::itemChange( GraphicsItemChange change, const QVariant & value ) { if( scene() && change == ItemPositionHasChanged ) - static_cast( scene() )->setChanged(); + static_cast( scene() )->itemMoved(); return value; }