Purged out the old history code

Sat, 01 Jun 2013 03:17:52 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sat, 01 Jun 2013 03:17:52 +0300
changeset 265
955c0aabfebf
parent 264
4299b818a816
child 266
12e7302f14e9

Purged out the old history code

src/addObjectDialog.cpp file | annotate | diff | comparison | revisions
src/extprogs.cpp file | annotate | diff | comparison | revisions
src/file.cpp file | annotate | diff | comparison | revisions
src/file.h file | annotate | diff | comparison | revisions
src/gldraw.cpp file | annotate | diff | comparison | revisions
src/gui.cpp file | annotate | diff | comparison | revisions
src/gui_actions.cpp file | annotate | diff | comparison | revisions
src/gui_editactions.cpp file | annotate | diff | comparison | revisions
src/history.cpp file | annotate | diff | comparison | revisions
src/history.h file | annotate | diff | comparison | revisions
src/historyDialog.cpp file | annotate | diff | comparison | revisions
src/ldtypes.cpp file | annotate | diff | comparison | revisions
src/ldtypes.h file | annotate | diff | comparison | revisions
--- a/src/addObjectDialog.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/addObjectDialog.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -382,10 +382,6 @@
 	if (dlg.exec () == false)
 		return;
 	
-	LDObject* backup = null;
-	if (!newObject)
-		backup = obj->clone ();
-	
 	matrix transform = g_identity;
 	if (type == LDObject::Subfile || type == LDObject::Radial) {
 		vector<str> matrixstrvals = str (dlg.le_matrix->text ()).split (" ");
@@ -505,9 +501,6 @@
 	if (newObject) {
 		ulong idx = g_win->getInsertionPoint ();
 		g_curfile->insertObj (idx, obj);
-		History::addEntry (new AddHistory ({(ulong) idx}, {obj->clone ()}));
-	} else {
-		History::addEntry (new EditHistory ({(ulong) obj->getIndex (g_curfile)}, {backup}, {obj->clone ()}));
 	}
 	
 	g_win->fullRefresh ();
--- a/src/extprogs.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/extprogs.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -203,7 +203,7 @@
 	}
 }
 
-// ========================================================================================================================================
+// ================================================================================================
 static void insertOutput (str fname, bool replace, vector<short> colorsToReplace) {
 #ifndef RELEASE
 	QFile::copy (fname, "./debug_lastOutput");
@@ -216,17 +216,14 @@
 		return;
 	}
 	
-	ComboHistory* cmb = new ComboHistory ();
-	vector<LDObject*> objs = loadFileContents (fp, null),
-		copies;
-	vector<ulong> indices;
+	vector<LDObject*> objs = loadFileContents (fp, null);
 	
 	// If we replace the objects, delete the selection now.
 	if (replace)
-		*cmb << g_win->deleteSelection ();
+		g_win->deleteSelection ();
 	
 	for (const short colnum : colorsToReplace)
-		*cmb << g_win->deleteByColor (colnum);
+		g_win->deleteByColor (colnum);
 	
 	// Insert the new objects
 	g_win->sel ().clear ();
@@ -236,20 +233,10 @@
 			continue;
 		}
 		
-		ulong idx = g_curfile->addObject (obj);
-		indices << idx;
-		copies << obj->clone ();
+		g_curfile->addObject (obj);
 		g_win->sel () << obj;
 	}
 	
-	if (indices.size() > 0)
-		*cmb << new AddHistory ({indices, copies});
-	
-	if (cmb->paEntries.size () > 0)
-		History::addEntry (cmb);
-	else
-		delete cmb;
-	
 	fclose (fp);
 	g_win->fullRefresh ();
 }
--- a/src/file.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/file.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -351,7 +351,7 @@
 	setlocale (LC_ALL, "C");
 	
 	// If we have unsaved changes, warn and give the option of saving.
-	if (!implicit () && History::pos () != savePos ()) {
+	if (!implicit () && history ().pos () != savePos ()) {
 		switch (QMessageBox::question (g_win, "Unsaved Changes",
 			fmt ("There are unsaved changes to %s. Should it be saved?",
 			(name ().len () > 0) ? name ().c () : "<anonymous>"),
@@ -425,8 +425,6 @@
 	g_loadedFiles << f;
 	g_curfile = f;
 	
-	History::clear ();
-	
 	g_BBox.reset ();
 	g_win->R ()->setFile (f);
 	g_win->fullRefresh ();
@@ -500,8 +498,6 @@
 	g_win->R ()->setFile (file);
 	g_win->R ()->resetAngles ();
 	
-	History::clear ();
-	
 	// Add it to the recent files list.
 	addRecentFile (path);
 	g_loadingMainFile = false;
@@ -549,7 +545,7 @@
 	fclose (fp);
 	
 	// We have successfully saved, update the save position now.
-	setSavePos (History::pos ());
+	setSavePos (history ().pos ());
 	setName (savepath);
 	
 	g_win->updateTitle ();
--- a/src/file.h	Tue May 28 18:30:40 2013 +0300
+++ b/src/file.h	Sat Jun 01 03:17:52 2013 +0300
@@ -21,8 +21,10 @@
 
 #include "common.h"
 #include "ldtypes.h"
+#include "history.h"
 #include <QObject>
 
+class History;
 class OpenProgressDialog;
 namespace LDPaths {
 	void initPaths ();
@@ -49,6 +51,7 @@
 	MUTABLE_READ_PROPERTY (vector<LDObject*>, objs)
 	PROPERTY (vector<LDObject*>, cache, setCache)
 	PROPERTY (long, savePos, setSavePos)
+	MUTABLE_READ_PROPERTY (History, history)
 	
 public:
 	LDOpenFile ();
--- a/src/gldraw.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/gldraw.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -1268,8 +1268,6 @@
 		file ()->addObject (obj);
 		compileObject (obj);
 		g_win->fullRefresh ();
-		
-		History::addEntry (new AddHistory ({(ulong) obj->getIndex (file ())}, {obj->clone ()}));
 	}
 	
 	m_drawedVerts.clear ();
--- a/src/gui.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/gui.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -134,7 +134,7 @@
 	// things not implemented yet
 	findAction ("help")->setEnabled (false);
 	
-	History::updateActions ();
+	g_curfile->history ().updateActions ();
 }
 
 // =============================================================================
@@ -518,7 +518,7 @@
 			title += fmt (": %s", comm->text.chars());
 		}
 		
-		if (History::pos () != g_curfile->savePos ())
+		if (g_curfile->history ().pos () != g_curfile->savePos ())
 			title += '*';
 	}
 	
@@ -782,21 +782,15 @@
 	if (col == null)
 		return;
 	
-	vector<ulong> indices;
-	vector<short> colors;
 	short newColor = col->index;
 	
 	for (LDObject* obj : m_sel) {
 		if (obj->color == -1)
 			continue; // uncolored object
 		
-		indices << obj->getIndex (g_curfile);
-		colors << obj->color;
-		
 		obj->color = newColor;
 	}
 	
-	History::addEntry (new SetColorHistory (indices, colors, newColor));
 	fullRefresh ();
 }
 
