# HG changeset patch # User Santeri Piippo # Date 1370866523 -10800 # Node ID d5ec224c18794fed127613ffab48b3469fce8fef # Parent f5f2353af0d922a7b0bc196107647c32436856de Laid down the foundations of the new history system diff -r f5f2353af0d9 -r d5ec224c1879 changelog.txt --- a/changelog.txt Sat Jun 01 22:42:52 2013 +0300 +++ b/changelog.txt Mon Jun 10 15:15:23 2013 +0300 @@ -1,5 +1,5 @@ ================================================= -== Changes in version 1.1 +== Changes since version 1.0 ================================================= - Added a progress dialog for file loading to respond to desktops while loading files. With large files diff -r f5f2353af0d9 -r d5ec224c1879 src/file.cpp --- a/src/file.cpp Sat Jun 01 22:42:52 2013 +0300 +++ b/src/file.cpp Mon Jun 10 15:15:23 2013 +0300 @@ -91,6 +91,7 @@ LDOpenFile::LDOpenFile () { setImplicit (true); setSavePos (-1); + history ().setFile (this); } // ============================================================================= @@ -429,6 +430,7 @@ g_win->R ()->setFile (f); g_win->fullRefresh (); g_win->updateTitle (); + f->history ().updateActions (); } // ============================================================================= @@ -819,7 +821,11 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= ulong LDOpenFile::addObject (LDObject* obj) { - m_objs << obj; + PROP_NAME (history).add (new AddHistory (PROP_NAME (objs).size (), obj)); + PROP_NAME (objs) << obj; + + if (obj->getType () == LDObject::Vertex) + PROP_NAME (vertices) << obj; if (this == g_curfile) g_BBox.calcObject (obj); @@ -831,6 +837,7 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void LDOpenFile::insertObj (const ulong pos, LDObject* obj) { + m_history.add (new AddHistory (pos, obj)); m_objs.insert (pos, obj); if (this == g_curfile) @@ -841,16 +848,8 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void LDOpenFile::forgetObject (LDObject* obj) { - // Find the index for the given object - ulong idx; - for (idx = 0; idx < (ulong)m_objs.size(); ++idx) - if (m_objs[idx] == obj) - break; // found it - - if (idx >= m_objs.size ()) - return; // was not found - - // Erase it from memory + ulong idx = obj->getIndex (this); + m_history.add (new DelHistory (idx, obj)); m_objs.erase (idx); // Update the bounding box diff -r f5f2353af0d9 -r d5ec224c1879 src/file.h --- a/src/file.h Sat Jun 01 22:42:52 2013 +0300 +++ b/src/file.h Mon Jun 10 15:15:23 2013 +0300 @@ -52,6 +52,7 @@ PROPERTY (vector, cache, setCache) PROPERTY (long, savePos, setSavePos) MUTABLE_READ_PROPERTY (History, history) + READ_PROPERTY (vector, vertices, setVertices) public: typedef vector::it it; diff -r f5f2353af0d9 -r d5ec224c1879 src/gldraw.cpp --- a/src/gldraw.cpp Sat Jun 01 22:42:52 2013 +0300 +++ b/src/gldraw.cpp Mon Jun 10 15:15:23 2013 +0300 @@ -1268,9 +1268,11 @@ } if (obj) { + file ()->history ().open (); file ()->addObject (obj); compileObject (obj); g_win->fullRefresh (); + file ()->history ().close (); } m_drawedVerts.clear (); diff -r f5f2353af0d9 -r d5ec224c1879 src/gui.cpp --- a/src/gui.cpp Sat Jun 01 22:42:52 2013 +0300 +++ b/src/gui.cpp Mon Jun 10 15:15:23 2013 +0300 @@ -133,8 +133,6 @@ // things not implemented yet findAction ("help")->setEnabled (false); - - g_curfile->history ().updateActions (); } // ============================================================================= @@ -528,8 +526,11 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= +EXTERN_ACTION (undo); +EXTERN_ACTION (redo); void ForgeWindow::slot_action () { - g_curfile->history ().open (); + if (sender () != ACTION (undo) && sender () != ACTION (redo)) + g_curfile->history ().open (); // Get the action that triggered this slot. QAction* qAct = static_cast (sender ()); diff -r f5f2353af0d9 -r d5ec224c1879 src/gui_editactions.cpp --- a/src/gui_editactions.cpp Sat Jun 01 22:42:52 2013 +0300 +++ b/src/gui_editactions.cpp Mon Jun 10 15:15:23 2013 +0300 @@ -366,11 +366,11 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= MAKE_ACTION (undo, "Undo", "undo", "Undo a step.", CTRL (Z)) { - + g_curfile->history ().undo (); } MAKE_ACTION (redo, "Redo", "redo", "Redo a step.", CTRL_SHIFT (Z)) { - + g_curfile->history ().redo (); } MAKE_ACTION (showHistory, "Edit History", "history", "Show the history dialog.", (0)) { diff -r f5f2353af0d9 -r d5ec224c1879 src/history.cpp --- a/src/history.cpp Sat Jun 01 22:42:52 2013 +0300 +++ b/src/history.cpp Mon Jun 10 15:15:23 2013 +0300 @@ -21,6 +21,7 @@ #include "file.h" #include "misc.h" #include "gui.h" +#include "gldraw.h" EXTERN_ACTION (undo) EXTERN_ACTION (redo) @@ -30,11 +31,33 @@ } void History::undo () { + if (m_changesets.size () == 0 || pos () == -1) + return; + const list& set = changeset (pos ()); + + // Iterate the list in reverse and undo all actions + for (const AbstractHistoryEntry* change : c_rev (set)) + change->undo (); + + setPos (pos () - 1); + g_win->refresh (); + updateActions (); } void History::redo () { + if (pos () == (long) m_changesets.size ()) + return; + const list& set = changeset (pos () + 1); + + // Redo things - in the order as they were done in the first place + for (const AbstractHistoryEntry* change : set) + change->redo (); + + setPos (pos () + 1); + g_win->refresh (); + updateActions (); } void History::clear () { @@ -42,8 +65,8 @@ } void History::updateActions () { - ACTION (undo)->setEnabled (false); - ACTION (redo)->setEnabled (false); + ACTION (undo)->setEnabled (pos () != -1); + ACTION (redo)->setEnabled (pos () < (long) m_changesets.size () - 1); } void History::open () { @@ -58,19 +81,60 @@ return; setOpened (false); + if (m_currentArchive.size () == 0) return; while (pos () < size () - 1) - m_entries.erase (size () - 1); + m_changesets.erase (size () - 1); - m_entries << m_currentArchive; + m_changesets << m_currentArchive; m_currentArchive.clear (); setPos (pos () + 1); updateActions (); } void History::add (AbstractHistoryEntry* entry) { - assert (opened ()); + if (!opened ()) { + delete entry; + return; + } + + entry->setParent (this); m_currentArchive << entry; -} \ No newline at end of file +} + +// ============================================================================= +void AddHistory::undo () const { + LDOpenFile* f = parent ()->file (); + LDObject* obj = f->object (index ()); + f->forgetObject (obj); + delete obj; +} + +void AddHistory::redo () const { + LDOpenFile* f = parent ()->file (); + LDObject* obj = parseLine (code ()); + f->insertObj (index (), obj); + g_win->R ()->compileObject (obj); +} + +AddHistory::~AddHistory () {} + +// ============================================================================= +// heh +void DelHistory::undo () const { + LDOpenFile* f = parent ()->file (); + LDObject* obj = parseLine (code ()); + f->insertObj (index (), obj); + g_win->R ()->compileObject (obj); +} + +void DelHistory::redo () const { + LDOpenFile* f = parent ()->file (); + LDObject* obj = f->object (index ()); + f->forgetObject (obj); + delete obj; +} + +DelHistory::~DelHistory () {} \ No newline at end of file diff -r f5f2353af0d9 -r d5ec224c1879 src/history.h --- a/src/history.h Sat Jun 01 22:42:52 2013 +0300 +++ b/src/history.h Mon Jun 10 15:15:23 2013 +0300 @@ -24,32 +24,29 @@ #define IMPLEMENT_HISTORY_TYPE(N) \ virtual ~N##History (); \ - virtual void undo (); \ - virtual void redo (); \ - virtual HistoryType type () { return HISTORY_##N; } + virtual void undo () const; \ + virtual void redo () const; \ + virtual History::Type type () { return History::N; } class AbstractHistoryEntry; // ============================================================================= -enum HistoryType { - HISTORY_Del, - HISTORY_SetColor, - HISTORY_Edit, - HISTORY_ListMove, - HISTORY_Add, - HISTORY_QuadSplit, - HISTORY_Inline, - HISTORY_Move, - HISTORY_Combo, -}; - class History { PROPERTY (long, pos, setPos) + PROPERTY (LDOpenFile*, file, setFile) READ_PROPERTY (bool, opened, setOpened) public: typedef vector list; + enum Type { + Del, + Edit, + ListMove, + Add, + Move, + }; + History (); void undo (); void redo (); @@ -59,27 +56,33 @@ void open (); void close (); void add (AbstractHistoryEntry* entry); - long size () const { return m_entries.size (); } + long size () const { return m_changesets.size (); } History& operator<< (AbstractHistoryEntry* entry) { add (entry); return *this; } + const list& changeset (long pos) const { + return m_changesets[pos]; + } + private: list m_currentArchive; - vector m_entries; + vector m_changesets; }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= class AbstractHistoryEntry { + PROPERTY (History*, parent, setParent) + public: - virtual void undo () {} - virtual void redo () {} + virtual void undo () const {} + virtual void redo () const {} virtual ~AbstractHistoryEntry () {} - virtual HistoryType type () { return (HistoryType)(0); } + virtual History::Type type () { return (History::Type) 0; } }; // ============================================================================= @@ -93,14 +96,14 @@ }; PROPERTY (ulong, index, setIndex) - PROPERTY (LDObject*, copy, setCopy) + PROPERTY (str, code, setCode) PROPERTY (DelHistory::Type, type, setType) public: IMPLEMENT_HISTORY_TYPE (Del) - DelHistory (ulong idx, LDObject* copy, Type type) : - m_index (idx), m_copy (copy), m_type (type) {} + DelHistory (ulong idx, LDObject* obj, Type type = Other) : + m_index (idx), m_code (obj->raw ()), m_type (type) {} }; // ============================================================================= @@ -108,14 +111,14 @@ // ============================================================================= class EditHistory : public AbstractHistoryEntry { PROPERTY (ulong, index, setIndex) - PROPERTY (LDObject*, oldCopy, setOldCopy) - PROPERTY (LDObject*, newCopy, setNewCopy) + PROPERTY (str, oldCode, setOldCode) + PROPERTY (str, newCode, setNewCode) public: IMPLEMENT_HISTORY_TYPE (Edit) - EditHistory (ulong idx, LDObject* oldcopy, LDObject* newcopy) : - m_index (idx), m_oldCopy (oldcopy), m_newCopy (newcopy) {} + EditHistory (ulong idx, str oldCode, str newCode) : + m_index (idx), m_oldCode (oldCode), m_newCode (newCode) {} }; // ============================================================================= @@ -143,14 +146,14 @@ }; PROPERTY (ulong, index, setIndex) - PROPERTY (LDObject*, copy, setCopy) + PROPERTY (str, code, setCode) PROPERTY (AddHistory::Type, type, setType) public: IMPLEMENT_HISTORY_TYPE (Add) - AddHistory (ulong idx, LDObject* copy, Type type = Other) : - m_index (idx), m_copy (copy), m_type (type) {} + AddHistory (ulong idx, LDObject* obj, Type type = Other) : + m_index (idx), m_code (obj->raw ()), m_type (type) {} }; // ============================================================================= diff -r f5f2353af0d9 -r d5ec224c1879 src/main.cpp --- a/src/main.cpp Sat Jun 01 22:42:52 2013 +0300 +++ b/src/main.cpp Mon Jun 10 15:15:23 2013 +0300 @@ -41,6 +41,8 @@ // ============================================================================= int main (int argc, char* argv[]) { const QApplication app (argc, argv); + g_app = &app; + g_curfile = NULL; // Load or create the configuration if (!config::load ()) { @@ -57,9 +59,6 @@ initPartList (); ForgeWindow* win = new ForgeWindow; - - g_app = &app; - newFile (); win->show (); diff -r f5f2353af0d9 -r d5ec224c1879 src/types.h --- a/src/types.h Sat Jun 01 22:42:52 2013 +0300 +++ b/src/types.h Mon Jun 10 15:15:23 2013 +0300 @@ -24,6 +24,9 @@ class String; typedef String str; +template class ConstVectorReverser; +template using c_rev = ConstVectorReverser; + typedef unsigned int uint; typedef unsigned short ushort; typedef unsigned long ulong; @@ -129,6 +132,8 @@ public: typedef typename std::vector::iterator it; typedef typename std::vector::const_iterator c_it; + typedef typename std::vector::reverse_iterator r_it; + typedef typename std::vector::const_reverse_iterator cr_it; vector () {} vector (initlist vals) { @@ -151,6 +156,22 @@ return m_vect.cend (); } + r_it rbegin () { + return m_vect.rbegin (); + } + + cr_it crbegin () const { + return m_vect.crbegin (); + } + + r_it rend () { + return m_vect.rend (); + } + + cr_it crend () const { + return m_vect.crend (); + } + void erase (ulong pos) { assert (pos < size ()); m_vect.erase (m_vect.begin () + pos); @@ -191,7 +212,7 @@ vector reverse () const { vector rev; - for (const T& val : m_vect) + for (const T& val : c_rev (*this)) rev << val; return rev; @@ -239,4 +260,47 @@ std::vector m_vect; }; +template class VectorReverser { +public: + typedef typename vector::r_it it; + + VectorReverser (vector& vect) { + m_vect = &vect; + } + + it begin () { + return m_vect->rbegin (); + } + + it end () { + return m_vect->rend (); + } + +private: + vector* m_vect; +}; + +template class ConstVectorReverser { +public: + typedef typename vector::cr_it it; + + ConstVectorReverser (const vector& vect) { + m_vect = &vect; + } + + it begin () const { + return m_vect->crbegin (); + } + + it end () const { + return m_vect->crend (); + } + +private: + const vector* m_vect; +}; + +template using rev = VectorReverser; +template using c_rev = ConstVectorReverser; + #endif // TYPES_H \ No newline at end of file