From 146a7e4a43f4247e2bab6bf2551c06973c3076c2 Mon Sep 17 00:00:00 2001 From: baydam Date: Fri, 16 Jan 2015 17:39:38 +0000 Subject: [PATCH 1/7] Add Undo and Redo Command to Mesh, Triangle and Ellipse --- Commands.cpp | 24 ++++++++++++++++++++++++ Commands.h | 42 ++++++++++++++++++++++++++++++++++++++++++ MainWindow.cpp | 50 +++++++++++++++++++++++++++++++++++++++----------- MainWindow.h | 10 +++++++++- mapmap.pro | 6 ++++-- 5 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 Commands.cpp create mode 100644 Commands.h diff --git a/Commands.cpp b/Commands.cpp new file mode 100644 index 0000000..89ca53d --- /dev/null +++ b/Commands.cpp @@ -0,0 +1,24 @@ + +#include "Commands.h" + +AddShapesCommand::AddShapesCommand(MainWindow *mainWindow, uid mappingId, QUndoCommand *parent): + QUndoCommand(parent) +{ + m_mainWindow = mainWindow; + m_mappingId = mappingId; +} + +void AddShapesCommand::undo() +{ + m_mappingPtr = m_mainWindow->getMappingManager().getMappingById(m_mappingId); + m_mainWindow->deleteMapping(m_mappingId); +} + +void AddShapesCommand::redo() +{ + if(m_mappingPtr != NULL) + { + uint currentId = m_mainWindow->getMappingManager().addMapping(m_mappingPtr); + m_mainWindow->addMappingItem(currentId); + } +} diff --git a/Commands.h b/Commands.h new file mode 100644 index 0000000..bec7ebd --- /dev/null +++ b/Commands.h @@ -0,0 +1,42 @@ +/* + * Commands.h + * + * (c) 2014 Sofian Audry -- info(@)sofianaudry(.)com + * (c) 2014 Alexandre Quessy -- alexandre(@)quessy(.)net + * (c) 2014 Dame Diongue -- baydamd(@)gmail(.)com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef COMMANDS_H_ +#define COMMANDS_H_ + +#include +#include "MainWindow.h" + +class AddShapesCommand : public QUndoCommand +{ +public: + AddShapesCommand(MainWindow *mainWindow, uid mappingId, QUndoCommand *parent = 0); + void undo(); + void redo(); + +private: + MainWindow *m_mainWindow; + Mapping::ptr m_mappingPtr; + uid m_mappingId; + +}; + +#endif /* COMMANDS_H_ */ diff --git a/MainWindow.cpp b/MainWindow.cpp index d7408b6..a52ebc9 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -19,6 +19,7 @@ */ #include "MainWindow.h" +#include "Commands.h" #include "ProjectWriter.h" #include "ProjectReader.h" #include @@ -27,6 +28,9 @@ MainWindow::MainWindow() { + // UndoStack + undoStack = new QUndoStack(this); + // Create model. if (Media::hasVideoSupport()) std::cout << "Video support: yes" << std::endl; @@ -53,6 +57,8 @@ MainWindow::MainWindow() createContextMenu(); createToolBars(); createStatusBar(); + + // Update Recent files and video updateRecentFileActions(); updateRecentVideoActions(); @@ -525,6 +531,9 @@ void MainWindow::addMesh() Mapping::ptr mapping(mappingPtr); uint mappingId = mappingManager->addMapping(mapping); addMappingItem(mappingId); + + // Implement undoStack Commands + undoStack->push(new AddShapesCommand(this, mappingId)); } void MainWindow::addTriangle() @@ -561,6 +570,9 @@ void MainWindow::addTriangle() Mapping::ptr mapping(mappingPtr); uint mappingId = mappingManager->addMapping(mapping); addMappingItem(mappingId); + + // Implement undoStack Commands + undoStack->push(new AddShapesCommand(this, mappingId)); } void MainWindow::addEllipse() @@ -597,6 +609,9 @@ void MainWindow::addEllipse() Mapping::ptr mapping(mappingPtr); uint mappingId = mappingManager->addMapping(mapping); addMappingItem(mappingId); + + // Implement undoStack Commands + undoStack->push(new AddShapesCommand(this, mappingId)); } void MainWindow::play() @@ -1201,11 +1216,15 @@ void MainWindow::createActions() connect(recentVideoActions[i], SIGNAL(triggered()), this, SLOT(openRecentVideo())); } - // Clear action + // Clear recent video list action clearRecentFileActions = new QAction(this); clearRecentFileActions->setVisible(true); connect(clearRecentFileActions, SIGNAL(triggered()), this, SLOT(clearRecentFileList())); + // Empty list of recent video action + emptyRecentVideos = new QAction(tr("No Videos"), this); + emptyRecentVideos->setEnabled(false); + // Import video. importVideoAction = new QAction(tr("&Import media source file..."), this); @@ -1254,6 +1273,16 @@ void MainWindow::createActions() // connect(pasteAction, SIGNAL(triggered()), spreadsheet, SLOT(paste())); // + // Undo action + undoAction = undoStack->createUndoAction(editMenu, tr("&Undo")); + undoAction->setShortcut(QKeySequence::Undo); + undoAction->setIconVisibleInMenu(false); + + //Redo action + redoAction = undoStack->createRedoAction(editMenu, tr("&Redo")); + redoAction->setShortcut(QKeySequence::Redo); + redoAction->setIconVisibleInMenu(false); + // About. aboutAction = new QAction(tr("&About"), this); aboutAction->setStatusTip(tr("Show the application's About box")); @@ -1445,6 +1474,7 @@ void MainWindow::createMenus() // Recent import video recentVideoMenu = fileMenu->addMenu(tr("Recents video")); + recentVideoMenu->addAction(emptyRecentVideos); for (int i = 0; i < MaxRecentVideo; ++i) recentVideoMenu->addAction(recentVideoActions[i]); @@ -1455,6 +1485,8 @@ void MainWindow::createMenus() // Edit. editMenu = menuBar->addMenu(tr("&Edit")); + editMenu->addAction(undoAction); + editMenu->addAction(redoAction); // editMenu->addAction(cutAction); // editMenu->addAction(copyAction); // editMenu->addAction(pasteAction); @@ -1504,7 +1536,7 @@ void MainWindow::createContextMenu() // spreadsheet->addAction(cutAction); // spreadsheet->addAction(copyAction); // spreadsheet->addAction(pasteAction); -// spreadsheet->setContextMenuPolicy(Qt::ActionsContextMenu); + // spreadsheet->setContextMenuPolicy(Qt::ActionsContextMenu); } void MainWindow::createToolBars() @@ -1606,8 +1638,6 @@ void MainWindow::readSettings() } config_osc_receive_port = settings.value("osc_receive_port", 12345).toInt(); - updateRecentFileActions(); - updateRecentVideoActions(); } void MainWindow::writeSettings() @@ -1776,9 +1806,9 @@ void MainWindow::updateRecentFileActions() void MainWindow::updateRecentVideoActions() { recentVideos = settings.value("recentVideos").toStringList(); - int numRecentVidoes = qMin(recentVideos.size(), int(MaxRecentVideo)); + int numRecentVideos = qMin(recentVideos.size(), int(MaxRecentVideo)); - for (int i = 0; i < numRecentVidoes; ++i) + for (int i = 0; i < numRecentVideos; ++i) { QString text = tr("&%1 %2") .arg(i + 1) @@ -1788,14 +1818,12 @@ void MainWindow::updateRecentVideoActions() recentVideoActions[i]->setVisible(true); } - for (int j = numRecentVidoes; j < MaxRecentVideo; ++j) + for (int j = numRecentVideos; j < MaxRecentVideo; ++j) recentVideoActions[j]->setVisible(false); - if (numRecentVidoes <= 0) + if (numRecentVideos > 0) { - QAction *noVideos = new QAction(tr("No Videos"), this); - noVideos->setEnabled(false); - recentVideoMenu->addAction(noVideos); + emptyRecentVideos->setVisible(false); } } diff --git a/MainWindow.h b/MainWindow.h index a99770a..e2b7ee7 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -21,7 +21,7 @@ #ifndef MAIN_WINDOW_H_ #define MAIN_WINDOW_H_ -#include +#include #include #include #include @@ -262,6 +262,8 @@ private: QAction *saveAction; QAction *saveAsAction; QAction *exitAction; + QAction *undoAction; + QAction *redoAction; // QAction *cutAction; // QAction *copyAction; // QAction *pasteAction; @@ -269,6 +271,7 @@ private: QAction *preferencesAction; QAction *aboutAction; QAction *clearRecentFileActions; + QAction *emptyRecentVideos; QAction *addMeshAction; QAction *addTriangleAction; @@ -352,6 +355,11 @@ private: PreferencesDialog* _preferences_dialog; + // UndoStack + QUndoStack *undoStack; + + + public: // Accessor/mutators for the view. /////////////////////////////////////////////////////////////////// MappingManager& getMappingManager() { return *mappingManager; } diff --git a/mapmap.pro b/mapmap.pro index b85f270..5121ebc 100644 --- a/mapmap.pro +++ b/mapmap.pro @@ -27,7 +27,8 @@ HEADERS = \ Shape.h \ SourceGLCanvas.h \ UidAllocator.h \ - Util.h + Util.h \ + Commands.h SOURCES = \ DestinationGLCanvas.cpp \ @@ -51,7 +52,8 @@ SOURCES = \ SourceGLCanvas.cpp \ UidAllocator.cpp \ Util.cpp \ - main.cpp + main.cpp \ + Commands.cpp RESOURCES = mapmap.qrc TRANSLATIONS = resources/texts/mapmap_*.ts From 078a27f8ceca3f168ab52daae140044ebc06b239 Mon Sep 17 00:00:00 2001 From: baydam Date: Mon, 19 Jan 2015 14:35:19 +0000 Subject: [PATCH 2/7] Undo Command to restore position of vertices moved by mouse or arrow key --- Commands.cpp | 26 ++++++++++++++++++++++++++ Commands.h | 19 +++++++++++++++++++ MainWindow.h | 3 +++ MapperGLCanvas.cpp | 11 +++++------ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/Commands.cpp b/Commands.cpp index 89ca53d..5f09aa9 100644 --- a/Commands.cpp +++ b/Commands.cpp @@ -22,3 +22,29 @@ void AddShapesCommand::redo() m_mainWindow->addMappingItem(currentId); } } + + +MoveVertexCommand::MoveVertexCommand(MapperGLCanvas *mapperGLCanvas, Shape *shape, int activeVertex, const QPointF &point, QUndoCommand *parent) : + QUndoCommand(parent) +{ + m_mapperGLCanvas = mapperGLCanvas; + m_shape = shape; + m_activeVertex = activeVertex; + newPosition = point; + + oldPosition = m_shape->getVertex(m_activeVertex); +} + +void MoveVertexCommand::undo() +{ + m_shape->setVertex(m_activeVertex, oldPosition); + m_mapperGLCanvas->update(); + emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); +} + +void MoveVertexCommand::redo() +{ + m_shape->setVertex(m_activeVertex, newPosition); + m_mapperGLCanvas->update(); + emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); +} diff --git a/Commands.h b/Commands.h index bec7ebd..1dbeb04 100644 --- a/Commands.h +++ b/Commands.h @@ -24,6 +24,7 @@ #include #include "MainWindow.h" +#include "MapperGLCanvas.h" class AddShapesCommand : public QUndoCommand { @@ -39,4 +40,22 @@ private: }; +class MoveVertexCommand : public QUndoCommand +{ +public: + MoveVertexCommand(MapperGLCanvas *mapperGLCanvas, Shape *shape, int activeVertex, const QPointF &point, QUndoCommand *parent = 0); + void undo(); + void redo(); + +signals: + void shapeChanged(Shape*); + +private: + MapperGLCanvas *m_mapperGLCanvas; + Shape *m_shape; + int m_activeVertex; + QPointF newPosition, oldPosition; + +}; + #endif /* COMMANDS_H_ */ diff --git a/MainWindow.h b/MainWindow.h index e2b7ee7..07b6f76 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -374,6 +374,9 @@ public: void removeCurrentPaint(); void removeCurrentMapping(); + // Use the same undoStack for whole program + QUndoStack* getUndoStack() { return undoStack; } + void startFullScreen(); bool setOscPort(QString portNumber); bool setOscPort(int portNumber); diff --git a/MapperGLCanvas.cpp b/MapperGLCanvas.cpp index 72346e9..fa0ac69 100644 --- a/MapperGLCanvas.cpp +++ b/MapperGLCanvas.cpp @@ -21,6 +21,7 @@ #include "MapperGLCanvas.h" #include "MainWindow.h" +#include "Commands.h" MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, QWidget* parent, const QGLWidget * shareWidget) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent, shareWidget), @@ -202,10 +203,9 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) // Stick to vertices. if (stickyVertices()) glueVertex(shape, &p); - shape->setVertex(_activeVertex, p); - update(); - emit shapeChanged(getCurrentShape()); + // Enable to Undo and Redo when mouse move the position of vertices + getMainWindow()->getUndoStack()->push(new MoveVertexCommand(this, shape, _activeVertex, p)); } } else if (_shapeGrabbed) @@ -268,9 +268,8 @@ void MapperGLCanvas::keyPressEvent(QKeyEvent* event) break; } // TODO: this will always be called even if no arrow key has been pressed (small performance issue). - shape->setVertex(_activeVertex, p); - update(); - emit shapeChanged(getCurrentShape()); + // Enable to Undo and Redo when arrow keys move the position of vertices + getMainWindow()->getUndoStack()->push(new MoveVertexCommand(this, shape, _activeVertex, p)); } // Defer unhandled keys to parent. From e4ce6eab42c5977bd879f10e529218a2cbe43de6 Mon Sep 17 00:00:00 2001 From: baydam Date: Mon, 19 Jan 2015 21:08:02 +0000 Subject: [PATCH 3/7] Command to restore deleted mapping --- Commands.cpp | 23 +++++++++++++++++++++++ Commands.h | 21 ++++++++++++++++++--- MainWindow.cpp | 33 ++++++++++++++++++++------------- MapperGLCanvas.cpp | 6 ++++++ 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/Commands.cpp b/Commands.cpp index 5f09aa9..a99b36f 100644 --- a/Commands.cpp +++ b/Commands.cpp @@ -48,3 +48,26 @@ void MoveVertexCommand::redo() m_mapperGLCanvas->update(); emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); } + + +DeleteMappingCommand::DeleteMappingCommand(MainWindow *mainWindow, uid mappingId, QUndoCommand *parent) : + QUndoCommand(parent) +{ + m_mainWindow = mainWindow; + m_mappingId = mappingId; +} + +void DeleteMappingCommand::undo() +{ + if(m_mappingPtr != NULL) + { + uint currentId = m_mainWindow->getMappingManager().addMapping(m_mappingPtr); + m_mainWindow->addMappingItem(currentId); + } +} + +void DeleteMappingCommand::redo() +{ + m_mappingPtr = m_mainWindow->getMappingManager().getMappingById(m_mappingId); + m_mainWindow->deleteMapping(m_mappingId); +} diff --git a/Commands.h b/Commands.h index 1dbeb04..e69e1af 100644 --- a/Commands.h +++ b/Commands.h @@ -47,9 +47,6 @@ public: void undo(); void redo(); -signals: - void shapeChanged(Shape*); - private: MapperGLCanvas *m_mapperGLCanvas; Shape *m_shape; @@ -58,4 +55,22 @@ private: }; +class MoveShapesCommand : public QUndoCommand +{ + +}; + +class DeleteMappingCommand : public QUndoCommand +{ +public: + DeleteMappingCommand(MainWindow *mainWindow, uid mappingId, QUndoCommand *parent = 0); + void undo(); + void redo(); + +private: + MainWindow *m_mainWindow; + Mapping::ptr m_mappingPtr; + uid m_mappingId; +}; + #endif /* COMMANDS_H_ */ diff --git a/MainWindow.cpp b/MainWindow.cpp index a52ebc9..0096a59 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -294,37 +294,37 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) if (keyEvent->modifiers() == Qt::CTRL) { switch (keyEvent->key()) { - case Qt::Key_F: + case Qt::Key_F: outputWindow->setFullScreen(true); break; - case Qt::Key_N: + case Qt::Key_N: newFile(); break; - case Qt::Key_O: + case Qt::Key_O: open(); break; - case Qt::Key_S: + case Qt::Key_S: save(); break; - case Qt::Key_Q: + case Qt::Key_Q: close(); break; - case Qt::Key_Delete: + case Qt::Key_Delete: deleteItem(); break; - case Qt::Key_M: + case Qt::Key_M: addMesh(); break; - case Qt::Key_T: + case Qt::Key_T: addTriangle(); break; - case Qt::Key_E: + case Qt::Key_E: addEllipse(); break; - case Qt::Key_D: + case Qt::Key_D: outputWindow->setVisible(true); break; - case Qt::Key_P: + case Qt::Key_P: if (_isPlaying) { pause(); @@ -334,11 +334,18 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) play(); } break; - case Qt::Key_R: + case Qt::Key_R: rewind(); break; + case Qt::Key_Z: + undoStack->undo(); + break; } } + else if (keyEvent->matches(QKeySequence::Redo)) + { + undoStack->redo(); + } else if (keyEvent->key() == Qt::Key_Escape) { outputWindow->setFullScreen(false); @@ -698,7 +705,7 @@ void MainWindow::deleteItem() if (isMappingTabSelected) //currentSelectedItem->listWidget() == mappingList) { // Delete mapping. - deleteMapping( getItemId(*mappingList->currentItem()) ); + undoStack->push(new DeleteMappingCommand(this, getItemId(*mappingList->currentItem()))); //currentSelectedItem = NULL; } else if (isPaintTabSelected) //currentSelectedItem->listWidget() == paintList) diff --git a/MapperGLCanvas.cpp b/MapperGLCanvas.cpp index fa0ac69..299f0fb 100644 --- a/MapperGLCanvas.cpp +++ b/MapperGLCanvas.cpp @@ -264,6 +264,12 @@ void MapperGLCanvas::keyPressEvent(QKeyEvent* event) p.rx()--; break; default: + if (event->matches(QKeySequence::Undo)) + getMainWindow()->getUndoStack()->undo(); + + else if (event->matches(QKeySequence::Redo)) + getMainWindow()->getUndoStack()->redo(); + handledKey = false; break; } From f3351273694348c7137d4872f036e92bf84d5b43 Mon Sep 17 00:00:00 2001 From: baydam Date: Wed, 21 Jan 2015 12:47:17 +0000 Subject: [PATCH 4/7] Can restore last position of moved shapes --- Commands.cpp | 27 +++++++++++++++++++++++++++ Commands.h | 9 +++++++++ MapperGLCanvas.cpp | 22 +++++++++++++--------- MapperGLCanvas.h | 4 ++++ 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/Commands.cpp b/Commands.cpp index a99b36f..782107d 100644 --- a/Commands.cpp +++ b/Commands.cpp @@ -50,6 +50,33 @@ void MoveVertexCommand::redo() } +MoveShapesCommand::MoveShapesCommand(MapperGLCanvas *mapperGLCanvas, Shape *shape, QMouseEvent *event, const QPointF &point, QUndoCommand *parent) : + QUndoCommand(parent) +{ + m_mapperGLCanvas = mapperGLCanvas; + m_shape = shape; + m_event = event; + newPosition = point; +} + +void MoveShapesCommand::undo() +{ + m_shape->translate(oldPosition.x(), oldPosition.y()); + m_mapperGLCanvas->update(); + emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); +} + +void MoveShapesCommand::redo() +{ + m_shape->translate(m_event->x() - newPosition.x(), m_event->y() - newPosition.y()); + m_mapperGLCanvas->update(); + emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); + + oldPosition.setX(newPosition.x() - m_event->x()); + oldPosition.setY(newPosition.y() - m_event->y()); +} + + DeleteMappingCommand::DeleteMappingCommand(MainWindow *mainWindow, uid mappingId, QUndoCommand *parent) : QUndoCommand(parent) { diff --git a/Commands.h b/Commands.h index e69e1af..b83cb4c 100644 --- a/Commands.h +++ b/Commands.h @@ -57,7 +57,16 @@ private: class MoveShapesCommand : public QUndoCommand { +public: + MoveShapesCommand(MapperGLCanvas *mapperGLCanvas, Shape *shape, QMouseEvent *event, const QPointF &point, QUndoCommand *parent = 0); + void undo(); + void redo(); +private: + MapperGLCanvas *m_mapperGLCanvas; + Shape *m_shape; + QMouseEvent *m_event; + QPointF newPosition, oldPosition; }; class DeleteMappingCommand : public QUndoCommand diff --git a/MapperGLCanvas.cpp b/MapperGLCanvas.cpp index 299f0fb..eee6d87 100644 --- a/MapperGLCanvas.cpp +++ b/MapperGLCanvas.cpp @@ -189,6 +189,9 @@ void MapperGLCanvas::mouseReleaseEvent(QMouseEvent* event) void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) { + // Prepare to store commands + undoStack = getMainWindow()->getUndoStack(); + if (_mousePressedOnVertex) { // std::cout << "Move event " << std::endl; @@ -205,7 +208,7 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) glueVertex(shape, &p); // Enable to Undo and Redo when mouse move the position of vertices - getMainWindow()->getUndoStack()->push(new MoveVertexCommand(this, shape, _activeVertex, p)); + undoStack->push(new MoveVertexCommand(this, shape, _activeVertex, p)); } } else if (_shapeGrabbed) @@ -217,9 +220,7 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) { if (!_shapeFirstGrab) { - shape->translate(event->x() - prevMousePosition.x(), event->y() - prevMousePosition.y()); - update(); - emit shapeChanged(getCurrentShape()); + undoStack->push(new MoveShapesCommand(this, shape, event, prevMousePosition)); } else _shapeFirstGrab = false; @@ -232,6 +233,9 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) void MapperGLCanvas::keyPressEvent(QKeyEvent* event) { + // Prepare to store commands + undoStack = getMainWindow()->getUndoStack(); + // Checks if the key has been handled by this function or needs to be deferred to superclass. bool handledKey = false; @@ -265,17 +269,17 @@ void MapperGLCanvas::keyPressEvent(QKeyEvent* event) break; default: if (event->matches(QKeySequence::Undo)) - getMainWindow()->getUndoStack()->undo(); + undoStack->undo(); else if (event->matches(QKeySequence::Redo)) - getMainWindow()->getUndoStack()->redo(); - - handledKey = false; + undoStack->redo(); + else + handledKey = false; break; } // TODO: this will always be called even if no arrow key has been pressed (small performance issue). // Enable to Undo and Redo when arrow keys move the position of vertices - getMainWindow()->getUndoStack()->push(new MoveVertexCommand(this, shape, _activeVertex, p)); + undoStack->push(new MoveVertexCommand(this, shape, _activeVertex, p)); } // Defer unhandled keys to parent. diff --git a/MapperGLCanvas.h b/MapperGLCanvas.h index ca8ef24..9576638 100644 --- a/MapperGLCanvas.h +++ b/MapperGLCanvas.h @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -141,6 +142,9 @@ private: // True iff we want vertices to stick to each other. bool _stickyVertices; + // Pointer to MainWindow UndoStack + QUndoStack *undoStack; + signals: void shapeChanged(Shape*); void imageChanged(); From 4d6caf2cfb596b96b40dd059f0a9cd42c2fb23a9 Mon Sep 17 00:00:00 2001 From: baydam Date: Fri, 23 Jan 2015 20:36:30 +0000 Subject: [PATCH 5/7] Optimization of Undo Command --- Commands.cpp | 16 +++++++--------- Commands.h | 6 +++--- MainWindow.cpp | 14 ++++++-------- MainWindow.h | 2 +- MapperGLCanvas.cpp | 6 +++--- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/Commands.cpp b/Commands.cpp index 782107d..6958b67 100644 --- a/Commands.cpp +++ b/Commands.cpp @@ -24,37 +24,35 @@ void AddShapesCommand::redo() } -MoveVertexCommand::MoveVertexCommand(MapperGLCanvas *mapperGLCanvas, Shape *shape, int activeVertex, const QPointF &point, QUndoCommand *parent) : +MoveVertexCommand::MoveVertexCommand(MapperGLCanvas *mapperGLCanvas, int activeVertex, const QPointF &point, QUndoCommand *parent) : QUndoCommand(parent) { m_mapperGLCanvas = mapperGLCanvas; - m_shape = shape; + m_shape = m_mapperGLCanvas->getCurrentShape(); m_activeVertex = activeVertex; - newPosition = point; - - oldPosition = m_shape->getVertex(m_activeVertex); + vertexPosition = point; } void MoveVertexCommand::undo() { - m_shape->setVertex(m_activeVertex, oldPosition); + m_shape->setVertex(m_activeVertex, vertexPosition); m_mapperGLCanvas->update(); emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); } void MoveVertexCommand::redo() { - m_shape->setVertex(m_activeVertex, newPosition); + m_shape->setVertex(m_activeVertex, vertexPosition); m_mapperGLCanvas->update(); emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); } -MoveShapesCommand::MoveShapesCommand(MapperGLCanvas *mapperGLCanvas, Shape *shape, QMouseEvent *event, const QPointF &point, QUndoCommand *parent) : +MoveShapesCommand::MoveShapesCommand(MapperGLCanvas *mapperGLCanvas, QMouseEvent *event, const QPointF &point, QUndoCommand *parent) : QUndoCommand(parent) { m_mapperGLCanvas = mapperGLCanvas; - m_shape = shape; + m_shape = m_mapperGLCanvas->getCurrentShape(); m_event = event; newPosition = point; } diff --git a/Commands.h b/Commands.h index b83cb4c..7c8d155 100644 --- a/Commands.h +++ b/Commands.h @@ -43,7 +43,7 @@ private: class MoveVertexCommand : public QUndoCommand { public: - MoveVertexCommand(MapperGLCanvas *mapperGLCanvas, Shape *shape, int activeVertex, const QPointF &point, QUndoCommand *parent = 0); + MoveVertexCommand(MapperGLCanvas *mapperGLCanvas, int activeVertex, const QPointF &point, QUndoCommand *parent = 0); void undo(); void redo(); @@ -51,14 +51,14 @@ private: MapperGLCanvas *m_mapperGLCanvas; Shape *m_shape; int m_activeVertex; - QPointF newPosition, oldPosition; + QPointF vertexPosition; }; class MoveShapesCommand : public QUndoCommand { public: - MoveShapesCommand(MapperGLCanvas *mapperGLCanvas, Shape *shape, QMouseEvent *event, const QPointF &point, QUndoCommand *parent = 0); + MoveShapesCommand(MapperGLCanvas *mapperGLCanvas, QMouseEvent *event, const QPointF &point, QUndoCommand *parent = 0); void undo(); void redo(); diff --git a/MainWindow.cpp b/MainWindow.cpp index 0096a59..e5596ef 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -27,10 +27,6 @@ MainWindow::MainWindow() { - - // UndoStack - undoStack = new QUndoStack(this); - // Create model. if (Media::hasVideoSupport()) std::cout << "Video support: yes" << std::endl; @@ -58,10 +54,6 @@ MainWindow::MainWindow() createToolBars(); createStatusBar(); - // Update Recent files and video - updateRecentFileActions(); - updateRecentVideoActions(); - // Load settings. readSettings(); @@ -1175,6 +1167,9 @@ void MainWindow::createLayout() void MainWindow::createActions() { + // UndoStack + undoStack = new QUndoStack(this); + // New. newAction = new QAction(tr("&New"), this); newAction->setIcon(QIcon(":/new")); @@ -1645,6 +1640,9 @@ void MainWindow::readSettings() } config_osc_receive_port = settings.value("osc_receive_port", 12345).toInt(); + // Update Recent files and video + updateRecentFileActions(); + updateRecentVideoActions(); } void MainWindow::writeSettings() diff --git a/MainWindow.h b/MainWindow.h index 07b6f76..5e9d1b1 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -375,7 +375,7 @@ public: void removeCurrentMapping(); // Use the same undoStack for whole program - QUndoStack* getUndoStack() { return undoStack; } + QUndoStack* getUndoStack() const { return undoStack; } void startFullScreen(); bool setOscPort(QString portNumber); diff --git a/MapperGLCanvas.cpp b/MapperGLCanvas.cpp index eee6d87..9723200 100644 --- a/MapperGLCanvas.cpp +++ b/MapperGLCanvas.cpp @@ -208,7 +208,7 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) glueVertex(shape, &p); // Enable to Undo and Redo when mouse move the position of vertices - undoStack->push(new MoveVertexCommand(this, shape, _activeVertex, p)); + undoStack->push(new MoveVertexCommand(this, _activeVertex, p)); } } else if (_shapeGrabbed) @@ -220,7 +220,7 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) { if (!_shapeFirstGrab) { - undoStack->push(new MoveShapesCommand(this, shape, event, prevMousePosition)); + undoStack->push(new MoveShapesCommand(this, event, prevMousePosition)); } else _shapeFirstGrab = false; @@ -279,7 +279,7 @@ void MapperGLCanvas::keyPressEvent(QKeyEvent* event) } // TODO: this will always be called even if no arrow key has been pressed (small performance issue). // Enable to Undo and Redo when arrow keys move the position of vertices - undoStack->push(new MoveVertexCommand(this, shape, _activeVertex, p)); + undoStack->push(new MoveVertexCommand(this, _activeVertex, p)); } // Defer unhandled keys to parent. From c79e873fd35ba7f6fd9ac765bb5f103c2e3840bf Mon Sep 17 00:00:00 2001 From: baydam Date: Fri, 23 Jan 2015 20:45:12 +0000 Subject: [PATCH 6/7] Clear UndoStack when select a new file or project --- MainWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/MainWindow.cpp b/MainWindow.cpp index e5596ef..03d71c5 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -371,6 +371,7 @@ void MainWindow::newFile() { clearWindow(); setCurrentFile(""); + undoStack->clear(); } // Restart video playback. XXX Hack From 6a3545ff473a6e85ba0b69c52486e7db1e3984e6 Mon Sep 17 00:00:00 2001 From: baydam Date: Thu, 29 Jan 2015 20:39:49 +0000 Subject: [PATCH 7/7] Segmentation fault fixed --- MainWindow.cpp | 6 ++++-- MainWindow.h | 5 ++++- main.cpp | 1 - mapmap.pro | 11 ++++++----- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/MainWindow.cpp b/MainWindow.cpp index 03d71c5..b58c92a 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -1277,14 +1277,16 @@ void MainWindow::createActions() // // Undo action - undoAction = undoStack->createUndoAction(editMenu, tr("&Undo")); + undoAction = undoStack->createUndoAction(this, tr("&Undo")); undoAction->setShortcut(QKeySequence::Undo); undoAction->setIconVisibleInMenu(false); + undoAction->setShortcutContext(Qt::ApplicationShortcut); //Redo action - redoAction = undoStack->createRedoAction(editMenu, tr("&Redo")); + redoAction = undoStack->createRedoAction(this, tr("&Redo")); redoAction->setShortcut(QKeySequence::Redo); redoAction->setIconVisibleInMenu(false); + redoAction->setShortcutContext(Qt::ApplicationShortcut); // About. aboutAction = new QAction(tr("&About"), this); diff --git a/MainWindow.h b/MainWindow.h index 5e9d1b1..5b70ebf 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -21,7 +21,10 @@ #ifndef MAIN_WINDOW_H_ #define MAIN_WINDOW_H_ -#include +#include +#if QT_VERSION >= 0x050000 + #include +#endif #include #include #include diff --git a/main.cpp b/main.cpp index 490a27c..c68aedc 100644 --- a/main.cpp +++ b/main.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #if USING_QT_5 #include diff --git a/mapmap.pro b/mapmap.pro index 5121ebc..b5a323c 100644 --- a/mapmap.pro +++ b/mapmap.pro @@ -2,10 +2,12 @@ CONFIG += qt debug TEMPLATE = app VERSION = 0.2.1 TARGET = mapmap -QT += gui opengl xml widgets +QT += gui opengl xml +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB HEADERS = \ + Commands.h \ DestinationGLCanvas.h \ MM.h \ MainApplication.h \ @@ -27,10 +29,10 @@ HEADERS = \ Shape.h \ SourceGLCanvas.h \ UidAllocator.h \ - Util.h \ - Commands.h + Util.h SOURCES = \ + Commands.cpp \ DestinationGLCanvas.cpp \ MM.cpp \ MainApplication.cpp \ @@ -52,8 +54,7 @@ SOURCES = \ SourceGLCanvas.cpp \ UidAllocator.cpp \ Util.cpp \ - main.cpp \ - Commands.cpp + main.cpp RESOURCES = mapmap.qrc TRANSLATIONS = resources/texts/mapmap_*.ts