@@ -950,20 +944,11 @@
 
 // ========================================================================================================================================
 DelHistory* ForgeWindow::deleteObjVector (vector<LDObject*> objs) {
-	vector<ulong> indices;
-	vector<LDObject*> cache;
-	
 	for (LDObject* obj : objs) {
-		indices << obj->getIndex (g_curfile);
-		cache << obj->clone ();
-		
 		g_curfile->forgetObject (obj);
 		delete obj;
 	}
 	
-	if (indices.size () > 0)
-		return new DelHistory (indices, cache);
-	
 	return null;
 }
 
--- a/src/gui_actions.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/gui_actions.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -310,26 +310,19 @@
 		return;
 	}
 	
-	vector<LDObject*> historyCopies;
-	vector<ulong> historyIndices;
 	vector<LDObject*> objs = loadFileContents (fp, null);
 	
 	g_win->sel ().clear ();
 	
 	for (LDObject* obj : objs) {
-		historyCopies << obj->clone ();
-		historyIndices << idx;
 		g_curfile->insertObj (idx, obj);
 		g_win->sel () << obj;
 		
 		idx++;
 	}
 	
-	if (historyCopies.size() > 0) {
-		History::addEntry (new AddHistory (historyIndices, historyCopies));
-		g_win->fullRefresh ();
-		g_win->scrollToSelection ();
-	}
+	g_win->fullRefresh ();
+	g_win->scrollToSelection ();
 }
 
 // =============================================================================
@@ -366,8 +359,6 @@
 	QVBoxLayout* const layout = new QVBoxLayout;
 	QTextEdit* const te_edit = new QTextEdit;
 	QDialogButtonBox* const bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
-	vector<LDObject*> historyCopies;
-	vector<ulong> historyIndices;
 	
 	layout->addWidget (te_edit);
 	layout->addWidget (bbx_buttons);
@@ -385,17 +376,12 @@
 		LDObject* obj = parseLine (line);
 		
 		g_curfile->insertObj (idx, obj);
-		historyIndices << idx;
-		historyCopies << obj->clone ();
 		g_win->sel () << obj;
 		idx++;
 	}
 	
-	if (historyCopies.size () > 0) {
-		History::addEntry (new AddHistory (historyIndices, historyCopies));
-		g_win->fullRefresh ();
-		g_win->scrollToSelection ();
-	}
+	g_win->fullRefresh ();
+	g_win->scrollToSelection ();
 }
 
 // =========================================================================================================================================
--- a/src/gui_editactions.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/gui_editactions.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -23,7 +23,6 @@
 #include "gui.h"
 #include "common.h"
 #include "file.h"
-#include "history.h"
 #include "colorSelectDialog.h"
 #include "historyDialog.h"
 #include "misc.h"
@@ -73,7 +72,6 @@
 		return;
 	
 	g_win->deleteSelection (&ulaIndices, &copies);
-	History::addEntry (new DelHistory (ulaIndices, copies, DelHistory::Cut));
 }
 
 // =============================================================================
@@ -87,22 +85,15 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 MAKE_ACTION (paste, "Paste", "paste", "Paste clipboard contents.", CTRL (V)) {
-	vector<ulong> historyIndices;
-	vector<LDObject*> historyCopies;
-	
 	ulong idx = g_win->getInsertionPoint ();
 	g_win->sel ().clear ();
 	
 	for (LDObject* obj : g_Clipboard) {
-		historyIndices << idx;
-		historyCopies << obj->clone ();
-		
 		LDObject* copy = obj->clone ();
 		g_curfile->insertObj (idx++, copy);
 		g_win->sel () << copy;
 	}
 	
-	History::addEntry (new AddHistory (historyIndices, historyCopies, AddHistory::Paste));
 	g_win->fullRefresh ();
 	g_win->scrollToSelection ();
 }
@@ -111,13 +102,7 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 MAKE_ACTION (del, "Delete", "delete", "Delete the selection", KEY (Delete)) {
-	vector<ulong> ulaIndices;
-	vector<LDObject*> copies;
-	
-	g_win->deleteSelection (&ulaIndices, &copies);
-	
-	if (copies.size ())
-		History::addEntry (new DelHistory (ulaIndices, copies));
+	g_win->deleteSelection (null, null);
 }
 
 // =============================================================================
@@ -126,18 +111,6 @@
 static void doInline (bool deep) {
 	vector<LDObject*> sel = g_win->sel ();
 	
-	// History stuff
-	vector<LDSubfile*> refs;
-	vector<ulong> refIndices, bitIndices;
-	
-	for (LDObject* obj : sel) {
-		if (obj->getType() != LDObject::Subfile)
-			continue;
-		
-		refIndices << obj->getIndex (g_curfile);
-		refs << static_cast<LDSubfile*> (obj)->clone ();
-	}
-	
 	for (LDObject* obj : sel) {
 		// Get the index of the subfile so we know where to insert the
 		// inlined contents.
@@ -156,8 +129,6 @@
 		
 		// Merge in the inlined objects
 		for (LDObject* inlineobj : objs) {
-			bitIndices << idx;
-			
 			// This object is now inlined so it has no parent anymore.
 			inlineobj->parent = null;
 			
@@ -169,7 +140,6 @@
 		delete obj;
 	}
 	
-	History::addEntry (new InlineHistory (bitIndices, refIndices, refs, deep));
 	g_win->fullRefresh ();
 }
 
@@ -189,7 +159,6 @@
 MAKE_ACTION (radialConvert, "Radials to Subfiles", "radial-convert", "Convert radials into primitives.", (0)) {
 	vector<str> fails;
 	vector<LDObject*> sel = g_win->sel ();
-	EditHistory* history = new EditHistory;
 	
 	for (LDObject* obj : sel) {
 		if (obj->getType() != LDObject::Radial)
@@ -212,9 +181,6 @@
 		prim->fileName = name;
 		prim->fileInfo = file;
 		
-		// Add the history entry - this must be done while both objects are still valid.
-		history->addEntry (rad, prim);
-		
 		// Replace the radial with the primitive.
 		rad->replace (prim);
 	}
@@ -229,50 +195,36 @@
 		critical (errmsg);
 	}
 	
-	History::addEntry (history);
 	g_win->fullRefresh ();
 }
 
