Sun, 06 Sep 2015 03:00:28 +0300
Refactor edit history
src/editHistory.cpp | file | annotate | diff | comparison | revisions | |
src/editHistory.h | file | annotate | diff | comparison | revisions | |
src/ldDocument.cpp | file | annotate | diff | comparison | revisions | |
src/ldDocument.h | file | annotate | diff | comparison | revisions | |
src/ldObject.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.h | file | annotate | diff | comparison | revisions |
--- a/src/editHistory.cpp Sun Sep 06 01:52:37 2015 +0300 +++ b/src/editHistory.cpp Sun Sep 06 03:00:28 2015 +0300 @@ -23,23 +23,19 @@ #include "mainwindow.h" #include "glRenderer.h" -// ============================================================================= -// -History::History() : - m_position (-1), - m_isIgnoring (false) {} +EditHistory::EditHistory (LDDocument* document) : + m_document (document), + m_isIgnoring (false), + m_position (-1) {} -// ============================================================================= -// -void History::undo() +void EditHistory::undo() { if (m_changesets.isEmpty() or position() == -1) return; // Don't take the changes done here as actual edits to the document setIgnoring (true); - - const Changeset& set = getChangeset (position()); + const Changeset& set = changesetAt (position()); // Iterate the list in reverse and undo all actions for (int i = set.size() - 1; i >= 0; --i) @@ -49,53 +45,42 @@ } m_position--; - g_win->refresh(); - g_win->updateActions(); - dprint ("Position is now %1", position()); setIgnoring (false); + emit undone(); } -// ============================================================================= -// -void History::redo() +void EditHistory::redo() { if (position() == m_changesets.size()) return; setIgnoring (true); - const Changeset& set = getChangeset (position() + 1); + const Changeset& set = changesetAt (position() + 1); - // Redo things - in the order as they were done in the first place + // Redo things in original order for (const AbstractHistoryEntry* change : set) change->redo(); - setPosition (position() + 1); - g_win->refresh(); - g_win->updateActions(); - dprint ("Position is now %1", position()); + ++m_position; setIgnoring (false); + emit redone(); } -// ============================================================================= -// -void History::clear() +void EditHistory::clear() { for (Changeset set : m_changesets) - for (AbstractHistoryEntry* change : set) - delete change; + for (AbstractHistoryEntry* change : set) + delete change; m_changesets.clear(); - dprint ("History: cleared"); } -// ============================================================================= -// -void History::addStep() +void EditHistory::addStep() { if (m_currentChangeset.isEmpty()) return; - while (position() < getSize() - 1) + while (position() < size() - 1) { Changeset last = m_changesets.last(); @@ -105,16 +90,13 @@ m_changesets.removeLast(); } -// dprint ("History: step added (%1 changes)", m_currentChangeset.size()); m_changesets << m_currentChangeset; m_currentChangeset.clear(); - setPosition (position() + 1); - g_win->updateActions(); + ++m_position; + emit stepAdded(); } -// ============================================================================= -// -void History::add (AbstractHistoryEntry* entry) +void EditHistory::add (AbstractHistoryEntry* entry) { if (isIgnoring()) { @@ -124,80 +106,128 @@ entry->setParent (this); m_currentChangeset << entry; -// dprint ("History: added entry of type %1", entry->getTypeName()); +} + +int EditHistory::size() const +{ + return m_changesets.size(); +} + +const EditHistory::Changeset& EditHistory::changesetAt (int pos) const +{ + return m_changesets[pos]; } -// ============================================================================= -// -void AddHistory::undo() const +int EditHistory::position() +{ + return m_position; +} + +bool EditHistory::isIgnoring() const { - LDObject* obj = parent()->document()->getObject (index()); - obj->destroy(); + return m_isIgnoring; +} + +void EditHistory::setIgnoring (bool value) +{ + m_isIgnoring = value; } -// ============================================================================= -// -void AddHistory::redo() const +LDDocument* EditHistory::document() const { - LDObject* obj = ParseLine (code()); - parent()->document()->insertObj (index(), obj); - g_win->renderer()->compileObject (obj); + return m_document; } -// ============================================================================= +// +// --------------------------------------------------------------------------------------------------------------------- // -DelHistory::DelHistory (int idx, LDObject* obj) : + +AbstractHistoryEntry::AbstractHistoryEntry() {} +AbstractHistoryEntry::~AbstractHistoryEntry() {} + +EditHistory* AbstractHistoryEntry::parent() const +{ + return m_parent; +} + +void AbstractHistoryEntry::setParent (EditHistory* parent) +{ + m_parent = parent; +} + +// +// --------------------------------------------------------------------------------------------------------------------- +// + +AddHistoryEntry::AddHistoryEntry (int idx, LDObject* obj) : m_index (idx), m_code (obj->asText()) {} -// ============================================================================= -// heh -// -void DelHistory::undo() const +void AddHistoryEntry::undo() const { - LDObject* obj = ParseLine (code()); - parent()->document()->insertObj (index(), obj); - g_win->renderer()->compileObject (obj); + parent()->document()->getObject (m_index)->destroy(); +} + +void AddHistoryEntry::redo() const +{ + parent()->document()->insertObj (m_index, ParseLine (m_code)); } -// ============================================================================= +// +// --------------------------------------------------------------------------------------------------------------------- // -void DelHistory::redo() const + +DelHistoryEntry::DelHistoryEntry (int idx, LDObject* obj) : + AddHistoryEntry (idx, obj) {} + +void DelHistoryEntry::undo() const { - LDObject* obj = parent()->document()->getObject (index()); - obj->destroy(); + AddHistoryEntry::redo(); +} + +void DelHistoryEntry::redo() const +{ + AddHistoryEntry::undo(); } -// ============================================================================= +// +// --------------------------------------------------------------------------------------------------------------------- // -void EditHistory::undo() const + +EditHistoryEntry::EditHistoryEntry (int idx, QString oldCode, QString newCode) : + m_index (idx), + m_oldCode (oldCode), + m_newCode (newCode) {} + +void EditHistoryEntry::undo() const { - LDObject* obj = g_win->currentDocument()->getObject (index()); - LDObject* newobj = ParseLine (oldCode()); + LDObject* obj = parent()->document()->getObject (m_index); + LDObject* newobj = ParseLine (m_oldCode); obj->replace (newobj); - g_win->renderer()->compileObject (newobj); } -// ============================================================================= -// -void EditHistory::redo() const +void EditHistoryEntry::redo() const { - LDObject* obj = g_win->currentDocument()->getObject (index()); - LDObject* newobj = ParseLine (newCode()); + LDObject* obj = parent()->document()->getObject (m_index); + LDObject* newobj = ParseLine (m_newCode); obj->replace (newobj); - g_win->renderer()->compileObject (newobj); } -// ============================================================================= +// +// --------------------------------------------------------------------------------------------------------------------- // -void SwapHistory::undo() const + +SwapHistoryEntry::SwapHistoryEntry (int a, int b) : + m_a (a), + m_b (b) {} + + +void SwapHistoryEntry::undo() const { - LDObject::fromID (a)->swap (LDObject::fromID (b)); + LDObject::fromID (m_a)->swap (LDObject::fromID (m_b)); } -// ============================================================================= -// -void SwapHistory::redo() const +void SwapHistoryEntry::redo() const { undo(); }
--- a/src/editHistory.h Sun Sep 06 01:52:37 2015 +0300 +++ b/src/editHistory.h Sun Sep 06 03:00:28 2015 +0300 @@ -20,155 +20,98 @@ #include "main.h" #include "ldObject.h" -#define IMPLEMENT_HISTORY_TYPE(N) \ - ~N##History() {} \ - void undo() const override; \ - void redo() const override; \ - \ - History::EHistoryType getType() const override \ - { \ - return History::E##N##History; \ - } \ - \ - QString getTypeName() const override \ - { \ - return #N; \ - } - class AbstractHistoryEntry; -// ============================================================================= -class History +class EditHistory : public QObject { - PROPERTY (private, int, position, setPosition, STOCK_WRITE) - PROPERTY (public, LDDocument*, document, setDocument, STOCK_WRITE) - PROPERTY (public, bool, isIgnoring, setIgnoring, STOCK_WRITE) - -public: - typedef QList<AbstractHistoryEntry*> Changeset; - - enum EHistoryType - { - EDelHistory, - EEditHistory, - EAddHistory, - EMoveHistory, - ESwapHistory, - }; - - History(); - void undo(); - void redo(); - void clear(); - - void addStep(); - void add (AbstractHistoryEntry* entry); - - inline long getSize() const - { - return m_changesets.size(); - } - - inline History& operator<< (AbstractHistoryEntry* entry) - { - add (entry); - return *this; - } - - inline const Changeset& getChangeset (long pos) const - { - return m_changesets[pos]; - } - -private: - Changeset m_currentChangeset; - QList<Changeset> m_changesets; -}; - -// ============================================================================= -// -class AbstractHistoryEntry -{ - PROPERTY (public, History*, parent, setParent, STOCK_WRITE) + Q_OBJECT public: - virtual ~AbstractHistoryEntry() {} - virtual void undo() const = 0; - virtual void redo() const = 0; - virtual History::EHistoryType getType() const = 0; - virtual QString getTypeName() const = 0; + using Changeset = QList<AbstractHistoryEntry*>; + + EditHistory (LDDocument* document); + + void add (AbstractHistoryEntry* entry); + void addStep(); + const Changeset& changesetAt (int pos) const; + void clear(); + LDDocument* document() const; + bool isIgnoring() const; + int position(); + void redo(); + void setIgnoring (bool value); + int size() const; + void undo(); + +signals: + void undone(); + void redone(); + void stepAdded(); + +private: + LDDocument* m_document; + Changeset m_currentChangeset; + QList<Changeset> m_changesets; + bool m_isIgnoring; + int m_position; }; -// ============================================================================= -// -class DelHistory : public AbstractHistoryEntry +class AbstractHistoryEntry { - PROPERTY (private, int, index, setIndex, STOCK_WRITE) - PROPERTY (private, QString, code, setCode, STOCK_WRITE) - public: - IMPLEMENT_HISTORY_TYPE (Del) - DelHistory (int idx, LDObject* obj); -}; + AbstractHistoryEntry(); + virtual ~AbstractHistoryEntry(); -// ============================================================================= -// -class EditHistory : public AbstractHistoryEntry -{ - PROPERTY (private, int, index, setIndex, STOCK_WRITE) - PROPERTY (private, QString, oldCode, setOldCode, STOCK_WRITE) - PROPERTY (private, QString, newCode, setNewCode, STOCK_WRITE) + EditHistory* parent() const; + virtual void redo() const = 0; + void setParent (EditHistory* parent); + virtual void undo() const = 0; -public: - IMPLEMENT_HISTORY_TYPE (Edit) - - EditHistory (int idx, QString oldCode, QString newCode) : - m_index (idx), - m_oldCode (oldCode), - m_newCode (newCode) {} +private: + EditHistory* m_parent; }; -// ============================================================================= -// -class AddHistory : public AbstractHistoryEntry +class AddHistoryEntry : public AbstractHistoryEntry { - PROPERTY (private, int, index, setIndex, STOCK_WRITE) - PROPERTY (private, QString, code, setCode, STOCK_WRITE) - public: - IMPLEMENT_HISTORY_TYPE (Add) - - AddHistory (int idx, LDObject* obj) : - m_index (idx), - m_code (obj->asText()) {} + AddHistoryEntry (int idx, LDObject* obj); + void undo() const override; + void redo() const override; + +private: + int m_index; + QString m_code; }; -// ============================================================================= -// -class MoveHistory : public AbstractHistoryEntry +class DelHistoryEntry : public AddHistoryEntry { public: - IMPLEMENT_HISTORY_TYPE (Move) - - QList<int> indices; - Vertex dest; - - MoveHistory (QList<int> indices, Vertex dest) : - indices (indices), - dest (dest) {} + DelHistoryEntry (int idx, LDObject* obj); + void undo() const override; + void redo() const override; }; -// ============================================================================= -// -class SwapHistory : public AbstractHistoryEntry +class EditHistoryEntry : public AbstractHistoryEntry { public: - IMPLEMENT_HISTORY_TYPE (Swap) + EditHistoryEntry (int idx, QString oldCode, QString newCode); + void undo() const override; + void redo() const override; + +private: + int m_index; + QString m_oldCode; + QString m_newCode; +}; - SwapHistory (int a, int b) : - a (a), - b (b) {} +class SwapHistoryEntry : public AbstractHistoryEntry +{ +public: + SwapHistoryEntry (int a, int b); + void undo() const override; + void redo() const override; private: - int a, b; + int m_a; + int m_b; };
--- a/src/ldDocument.cpp Sun Sep 06 01:52:37 2015 +0300 +++ b/src/ldDocument.cpp Sun Sep 06 03:00:28 2015 +0300 @@ -46,7 +46,7 @@ LDDocument::LDDocument (QObject* parent) : QObject (parent), HierarchyElement (parent), - m_history (new History), + m_history (new EditHistory (this)), m_isCache (true), m_verticesOutdated (true), m_needVertexMerge (true), @@ -55,7 +55,6 @@ { setSavePosition (-1); setTabIndex (-1); - m_history->setDocument (this); m_needsReCache = true; } @@ -81,7 +80,7 @@ return m_objects; } -History* LDDocument::history() const +EditHistory* LDDocument::history() const { return m_history; } @@ -172,7 +171,7 @@ void LDDocument::addToHistory (AbstractHistoryEntry* entry) { - *history() << entry; + history()->add (entry); } void LDDocument::close() @@ -961,7 +960,7 @@ // int LDDocument::addObject (LDObject* obj) { - history()->add (new AddHistory (objects().size(), obj)); + history()->add (new AddHistoryEntry (objects().size(), obj)); m_objects << obj; addKnownVertices (obj); obj->setDocument (this); @@ -984,7 +983,7 @@ // void LDDocument::insertObj (int pos, LDObject* obj) { - history()->add (new AddHistory (pos, obj)); + history()->add (new AddHistoryEntry (pos, obj)); m_objects.insert (pos, obj); obj->setDocument (this); m_window->renderer()->compileObject (obj); @@ -1023,7 +1022,7 @@ if (not isCache() and not m_beingDestroyed) { - history()->add (new DelHistory (idx, obj)); + history()->add (new DelHistoryEntry (idx, obj)); m_objectVertices.remove (obj); } @@ -1057,7 +1056,7 @@ { QString oldcode = getObject (idx)->asText(); QString newcode = obj->asText(); - *m_history << new EditHistory (idx, oldcode, newcode); + m_history->add (new EditHistoryEntry (idx, oldcode, newcode)); } m_objectVertices.remove (m_objects[idx]); @@ -1282,7 +1281,7 @@ { m_objects[b] = one; m_objects[a] = other; - addToHistory (new SwapHistory (one->id(), other->id())); + addToHistory (new SwapHistoryEntry (one->id(), other->id())); } }
--- a/src/ldDocument.h Sun Sep 06 01:52:37 2015 +0300 +++ b/src/ldDocument.h Sun Sep 06 03:00:28 2015 +0300 @@ -23,7 +23,7 @@ #include "editHistory.h" #include "glShared.h" -class History; +class EditHistory; class OpenProgressDialog; struct LDGLData; class GLCompiler; @@ -65,7 +65,7 @@ const LDObjectList& getSelection() const; LDGLData* glData(); bool hasUnsavedChanges() const; - History* history() const; + EditHistory* history() const; void initializeCachedData(); LDObjectList inlineContents (bool deep, bool renderinline); QList<LDPolygon> inlinePolygons(); @@ -104,7 +104,7 @@ QString m_fullPath; QString m_defaultName; LDObjectList m_objects; - History* m_history; + EditHistory* m_history; bool m_isCache; bool m_verticesOutdated; bool m_needVertexMerge;
--- a/src/ldObject.cpp Sun Sep 06 01:52:37 2015 +0300 +++ b/src/ldObject.cpp Sun Sep 06 03:00:28 2015 +0300 @@ -785,7 +785,7 @@ if (before != after) { - obj->document()->addToHistory (new EditHistory (idx, before, after)); + obj->document()->addToHistory (new EditHistoryEntry (idx, before, after)); g_win->renderer()->compileObject (obj); g_win->currentDocument()->redoVertices(); }
--- a/src/mainwindow.cpp Sun Sep 06 01:52:37 2015 +0300 +++ b/src/mainwindow.cpp Sun Sep 06 03:00:28 2015 +0300 @@ -1033,10 +1033,10 @@ { if (m_currentDocument != null and m_currentDocument->history() != null) { - History* his = m_currentDocument->history(); + EditHistory* his = m_currentDocument->history(); int pos = his->position(); ui.actionUndo->setEnabled (pos != -1); - ui.actionRedo->setEnabled (pos < (long) his->getSize() - 1); + ui.actionRedo->setEnabled (pos < (long) his->size() - 1); } ui.actionWireframe->setChecked (m_configOptions.drawWireframe()); @@ -1085,6 +1085,14 @@ // --------------------------------------------------------------------------------------------------------------------- // +void MainWindow::historyTraversed() +{ + updateActions(); + refresh(); +} + +// --------------------------------------------------------------------------------------------------------------------- +// void MainWindow::loadShortcuts() { for (QAction* act : findChildren<QAction*>()) @@ -1216,12 +1224,17 @@ // LDDocument* MainWindow::newDocument (bool cache) { - m_documents.append (new LDDocument (this)); + LDDocument* document = new LDDocument (this); + m_documents.append (document); + + connect (document->history(), SIGNAL (undone()), this, SLOT (historyTraversed())); + connect (document->history(), SIGNAL (redone()), this, SLOT (historyTraversed())); + connect (document->history(), SIGNAL (stepAdded()), this, SLOT (updateActions())); if (not cache) - m_documents.last()->openForEditing(); + document->openForEditing(); - return m_documents.last(); + return document; } // ---------------------------------------------------------------------------------------------------------------------
--- a/src/mainwindow.h Sun Sep 06 01:52:37 2015 +0300 +++ b/src/mainwindow.h Sun Sep 06 03:00:28 2015 +0300 @@ -105,7 +105,7 @@ void spawnContextMenu (const QPoint pos); int suggestInsertPoint(); void syncSettings(); - void updateActions(); + Q_SLOT void updateActions(); void updateColorToolbar(); void updateDocumentList(); void updateDocumentListItem (LDDocument* doc); @@ -119,6 +119,7 @@ void actionTriggered(); void circleToolSegmentsChanged(); void closeTab (int tabindex); + void historyTraversed(); void ringToolHiResClicked (bool clicked); void tabSelected(); void updatePrimitives();