-// =======================================================================================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =======================================================================================================================================
+// ===============================================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// ===============================================================================================
 MAKE_ACTION (splitQuads, "Split Quads", "quad-split", "Split quads into triangles.", (0)) {
 	vector<LDObject*> objs = g_win->sel ();
 	
-	vector<ulong> ulaIndices;
-	vector<LDQuad*> paCopies;
-	
-	// Store stuff first for history archival
-	for (LDObject* obj : objs) {
-		if (obj->getType() != LDObject::Quad)
-			continue;
-		
-		ulaIndices << obj->getIndex (g_curfile);
-		paCopies << static_cast<LDQuad*> (obj)->clone ();
-	}
-	
 	for (LDObject* obj : objs) {
 		if (obj->getType() != LDObject::Quad)
 			continue;
 		
 		// Find the index of this quad
-		long lIndex = obj->getIndex (g_curfile);
+		long index = obj->getIndex (g_curfile);
 		
-		if (lIndex == -1)
+		if (index == -1)
 			return;
 		
 		vector<LDTriangle*> triangles = static_cast<LDQuad*> (obj)->splitToTriangles ();
 		
 		// Replace the quad with the first triangle and add the second triangle
 		// after the first one.
-		g_curfile->setObject (lIndex, triangles[0]);
-		g_curfile->insertObj (lIndex + 1, triangles[1]);
+		g_curfile->setObject (index, triangles[0]);
+		g_curfile->insertObj (index + 1, triangles[1]);
 		
 		// Delete this quad now, it has been split.
 		delete obj;
 	}
 	
-	History::addEntry (new QuadSplitHistory (ulaIndices, paCopies));
 	g_win->fullRefresh ();
 }
 
@@ -295,11 +247,6 @@
 	// Reinterpret it from the text of the input field
 	obj = parseLine (dlg.text ());
 	
-	// Mark down the history now before we perform the replacement (which
-	// destroys the old object)
-	History::addEntry (new EditHistory ({(ulong) oldobj->getIndex (g_curfile)},
-		{oldobj->clone ()}, {obj->clone ()}));
-	
 	oldobj->replace (obj);
 	
 	// Rebuild stuff after this
@@ -325,21 +272,14 @@
 	
 	// Show the dialog to the user now and ask for a color.
 	if (ColorSelectDialog::staticDialog (colnum, defcol, g_win)) {
-		vector<ulong> indices;
-		vector<short> colornums;
-		
 		for (LDObject* obj : objs) {
 			if (obj->isColored () == false)
 				continue;
 			
-			indices << obj->getIndex (g_curfile);
-			colornums << obj->color;
-			
 			obj->color = colnum;
 			g_win->R ()->compileObject (obj);
 		}
 		
-		History::addEntry (new SetColorHistory (indices, colornums, colnum));
 		g_win->refresh ();
 	}
 }
@@ -349,8 +289,6 @@
 // =============================================================================
 MAKE_ACTION (makeBorders, "Make Borders", "make-borders", "Add borders around given polygons.", CTRL_SHIFT (B)) {
 	vector<LDObject*> objs = g_win->sel ();
-	vector<ulong> historyIndices;
-	vector<LDObject*> historyObjs;
 	
 	for (LDObject* obj : objs) {
 		if (obj->getType() != LDObject::Quad && obj->getType() != LDObject::Triangle)
@@ -382,13 +320,10 @@
 			lines[i]->color = edgecolor;
 			g_curfile->insertObj (idx, lines[i]);
 			
-			historyIndices << idx;
-			historyObjs << lines[i]->clone ();
 			g_win->R ()->compileObject (lines[i]);
 		}
 	}
 	
-	History::addEntry (new AddHistory (historyIndices, historyObjs));
 	g_win->refresh ();
 }
 
@@ -398,9 +333,6 @@
 MAKE_ACTION (makeCornerVerts, "Make Corner Vertices", "corner-verts",
 	"Adds vertex objects to the corners of the given polygons", (0))
 {
-	vector<ulong> ulaIndices;
-	vector<LDObject*> paObjs;
-	
 	for (LDObject* obj : g_win->sel ()) {
 		if (obj->vertices () < 2)
 			continue;
@@ -412,31 +344,19 @@
 			vert->color = obj->color;
 			
 			g_curfile->insertObj (++idx, vert);
-			ulaIndices << idx;
-			paObjs << vert->clone ();
 			g_win->R ()->compileObject (vert);
 		}
 	}
 	
-	if (ulaIndices.size() > 0) {
-		History::addEntry (new AddHistory (ulaIndices, paObjs));
-		g_win->refresh ();
-	}
+	g_win->refresh ();
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-static void doMoveSelection (const bool bUp) {
+static void doMoveSelection (const bool up) {
 	vector<LDObject*> objs = g_win->sel ();
-	
-	// Get the indices of the objects for history archival
-	vector<ulong> ulaIndices;
-	for (LDObject* obj : objs)
-		ulaIndices << obj->getIndex (g_curfile);
-	
-	LDObject::moveObjects (objs, bUp);
-	History::addEntry (new ListMoveHistory (ulaIndices, bUp));
+	LDObject::moveObjects (objs, up);
 	g_win->buildObjList ();
 }
 
@@ -452,11 +372,11 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 MAKE_ACTION (undo, "Undo", "undo", "Undo a step.", CTRL (Z)) {
-	History::undo ();
+	
 }
 
 MAKE_ACTION (redo, "Redo", "redo", "Redo a step.", CTRL_SHIFT (Z)) {
-	History::redo ();
+	
 }
 
 MAKE_ACTION (showHistory, "Edit History", "history", "Show the history dialog.", (0)) {
@@ -467,21 +387,17 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void doMoveObjects (vertex vVector) {
-	vector<ulong> ulaIndices;
-	
+void doMoveObjects (vertex vect) {
 	// Apply the grid values
-	vVector[X] *= currentGrid ().confs[Grid::X]->value;
-	vVector[Y] *= currentGrid ().confs[Grid::Y]->value;
-	vVector[Z] *= currentGrid ().confs[Grid::Z]->value;
+	vect[X] *= currentGrid ().confs[Grid::X]->value;
+	vect[Y] *= currentGrid ().confs[Grid::Y]->value;
+	vect[Z] *= currentGrid ().confs[Grid::Z]->value;
 	
 	for (LDObject* obj : g_win->sel ()) {
-		ulaIndices << obj->getIndex (g_curfile);
-		obj->move (vVector);
+		obj->move (vect);
 		g_win->R ()->compileObject (obj);
 	}
 	
-	History::addEntry (new MoveHistory (ulaIndices, vVector));
 	g_win->refresh ();
 }
 
@@ -510,36 +426,18 @@
 }
 
 // =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// invert - reverse winding
-// 
-// NOTE: History management gets a little tricky here. For lines, cond-lines,
-// triangles and quads, we edit the object, thus we record an EditHistory. For
-// subfiles and radials we create or delete invertnext objects. Since we have
-// multiple actions of different types, we store a history entry for each of
-// them and wrap them into a ComboHistory, which allows storage of multiple
-// simultaneous edits with different type. This is what we ultimately store into
-// History.
-// =============================================================================
 MAKE_ACTION (invert, "Invert", "invert", "Reverse the winding of given objects.", CTRL_SHIFT (W)) {
 	vector<LDObject*> sel = g_win->sel ();
-	ComboHistory* history = new ComboHistory;
 	
 	for (LDObject* obj : sel) {
-		*history << obj->invert ();
+		obj->invert ();
 		g_win->R ()->compileObject (obj);
 	}
 	
-	if (history->numEntries () > 0) {
-		History::addEntry (history);
-		g_win->refresh ();
-	} else
-		delete history;
+	g_win->refresh ();
 }
 
 // =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
 static void doRotate (const short l, const short m, const short n) {
 	vector<LDObject*> sel = g_win->sel ();
 	vertex origin;
@@ -638,24 +536,14 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 MAKE_ACTION (uncolorize, "Uncolorize", "uncolorize", "Reduce colors of everything selected to main and edge colors", (0)) {
-	vector<LDObject*> oldCopies, newCopies;
-	vector<ulong> indices;
-	
 	for (LDObject* obj : g_win->sel ()) {
 		if (obj->isColored () == false)
 			continue;
 		
-		indices << obj->getIndex (g_curfile);
-		oldCopies << obj->clone ();
-		
 		obj->color = (obj->getType () == LDObject::Line || obj->getType () == LDObject::CondLine) ? edgecolor : maincolor;
-		newCopies << obj->clone ();
 	}
 	
-	if (indices.size () > 0) {
-		History::addEntry (new EditHistory (indices, oldCopies, newCopies));
-		g_win->fullRefresh ();
-	}
+	g_win->fullRefresh ();
 }
 
 // =============================================================================
@@ -694,11 +582,8 @@
 		rel = dlg.rel ();
 	
 	vector<int> sel = dlg.axes ();
-	EditHistory* history = new EditHistory;
 	
 	for (LDObject* obj : g_win->sel ()) {
-		LDObject* copy = obj->clone ();
-		
 		for (short i = 0; i < obj->vertices (); ++i)
 		for (int ax : sel) {
 			double& coord = obj->coords[i][(Axis) ax];
@@ -710,13 +595,8 @@
 				coord += replacement;
 			}
 		}
-		
-		history->addEntry (copy, obj, obj->getIndex (g_curfile));
-		
-		delete copy;
 	}
 	
-	History::addEntry (history);
 	g_win->fullRefresh ();
 }
 
@@ -740,58 +620,38 @@
 	CheckBoxGroup* cbg_axes;
 };
 
+// ================================================================================================
 MAKE_ACTION (flip, "Flip", "flip", "Flip coordinates", CTRL_SHIFT (F)) {
 	FlipDialog dlg;
 	
 	if (!dlg.exec ())
 		return;
 	
-	EditHistory* history = new EditHistory;
 	vector<int> sel = dlg.axes ();
 	
-	for (LDObject* obj : g_win->sel ()) {
-		bool altered = false;
-		LDObject* copy = obj->clone ();
-		
-		for (short i = 0; i < obj->vertices (); ++i)
-		for (int ax : sel) {
-			obj->coords[i][(Axis) ax] *= -1;
-			altered = true;
-		}
-		
-		if (altered)
-			history->addEntry (copy, obj, obj->getIndex (g_curfile));
-		
-		delete copy;
-	}
+	for (LDObject* obj : g_win->sel ())
+	for (short i = 0; i < obj->vertices (); ++i)
+	for (int ax : sel)
+		obj->coords[i][(Axis) ax] *= -1;
 	
-	History::addEntry (history);
 	g_win->fullRefresh ();
 }
 
-// =========================================================================================================================================
+// ================================================================================================
 MAKE_ACTION (demote, "Demote conditional lines", "demote", "Demote conditional lines down to normal lines.", (0)) {
-	EditHistory* history = new EditHistory;
-	
 	vector<LDObject*> sel = g_win->sel ();
 	for (LDObject* obj : sel) {
 		if (obj->getType () != LDObject::CondLine)
 			continue;
 		
-		ulong idx = obj->getIndex (g_curfile);
-		LDObject* cache = obj->clone ();
 		LDLine* repl = static_cast<LDCondLine*> (obj)->demote ();
-		
-		history->addEntry (cache, repl, idx);
 		g_win->R ()->compileObject (repl);
-		delete cache;
 	}
 	
-	History::addEntry (history);
 	g_win->refresh ();
 }
 
-// =========================================================================================================================================
+// =================================================================================================
 static bool isColorUsed (short colnum) {
 	for (LDObject* obj : g_curfile->objs ())
 		if (obj->isColored () && obj->color == colnum)
@@ -802,8 +662,6 @@
 
 MAKE_ACTION (autoColor, "Autocolor", "autocolor", "Set the color of the given object to the first found unused color.", (0)) {
 	short colnum = 0;
-	vector<ulong> indices;
-	vector<short> colors;
 	
 	while (colnum < 512 && (getColor (colnum) == null || isColorUsed (colnum)))
 		colnum++;
@@ -817,13 +675,9 @@
 		if (obj->isColored () == false)
 			continue;
 		
-		indices << obj->getIndex (g_curfile);
-		colors << obj->color;
-		
 		obj->color = colnum;
 		g_win->R ()->compileObject (obj);
 	}
 	
-	History::addEntry (new SetColorHistory (indices, colors, colnum));
 	g_win->refresh ();
 }
\ No newline at end of file
--- a/src/history.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/history.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -25,344 +25,24 @@
 EXTERN_ACTION (undo)
 EXTERN_ACTION (redo)
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-namespace History {
-	vector<HistoryEntry*> s_entries;
-	static long s_pos = -1;
-	
-	// =========================================================================
-	void addEntry (HistoryEntry* entry) {
-		// If there's any entries ahead the current position, we need to
-		// remove them now
-		for (ulong i = s_pos + 1; i < s_entries.size(); ++i) {
-			delete s_entries[i];
-			s_entries.erase (i);
-		}
-		
-		s_entries << entry;
-		s_pos++;
-		
-		updateActions ();
-	}
-	
-	// =========================================================================
-	void undo () {
-		if (s_pos == -1)
-			return; // nothing to undo
-		
-		s_entries[s_pos--]->undo ();
-		updateActions ();
-	}
-	
-	// =========================================================================
-	void redo () {
-		if (s_pos == (long) s_entries.size () - 1)
-			return; // nothing to redo;
-		
-		s_entries[++s_pos]->redo ();
-		updateActions ();
-	}
-	
-	// =========================================================================
-	void clear () {
-		for (HistoryEntry* entry : s_entries)
-			delete entry;
-		
-		s_entries.clear ();
-		s_pos = -1;
-		updateActions ();
-	}
-	
-	// =========================================================================
-	void updateActions () {
-#ifndef RELEASE
-		ACTION (undo)->setEnabled (s_pos > -1);
-		ACTION (redo)->setEnabled (s_pos < (long) s_entries.size () - 1);
-#else
-		// These are kinda unstable so they're disabled for release builds
-		ACTION (undo)->setEnabled (false);
-		ACTION (redo)->setEnabled (false);
-#endif // RELEASE
-		
-		// Update the window title as well
-		g_win->updateTitle ();
-	}
-	
-	// =========================================================================
-	long pos () {
-		return s_pos;
-	}
-	
-	// =========================================================================
-	vector<HistoryEntry*>& entries () {
-		return s_entries;
-	}
+History::History () {
+	setPos (-1);
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void DelHistory::undo () {
-	for (ulong i = 0; i < cache.size(); ++i) {
-		ulong idx = cache.size() - i - 1;
-		LDObject* obj = cache[idx]->clone ();
-		g_curfile->insertObj (indices[idx], obj);
-	}
-	
-	g_win->fullRefresh ();
-}
-
-// =============================================================================
-void DelHistory::redo () {
-	for (ulong i = 0; i < cache.size(); ++i) {
-		LDObject* obj = g_curfile->object (indices[i]);
-		
-		g_curfile->forgetObject (obj);
-		delete obj;
-	}
-	
-	g_win->fullRefresh ();
-}
-
-// =============================================================================
-DelHistory::~DelHistory () {
-	for (LDObject* obj : cache)
-		delete obj;
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void SetColorHistory::undo () {
-	// Restore colors
-	for (ulong i = 0; i < ulaIndices.size (); ++i)
-		g_curfile->object (ulaIndices[i])->color = daColors[i];
+void History::undo () {
 	
-	g_win->fullRefresh ();
-}
-
-void SetColorHistory::redo () {
-	// Re-set post color
-	for (ulong i = 0; i < ulaIndices.size (); ++i)
-		g_curfile->object (ulaIndices[i])->color = dNewColor;
-	
-	g_win->fullRefresh ();
-}
-
-SetColorHistory::~SetColorHistory () {}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void EditHistory::undo () {
-	for (ulong idx : ulaIndices)
-		g_curfile->object (idx)->replace (paOldObjs[idx]->clone ());
-	
-	g_win->fullRefresh ();
-}
-
-void EditHistory::redo () {
-	for (ulong idx : ulaIndices)
-		g_curfile->object (idx)->replace (paNewObjs[idx]->clone ());
-	
-	g_win->fullRefresh ();
-}
-
-void EditHistory::addEntry (LDObject* const oldObj, LDObject* const newObj) {
-	addEntry (oldObj, newObj, oldObj->getIndex (g_curfile));
-}
-
-void EditHistory::addEntry (LDObject* const oldObj, LDObject* const newObj, const ulong idx) {
-	ulaIndices << idx;
-	paOldObjs << oldObj->clone ();
-	paNewObjs << newObj->clone ();
-}
-
-EditHistory::~EditHistory () {
-	for (LDObject* obj : paOldObjs)
-		delete obj;
-	
-	for (LDObject* obj : paNewObjs)
-		delete obj;
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-vector<LDObject*> ListMoveHistory::getObjects (short ofs) {
-	vector<LDObject*> objs;
-	
-	for (ulong idx : ulaIndices)
-		objs << g_curfile->object (idx + ofs);
+void History::redo () {
 	
-	return objs;
-}
-
-void ListMoveHistory::undo () {
-	vector<LDObject*> objs = getObjects (bUp ? -1 : 1);
-	LDObject::moveObjects (objs, !bUp);
-	g_win->buildObjList ();
-}
-
-void ListMoveHistory::redo () {
-	vector<LDObject*> objs = getObjects (0);
-	LDObject::moveObjects (objs, bUp);
-	g_win->buildObjList ();
-}
-
-ListMoveHistory::~ListMoveHistory() {}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-AddHistory::~AddHistory () {
-	for (LDObject* pObj : paObjs)
-		delete pObj;
-}
-
-void AddHistory::undo () {
-	for (ulong i = 0; i < paObjs.size(); ++i) {
-		ulong idx = ulaIndices[ulaIndices.size() - i - 1];
-		LDObject* obj = g_curfile->object (idx);
-		
-		g_curfile->forgetObject (obj);
-		delete obj;
-	}
-	
-	g_win->fullRefresh ();
-}
-
-void AddHistory::redo () {
-	for (ulong i = 0; i < paObjs.size(); ++i) {
-		ulong idx = ulaIndices[i];
-		LDObject* obj = paObjs[i]->clone ();
-		
-		g_curfile->insertObj (idx, obj);
-	}
-	
-	g_win->fullRefresh ();
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-QuadSplitHistory::~QuadSplitHistory () {
-	for (LDQuad* pQuad : paQuads)
-		delete pQuad;
-}
-
-void QuadSplitHistory::undo () {
-	for (ulong i = 0; i < paQuads.size(); ++i) {
-		// The quad was replaced by the first triangle and a second one was
-		// added after it. Thus, we remove the second one here and replace
-		// the first with a copy of the quad.
-		ulong idx = ulaIndices[i];
-		
-		LDTriangle* tri1 = static_cast<LDTriangle*> (g_curfile->object (idx)),
-			*tri2 = static_cast<LDTriangle*> (g_curfile->object (idx + 1));
-		LDQuad* pCopy = paQuads[i]->clone ();
-		
-		tri1->replace (pCopy);
-		g_curfile->forgetObject (tri2);
-		delete tri2;
-	}
-	
-	g_win->fullRefresh ();
 }
 
-void QuadSplitHistory::redo () {
-	for (long i = paQuads.size() - 1; i >= 0; --i) {
-		ulong idx = ulaIndices[i];
-		
-		LDQuad* pQuad = static_cast<LDQuad*> (g_curfile->object (idx));
-		vector<LDTriangle*> paTriangles = pQuad->splitToTriangles ();
-		
-		g_curfile->setObject (idx, paTriangles[0]);
-		g_curfile->insertObj (idx + 1, paTriangles[1]);
-		delete pQuad;
-	}
+void History::clear () {
 	
-	g_win->fullRefresh ();
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void InlineHistory::undo () {
-	for (long i = ulaBitIndices.size() - 1; i >= 0; --i) {
-		LDObject* obj = g_curfile->object (ulaBitIndices[i]);
-		g_curfile->forgetObject (obj);
-		delete obj;
-	}
-	
-	for (ulong i = 0; i < ulaRefIndices.size(); ++i) {
-		LDSubfile* obj = paRefs[i]->clone ();
-		g_curfile->insertObj (ulaRefIndices[i], obj);
-	}
-	
-	g_win->fullRefresh ();
 }
 
-void InlineHistory::redo () {
-	for (long i = ulaRefIndices.size() - 1; i >= 0; --i) {
-		ulong idx = ulaRefIndices[i];
-		
-		assert (g_curfile->object (idx)->getType () == LDObject::Subfile);
-		LDSubfile* ref = static_cast<LDSubfile*> (g_curfile->object (idx));
-		vector<LDObject*> objs = ref->inlineContents (bDeep, false);
-		
-		for (LDObject* obj : objs)
-			g_curfile->insertObj (idx++, obj);
-		
-		g_curfile->forgetObject (ref);
-		delete ref;
-	}
-	
-	g_win->fullRefresh ();
-}
-
-InlineHistory::~InlineHistory () {
-	for (LDSubfile* const ref : paRefs)
-		delete ref;
+void History::updateActions () {
+	ACTION (undo)->setEnabled (false);
+	ACTION (redo)->setEnabled (false);
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-MoveHistory::~MoveHistory () {}
-
-void MoveHistory::undo () {
-	const vertex vInverse = -vVector;
-	
-	for (const ulong& i : ulaIndices)
-		g_curfile->object (i)->move (vInverse);
-	g_win->fullRefresh ();
-}
-
-void MoveHistory::redo () {
-	for (const ulong& i : ulaIndices)
-		g_curfile->object (i)->move (vVector);
-	g_win->fullRefresh ();
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-ComboHistory::~ComboHistory () {
-	for (HistoryEntry* pEntry : paEntries)
-		delete pEntry;
-}
-
-void ComboHistory::undo () {
-	for (long i = paEntries.size() - 1; i >= 0; --i) {
-		HistoryEntry* pEntry = paEntries[i];
-		pEntry->undo ();
-	}
-}
-
-void ComboHistory::redo () {
-	for (HistoryEntry* pEntry : paEntries)
-		pEntry->redo ();
-}
\ No newline at end of file
--- a/src/history.h	Tue May 28 18:30:40 2013 +0300
+++ b/src/history.h	Sat Jun 01 03:17:52 2013 +0300
@@ -28,6 +28,8 @@
 	virtual void redo (); \
 	virtual HistoryType type () { return HISTORY_##N; }
 
+class AbstractHistoryEntry;
+
 // =============================================================================
 enum HistoryType {
 	HISTORY_Del,
@@ -41,180 +43,114 @@
 	HISTORY_Combo,
 };
 
+class History {
+	PROPERTY (long, pos, setPos)
+	
+public:
+	History ();
+	void undo ();
+	void redo ();
+	void clear ();
+	void updateActions ();
+	
+private:
+	vector<vector<AbstractHistoryEntry*>> m_entries;
+};
+
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-class HistoryEntry {
+class AbstractHistoryEntry {
 public:
 	virtual void undo () {}
 	virtual void redo () {}
-	virtual ~HistoryEntry () {}
+	virtual ~AbstractHistoryEntry () {}
 	virtual HistoryType type () { return (HistoryType)(0); }
 };
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-class DelHistory : public HistoryEntry {
+class DelHistory : public AbstractHistoryEntry {
 public:
 	enum Type {
-		Cut,	// were deleted with a cut operation
-		Other,	// were deleted witout specific reason
+		Cut,	// was deleted with a cut operation
+		Other,	// was deleted witout specific reason
 	};
 	
+	PROPERTY (ulong, index, setIndex)
+	PROPERTY (LDObject*, copy, setCopy)
+	PROPERTY (DelHistory::Type, type, setType)
+	
+public:
 	IMPLEMENT_HISTORY_TYPE (Del)
 	
-	vector<ulong> indices;
-	vector<LDObject*> cache;
-	const Type eType;
-	
-	DelHistory (vector<ulong> indices, vector<LDObject*> cache, const Type eType = Other) :
-		indices (indices), cache (cache), eType (eType) {}
-};
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-class SetColorHistory : public HistoryEntry {
-public:
-	IMPLEMENT_HISTORY_TYPE (SetColor)
-	
-	vector<ulong> ulaIndices;
-	vector<short> daColors;
-	short dNewColor;
-	
-	SetColorHistory (vector<ulong> ulaIndices, vector<short> daColors, short dNewColor) :
-		ulaIndices (ulaIndices), daColors (daColors), dNewColor (dNewColor) {}
+	DelHistory (ulong idx, LDObject* copy, Type type) :
+		m_index (idx), m_copy (copy), m_type (type) {}
 };
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-class EditHistory : public HistoryEntry {
+class EditHistory : public AbstractHistoryEntry {
+	PROPERTY (ulong, index, setIndex)
+	PROPERTY (LDObject*, oldCopy, setOldCopy)
+	PROPERTY (LDObject*, newCopy, setNewCopy)
+	
 public:
 	IMPLEMENT_HISTORY_TYPE (Edit)
 	
-	vector<ulong> ulaIndices;
-	vector<LDObject*> paOldObjs, paNewObjs;
-	
-	EditHistory () {}
-	EditHistory (vector<ulong> ulaIndices, vector<LDObject*> paOldObjs,
-		vector<LDObject*> paNewObjs) :
-		ulaIndices (ulaIndices), paOldObjs (paOldObjs), paNewObjs (paNewObjs) {}
-	
-	void	addEntry		(LDObject* const oldObj, LDObject* const newObj);
-	void	addEntry		(LDObject* const oldObj, LDObject* const newObj, const ulong idx);
-	ulong	numEntries		() const { return ulaIndices.size (); }
+	EditHistory (ulong idx, LDObject* oldcopy, LDObject* newcopy) :
+		m_index (idx), m_oldCopy (oldcopy), m_newCopy (newcopy) {}
 };
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-class ListMoveHistory : public HistoryEntry {
+class ListMoveHistory : public AbstractHistoryEntry {
 public:
 	IMPLEMENT_HISTORY_TYPE (ListMove)
 	
-	vector<ulong> ulaIndices;
-	bool bUp;
+	vector<ulong> idxs;
+	long dest;
 	
-	vector<LDObject*> getObjects (short ofs);
-	ListMoveHistory (vector<ulong> ulaIndices, const bool bUp) :
-		ulaIndices (ulaIndices), bUp (bUp) {}
+	ListMoveHistory (vector<ulong> idxs, long dest) :
+		idxs (idxs), dest (dest) {}
 };
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-class AddHistory : public HistoryEntry {
+class AddHistory : public AbstractHistoryEntry {
 public:
 	enum Type {
 		Other,	// was "just added"
 		Paste,	// was added through a paste operation
 	};
 	
+	PROPERTY (ulong, index, setIndex)
+	PROPERTY (LDObject*, copy, setCopy)
+	PROPERTY (AddHistory::Type, type, setType)
+	
+public:
 	IMPLEMENT_HISTORY_TYPE (Add)
 	
-	vector<ulong> ulaIndices;
-	vector<LDObject*> paObjs;
-	const Type eType;
-	
-	AddHistory (vector<ulong> ulaIndices, vector<LDObject*> paObjs,
-		const Type eType = Other) :
-		ulaIndices (ulaIndices), paObjs (paObjs), eType (eType) {}
-};
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-class QuadSplitHistory : public HistoryEntry {
-public:
-	IMPLEMENT_HISTORY_TYPE (QuadSplit)
-	
-	vector<ulong> ulaIndices;
-	vector<LDQuad*> paQuads;
-	
-	QuadSplitHistory (vector<ulong> ulaIndices, vector<LDQuad*> paQuads) :
-		ulaIndices (ulaIndices), paQuads (paQuads) {}
+	AddHistory (ulong idx, LDObject* copy, Type type = Other) :
+		m_index (idx), m_copy (copy), m_type (type) {}
 };
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-class InlineHistory : public HistoryEntry {
-public:
-	IMPLEMENT_HISTORY_TYPE (Inline)
-	
-	const vector<ulong> ulaBitIndices, ulaRefIndices;
-	const vector<LDSubfile*> paRefs;
-	const bool bDeep;
-	
-	InlineHistory (const vector<ulong> ulaBitIndices, const vector<ulong> ulaRefIndices,
-		const vector<LDSubfile*> paRefs, const bool bDeep) :
-		ulaBitIndices (ulaBitIndices), ulaRefIndices (ulaRefIndices), paRefs (paRefs), bDeep (bDeep) {}
-};
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-class MoveHistory : public HistoryEntry {
+class MoveHistory : public AbstractHistoryEntry {
 public:
 	IMPLEMENT_HISTORY_TYPE (Move)
 	
-	const vector<ulong> ulaIndices;
-	const vertex vVector;
-	
-	MoveHistory (const vector<ulong> ulaIndices, const vertex vVector) :
-		ulaIndices (ulaIndices), vVector (vVector) {}
-};
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-class ComboHistory : public HistoryEntry {
-public:
-	IMPLEMENT_HISTORY_TYPE (Combo)
-	
-	vector<HistoryEntry*> paEntries;
+	vector<ulong> indices;
+	vertex dest;
 	
-	ComboHistory () {}
-	ComboHistory (vector<HistoryEntry*> paEntries) : paEntries (paEntries) {}
-	
-	void			addEntry		(HistoryEntry* entry) { if (entry) paEntries << entry; }
-	ulong			numEntries		() const { return paEntries.size (); }
-	ComboHistory&	operator<<		(HistoryEntry* entry) { addEntry (entry); return *this;}
-};
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-namespace History {
-	void addEntry (HistoryEntry* entry);
-	void undo ();
-	void redo ();
-	void clear ();
-	void updateActions ();
-	long pos ();
-	vector<HistoryEntry*>& entries ();
+	MoveHistory (vector<ulong> indices, vertex dest) :
+		indices (indices), dest (dest) {}
 };
 
 #endif // HISTORY_H
\ No newline at end of file
--- a/src/historyDialog.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/historyDialog.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -21,6 +21,9 @@
 #include "historyDialog.h"
 #include "history.h"
 #include "colors.h"
+#include "file.h"
+
+History* g_history = null;
 
 EXTERN_ACTION (undo);
 EXTERN_ACTION (redo);
@@ -29,6 +32,8 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 HistoryDialog::HistoryDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) {
+	g_history = &g_curfile->history ();
+	
 	historyList = new QListWidget;
 	undoButton = new QPushButton ("Undo");
 	redoButton = new QPushButton ("Redo");
@@ -79,130 +84,12 @@
 	qItem->setIcon (getIcon ("empty"));
 	historyList->addItem (qItem);
 	
-	for (HistoryEntry* entry : History::entries ()) {
+#if 0
+	for (AbstractHistoryEntry* entry : g_history->entries ()) {
 		str text;
 		QIcon entryIcon;
 		
 		switch (entry->type ()) {
-		case HISTORY_Add:
-			{
-				AddHistory* subentry = static_cast<AddHistory*> (entry);
-				ulong count = subentry->paObjs.size ();
-				str verb = "Added";
-				
-				switch (subentry->eType) {
-				case AddHistory::Paste:
-					verb = "Pasted";
-					entryIcon = getIcon ("paste");
-					break;
-				
-				default:
-					{
-						// Determine a common type for these objects. If all objects are of the same
-						// type, we display its addition icon. Otherwise, we draw a subfile addition
-						// one as a default.
-						LDObject::Type eCommonType = LDObject::Unidentified;
-						for (LDObject* obj : subentry->paObjs) {
-							if (eCommonType == LDObject::Unidentified or obj->getType() == eCommonType)
-								eCommonType = obj->getType ();
-							else {
-								eCommonType = LDObject::Unidentified;
-								break;
-							}
-						}
-						
-						// Set the icon based on the common type decided above.
-						if (eCommonType == LDObject::Unidentified)
-							entryIcon = getIcon ("add-subfile");
-						else
-							entryIcon = getIcon (fmt ("add-%s", g_saObjTypeIcons[eCommonType]));
-					}
-					break;
-				}
-				
-				text.format ("%s %lu objects\n%s", verb.chars(), count,
-					LDObject::objectListContents (subentry->paObjs).chars());
-			}
-			break;
-		
-		case HISTORY_QuadSplit:
-			{
-				QuadSplitHistory* subentry = static_cast<QuadSplitHistory*> (entry);
-				ulong count = subentry->paQuads.size ();
-				text.format ("Split %lu quad%s to triangles", count, plural (count));
-				
-				entryIcon = getIcon ("quad-split");
-			}
-			break;
-		
-		case HISTORY_Del:
-			{
-				DelHistory* subentry = static_cast<DelHistory*> (entry);
-				ulong count = subentry->cache.size ();
-				str verb = "Deleted";
-				entryIcon = getIcon ("delete");
-				
-				switch (subentry->eType) {
-				case DelHistory::Cut:
-					entryIcon = getIcon ("cut");
-					verb = "Cut";
-					break;
-				
-				default:
-					break;
-				}
-				
-				text.format ("%s %lu objects:\n%s", verb.chars(), count,
-					LDObject::objectListContents (subentry->cache).chars ());
-			}
-			break;
-		
-		case HISTORY_SetColor:
-			{
-				SetColorHistory* subentry = static_cast<SetColorHistory*> (entry);
-				ulong count = subentry->ulaIndices.size ();
-				text.format ("Set color of %lu objects to %d (%s)", count,
-					subentry->dNewColor, getColor (subentry->dNewColor)->name.chars());
-				
-				entryIcon = getIcon ("palette");
-			}
-			break;
-		
-		case HISTORY_ListMove:
-			{
-				ListMoveHistory* subentry = static_cast<ListMoveHistory*> (entry);
-				ulong ulCount = subentry->ulaIndices.size ();
-				
-				text.format ("Moved %lu objects %s", ulCount,
-					subentry->bUp ? "up" : "down");
-				entryIcon = getIcon (subentry->bUp ? "arrow-up" : "arrow-down");
-			}
-			break;
-		
-		case HISTORY_Edit:
-			{
-				EditHistory* subentry = static_cast<EditHistory*> (entry);
-				
-				text.format ("Edited %u objects\n%s",
-					subentry->paNewObjs.size(),
-					LDObject::objectListContents (subentry->paOldObjs).chars ());
-				entryIcon = getIcon ("set-contents");
-			}
-			break;
-		
-		case HISTORY_Inline:
-			{
-				InlineHistory* subentry = static_cast<InlineHistory*> (entry);
-				
-				text.format ("%s %lu subfiles:\n%lu resultants",
-					(subentry->bDeep) ? "Deep-inlined" : "Inlined",
-					(ulong) subentry->paRefs.size(),
-					(ulong) subentry->ulaBitIndices.size());
-				
-				entryIcon = getIcon (subentry->bDeep ? "inline-deep" : "inline");
-			}
-			break;
-		
 		default:
 			text = "???";
 			break;
@@ -213,26 +100,27 @@
 		item->setIcon (entryIcon);
 		historyList->addItem (item);
 	}
+#endif
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void HistoryDialog::slot_undo () {
-	History::undo ();
+	g_curfile->history ().undo ();
 	updateButtons ();
 	updateSelection ();
 }
 
 // =============================================================================
 void HistoryDialog::slot_redo () {
-	History::redo ();
+	g_curfile->history ().redo ();
 	updateButtons ();
 	updateSelection ();
 }
 
 void HistoryDialog::updateSelection () {
-	historyList->setCurrentItem (historyList->item (History::pos () + 1));
+	historyList->setCurrentItem (historyList->item (g_curfile->history ().pos () + 1));
 }
 
 // =============================================================================
@@ -240,7 +128,7 @@
 	if (!confirm ("Are you sure you want to clear the edit history?\nThis cannot be undone."))
 		return; // Canceled
 	
-	History::clear ();
+	g_curfile->history ().clear ();
 	populateList ();
 	updateButtons ();
 }
@@ -256,27 +144,27 @@
 	if (historyList->selectedItems ().size () != 1)
 		return;
 	
-	QListWidgetItem* qItem = historyList->selectedItems ()[0];
+	QListWidgetItem* item = historyList->selectedItems ()[0];
 	
 	// Find the index of the edit
-	long lIdx;
-	for (lIdx = 0; lIdx < historyList->count (); ++lIdx)
-		if (historyList->item (lIdx) == qItem)
+	long index;
+	for (index = 0; index < historyList->count (); ++index)
+		if (historyList->item (index) == item)
 			break;
 	
 	// qHistoryList is 0-based, History is -1-based, thus decrement
 	// the index now
-	lIdx--;
+	index--;
 	
-	if (lIdx == History::pos ())
+	if (index == g_curfile->history ().pos ())
 		return;
 	
 	// Seek to the selected edit by repeadetly undoing or redoing.
-	while (History::pos () != lIdx) {
-		if (History::pos () > lIdx)
-			History::undo ();
+	while (g_history->pos () != index) {
+		if (g_history->pos () > index)
+			g_history->undo ();
 		else
-			History::redo ();
+			g_history->redo ();
 	}
 	
 	updateButtons ();
--- a/src/ldtypes.cpp	Tue May 28 18:30:40 2013 +0300
+++ b/src/ldtypes.cpp	Sat Jun 01 03:17:52 2013 +0300
@@ -718,38 +718,32 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-HistoryEntry* LDObject::invert () { return null; }
-HistoryEntry* LDBFC::invert () { return null; }
-HistoryEntry* LDEmpty::invert () { return null; }
-HistoryEntry* LDComment::invert () { return null; }
-HistoryEntry* LDGibberish::invert () { return null; }
+void LDObject::invert () { }
+void LDBFC::invert () { }
+void LDEmpty::invert () { }
+void LDComment::invert () { }
+void LDGibberish::invert () { }
 
-HistoryEntry* LDTriangle::invert () {
+void LDTriangle::invert () {
 	// Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1.
 	// Thus, we swap 1 and 2.
 	vertex tmp = coords[1];
-	
-	LDObject* oldCopy = clone ();
 	coords[1] = coords[2];
 	coords[2] = tmp;
 	
-	return new EditHistory ({(ulong) getIndex (g_curfile)}, {oldCopy}, {clone ()});
+	return;
 }
 
-HistoryEntry* LDQuad::invert () {
+void LDQuad::invert () {
 	// Quad: 0 -> 1 -> 2 -> 3
 	// rev:  0 -> 3 -> 2 -> 1
 	// Thus, we swap 1 and 3.
 	vertex tmp = coords[1];
-	LDObject* oldCopy = clone ();
-	
 	coords[1] = coords[3];
 	coords[3] = tmp;
-	
-	return new EditHistory ({(ulong) getIndex (g_curfile)}, {oldCopy}, {clone ()});
 }
 
-static HistoryEntry* invertSubfile (LDObject* obj) {
+static void invertSubfile (LDObject* obj) {
 	// Subfiles and radials are inverted when they're prefixed with
 	// a BFC INVERTNEXT statement. Thus we need to toggle this status.
 	// For flat primitives it's sufficient that the determinant is
@@ -763,51 +757,42 @@
 		
 		if (bfc && bfc->type == LDBFC::InvertNext) {
 			// Object is prefixed with an invertnext, thus remove it.
-			HistoryEntry* history = new DelHistory ({idx - 1}, {bfc->clone ()});
-			
 			g_curfile->forgetObject (bfc);
 			delete bfc;
-			return history;
+			return;
 		}
 	}
 	
 	// Not inverted, thus prefix it with a new invertnext.
 	LDBFC* bfc = new LDBFC (LDBFC::InvertNext);
 	g_curfile->insertObj (idx, bfc);
-	
-	return new AddHistory ({idx}, {bfc->clone ()});
+}
+
+void LDSubfile::invert () {
+	invertSubfile (this);
 }
 
-HistoryEntry* LDSubfile::invert () {
-	return invertSubfile (this);
+void LDRadial::invert () {
+	invertSubfile (this);
 }
 
-HistoryEntry* LDRadial::invert () {
-	return invertSubfile (this);
-}
-
-static HistoryEntry* invertLine (LDObject* line) {
+static void invertLine (LDObject* line) {
 	// For lines, we swap the vertices. I don't think that a
 	// cond-line's control points need to be swapped, do they?
-	LDObject* oldCopy = line->clone ();
 	vertex tmp = line->coords[0];
-	
-	oldCopy = line->clone ();
 	line->coords[0] = line->coords[1];
 	line->coords[1] = tmp;
-	
-	return new EditHistory ({(ulong) line->getIndex (g_curfile)}, {oldCopy}, {line->clone ()});
 }
 
-HistoryEntry* LDLine::invert () {
-	return invertLine (this);
+void LDLine::invert () {
+	invertLine (this);
 }
 
-HistoryEntry* LDCondLine::invert () {
-	return invertLine (this);
+void LDCondLine::invert () {
+	invertLine (this);
 }
 
-HistoryEntry* LDVertex::invert () { return null; }
+void LDVertex::invert () { }
 
 // =============================================================================
 LDLine* LDCondLine::demote () {
--- a/src/ldtypes.h	Tue May 28 18:30:40 2013 +0300
+++ b/src/ldtypes.h	Sat Jun 01 03:17:52 2013 +0300
@@ -22,8 +22,6 @@
 #include "common.h"
 #include "types.h"
 
-class HistoryEntry;
-
 #define LDOBJ(T) \
 	LD##T () {} \
 	virtual ~LD##T () {} \
@@ -35,7 +33,7 @@
 		return new LD##T (*this); \
 	} \
 	virtual void move (vertex vVector); \
-	virtual HistoryEntry* invert ();
+	virtual void invert ();
 
 #define LDOBJ_VERTICES(V) virtual short vertices () const { return V; }
 #define LDOBJ_SETCOLORED(V) virtual bool isColored () const { return V; }
@@ -163,10 +161,10 @@
 	// Object list entry for this object
 	QListWidgetItem* qObjListEntry;
 	
-	virtual bool			hasMatrix		() const { return false; }
-	virtual HistoryEntry*	invert			();
-	LDObject*				next			() const;
-	LDObject*				prev			() const;
+	virtual bool        hasMatrix       () const { return false; }
+	virtual void        invert          ();
+	LDObject*           next            () const;
+	LDObject*           prev            () const;
 
 protected:
 	bool m_glinit;

mercurial