Added history dialog, cannot display all types yet

Wed, 10 Apr 2013 19:26:14 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Wed, 10 Apr 2013 19:26:14 +0300
changeset 96
2f175b3d8211
parent 95
0a8ad4e3e7c1
child 97
52bcca21579e

Added history dialog, cannot display all types yet

gui.cpp file | annotate | diff | comparison | revisions
gui.h file | annotate | diff | comparison | revisions
gui_editactions.cpp file | annotate | diff | comparison | revisions
history.cpp file | annotate | diff | comparison | revisions
history.h file | annotate | diff | comparison | revisions
icons/history.png file | annotate | diff | comparison | revisions
ldforge.pro file | annotate | diff | comparison | revisions
ldtypes.cpp file | annotate | diff | comparison | revisions
ldtypes.h file | annotate | diff | comparison | revisions
zz_historyDialog.cpp file | annotate | diff | comparison | revisions
zz_historyDialog.h file | annotate | diff | comparison | revisions
--- a/gui.cpp	Wed Apr 10 16:17:22 2013 +0300
+++ b/gui.cpp	Wed Apr 10 19:26:14 2013 +0300
@@ -58,6 +58,7 @@
 EXTERN_ACTION (aboutQt)
 EXTERN_ACTION (undo)
 EXTERN_ACTION (redo)
+EXTERN_ACTION (showHistory)
 
 vector<actionmeta> g_ActionMeta;
 
@@ -177,6 +178,10 @@
 	ADD_MENU_ITEM (Edit, setContents)		// Set Contents
 	ADD_MENU_ITEM (Edit, makeBorders)		// Make Borders
 	
+	// Control menuBar
+	qControlMenu = menuBar ()->addMenu (tr ("&Control"));
+	ADD_MENU_ITEM (Control, showHistory)	// Show History
+	
 	// Help menu
 	qHelpMenu = menuBar ()->addMenu (tr ("&Help"));
 	ADD_MENU_ITEM (Help, help)				// Help
--- a/gui.h	Wed Apr 10 16:17:22 2013 +0300
+++ b/gui.h	Wed Apr 10 19:26:14 2013 +0300
@@ -58,7 +58,7 @@
 	static void actionHandler_##NAME ()
 
 #define EXTERN_ACTION(NAME) extern QAction* ACTION_NAME (NAME);
-#define ACTION_NAME(N) (LDForgeAction_##N)
+#define ACTION_NAME(N) LDForgeAction_##N
 
 // Convenience macros for key sequences.
 #define KEY(N) (Qt::Key_##N)
@@ -99,7 +99,7 @@
 	// Object list view
 	QTreeWidget* qObjList;
 	QTextEdit* qMessageLog;
-	QMenu* qFileMenu, *qEditMenu, *qInsertMenu, *qHelpMenu;
+	QMenu* qFileMenu, *qEditMenu, *qInsertMenu, *qHelpMenu, *qControlMenu;
 	std::vector<QToolBar*> qaToolBars;
 	
 	str zMessageLogHTML;
--- a/gui_editactions.cpp	Wed Apr 10 16:17:22 2013 +0300
+++ b/gui_editactions.cpp	Wed Apr 10 19:26:14 2013 +0300
@@ -18,10 +18,11 @@
 
 #include "gui.h"
 #include "common.h"
+#include "file.h"
+#include "history.h"
+#include "zz_colorSelectDialog.h"
+#include "zz_historyDialog.h"
 #include "zz_setContentsDialog.h"
-#include "file.h"
-#include "zz_colorSelectDialog.h"
-#include "history.h"
 
 vector<LDObject*> g_Clipboard;
 
@@ -322,10 +323,18 @@
 	doMoveSelection (false);
 }
 
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 ACTION (undo, "Undo", "undo", "Undo a step.", CTRL (Z)) {
 	History::undo ();
 }
 
 ACTION (redo, "Redo", "redo", "Redo a step.", CTRL_SHIFT (Z)) {
 	History::redo ();
+}
+
+ACTION (showHistory, "Show History", "history", "Show the history dialog.", (0)) {
+	HistoryDialog dlg;
+	dlg.exec ();
 }
\ No newline at end of file
--- a/history.cpp	Wed Apr 10 16:17:22 2013 +0300
+++ b/history.cpp	Wed Apr 10 19:26:14 2013 +0300
@@ -37,7 +37,6 @@
 	void addEntry (HistoryEntry* entry) {
 		// If there's any entries after our current position, we need to remove them now
 		for (ulong i = lPos + 1; i < entries.size(); ++i) {
-			
 			delete entries[i];
 			entries.erase (entries.begin() + i);
 		}
@@ -67,6 +66,16 @@
 	}
 	
 	// =========================================================================
+	void clear () {
+		for (HistoryEntry* entry : entries)
+			delete entry;
+		
+		entries.clear ();
+		lPos = -1;
+		updateActions ();
+	}
+	
+	// =========================================================================
 	void updateActions () {
 		ACTION_NAME (undo)->setEnabled (lPos > -1);
 		ACTION_NAME (redo)->setEnabled (lPos < (long) entries.size () - 1);
--- a/history.h	Wed Apr 10 16:17:22 2013 +0300
+++ b/history.h	Wed Apr 10 19:26:14 2013 +0300
@@ -25,8 +25,18 @@
 #define IMPLEMENT_HISTORY_TYPE(N) \
 	virtual ~N##History (); \
 	virtual void undo (); \
-	virtual void redo ();
+	virtual void redo (); \
+	virtual HistoryType type () { return HISTORY_##N; }
 
+// =============================================================================
+enum HistoryType {
+	HISTORY_Delete,
+	HISTORY_SetColor,
+	HISTORY_SetContents,
+	HISTORY_ListMove,
+	HISTORY_Addition,
+	HISTORY_QuadSplit,
+};
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -36,6 +46,7 @@
 	virtual void undo () {}
 	virtual void redo () {}
 	virtual ~HistoryEntry () {}
+	virtual HistoryType type () { return (HistoryType)(0); }
 };
 
 // =============================================================================
@@ -133,6 +144,7 @@
 	void addEntry (HistoryEntry* entry);
 	void undo ();
 	void redo ();
+	void clear ();
 	void updateActions ();
 };
 
Binary file icons/history.png has changed
--- a/ldforge.pro	Wed Apr 10 16:17:22 2013 +0300
+++ b/ldforge.pro	Wed Apr 10 19:26:14 2013 +0300
@@ -25,6 +25,7 @@
 	zz_addObjectDialog.h \
 	zz_colorSelectDialog.h \
 	zz_configDialog.h \
+	zz_historyDialog.h \
 	zz_newPartDialog.h \
 	zz_setContentsDialog.h
 
@@ -45,6 +46,7 @@
 	zz_addObjectDialog.cpp \
 	zz_colorSelectDialog.cpp \
 	zz_configDialog.cpp \
+	zz_historyDialog.cpp \
 	zz_newPartDialog.cpp \
 	zz_setContentsDialog.cpp
 
--- a/ldtypes.cpp	Wed Apr 10 16:17:22 2013 +0300
+++ b/ldtypes.cpp	Wed Apr 10 19:26:14 2013 +0300
@@ -22,31 +22,32 @@
 #include "misc.h"
 
 char const* g_saObjTypeNames[] = {
-	"unidentified",
+	"subfile",
+	"quadrilateral",
+	"triangle",
+	"line",
+	"condline",
+	"vertex",
+	"bfc",
+	"comment",
 	"unknown",
 	"empty",
-	"comment",
-	"subfile",
-	"line",
-	"triangle",
-	"quadrilateral",
-	"condline",
-	"bfc",
-	"vertex",
+	"unidentified",
 };
 
+// Should probably get rid of this array sometime
 char const* g_saObjTypeIcons[] = {
-	"error",
+	"subfile",
+	"quad",
+	"triangle",
+	"line",
+	"condline",
+	"vertex",
+	"bfc",
+	"comment",
 	"error",
 	"empty",
-	"comment",
-	"subfile",
-	"line",
-	"triangle",
-	"quad",
-	"condline",
-	"bfc",
-	"vertex",
+	"error",
 };
 
 // =============================================================================
@@ -395,6 +396,9 @@
 	return -1;
 }
 
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void LDObject::moveObjects (std::vector<LDObject*> objs, const bool bUp) {
 	// If we move down, we need to iterate the array in reverse order.
 	const long start = bUp ? 0 : (objs.size() - 1);
@@ -419,4 +423,34 @@
 		
 		obj->swap (g_CurrentFile->objects[lTarget]);
 	}
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+str LDObject::objectListContents (std::vector<LDObject*>& objs) {
+	bool bFirstDetails = true;
+	str zText = "";
+	
+	if (objs.size() == 0)
+		return "nothing"; // :)
+	
+	for (long i = 0; i < NUM_ObjectTypes; ++i) {
+		LDObjectType_e eType = (LDObjectType_e) i;
+		ulong ulCount = 0;
+		
+		for (LDObject* obj : objs)
+			if (obj->getType() == eType)
+				ulCount++;
+		
+		if (ulCount > 0) {
+			if (!bFirstDetails)
+				zText += ", ";
+			
+			zText.appendformat ("%lu %s%s", ulCount, g_saObjTypeNames[eType], PLURAL (ulCount));
+			bFirstDetails = false;
+		}
+	}
+	
+	return zText;
 }
\ No newline at end of file
--- a/ldtypes.h	Wed Apr 10 16:17:22 2013 +0300
+++ b/ldtypes.h	Wed Apr 10 19:26:14 2013 +0300
@@ -38,20 +38,21 @@
 // =============================================================================
 // LDObjectType_e
 // 
-// Object type codes
+// Object type codes. Codes are sorted in order of significance.
 // =============================================================================
 enum LDObjectType_e {
-	OBJ_Unidentified,	// Object is an uninitialized (LDObject) (SHOULD NEVER HAPPEN)
-	OBJ_Gibberish,		// Object is the result of failed parsing (LDGibberish)
-	OBJ_Empty,			// Object represents an empty line (LDEmpty)
-	OBJ_Comment,		// Object represents a comment (LDComment, code: 0)
-	OBJ_Subfile,		// Object represents a sub-file reference (LDSubfile, code: 1)
-	OBJ_Line,			// Object represents a line (LDLine, code: 2)
-	OBJ_Triangle,		// Object represents a triangle (LDTriangle, code: 3)
-	OBJ_Quad,			// Object represents a quadrilateral (LDQuad, code: 4)
-	OBJ_CondLine,		// Object represents a conditional line (LDCondLine, code: 5)
+	OBJ_Subfile,		// Object represents a sub-file reference
+	OBJ_Quad,			// Object represents a quadrilateral
+	OBJ_Triangle,		// Object represents a triangle
+	OBJ_Line,			// Object represents a line
+	OBJ_CondLine,		// Object represents a conditional line
+	OBJ_Vertex,			// Object is a vertex, LDForge extension object
 	OBJ_BFC,			// Object represents a BFC statement
-	OBJ_Vertex			// Object is a vertex, LDForge extension object (LDVertex)
+	OBJ_Comment,		// Object represents a comment
+	OBJ_Gibberish,		// Object is the result of failed parsing
+	OBJ_Empty,			// Object represents an empty line
+	OBJ_Unidentified,	// Object is an uninitialized (SHOULD NEVER HAPPEN)
+	NUM_ObjectTypes		// Amount of object types
 };
 
 // =============================================================================
@@ -99,6 +100,7 @@
 	void swap (LDObject* other);
 	
 	static void moveObjects (std::vector<LDObject*> objs, const bool bUp);
+	static str objectListContents (std::vector<LDObject*>& objs);
 	
 	QTreeWidgetItem* qObjListEntry;
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zz_historyDialog.cpp	Wed Apr 10 19:26:14 2013 +0300
@@ -0,0 +1,133 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 Santeri `arezey` Piippo
+ *  
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "zz_historyDialog.h"
+#include "history.h"
+#include <qboxlayout.h>
+#include <qmessagebox.h>
+
+EXTERN_ACTION (undo);
+EXTERN_ACTION (redo);
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+HistoryDialog::HistoryDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) {
+	qHistoryList = new QListWidget;
+	qUndoButton = new QPushButton ("Undo");
+	qRedoButton = new QPushButton ("Redo");
+	qClearButton = new QPushButton ("Clear");
+	qButtons = new QDialogButtonBox (QDialogButtonBox::Close);
+	
+	qUndoButton->setIcon (getIcon ("undo"));
+	qRedoButton->setIcon (getIcon ("redo"));
+	
+	connect (qUndoButton, SIGNAL (clicked ()), this, SLOT (slot_undo ()));
+	connect (qRedoButton, SIGNAL (clicked ()), this, SLOT (slot_redo ()));
+	connect (qClearButton, SIGNAL (clicked ()), this, SLOT (slot_clear ()));
+	connect (qButtons, SIGNAL (rejected ()), this, SLOT (reject ()));
+	
+	QVBoxLayout* qButtonLayout = new QVBoxLayout;
+	qButtonLayout->setDirection (QBoxLayout::TopToBottom);
+	qButtonLayout->addWidget (qUndoButton);
+	qButtonLayout->addWidget (qRedoButton);
+	qButtonLayout->addWidget (qClearButton);
+	qButtonLayout->addStretch ();
+	
+	QGridLayout* qLayout = new QGridLayout;
+	qLayout->addWidget (qHistoryList, 0, 0, 2, 1);
+	qLayout->addLayout (qButtonLayout, 0, 1);
+	qLayout->addWidget (qButtons, 1, 1);
+	
+	setLayout (qLayout);
+	setWindowIcon (getIcon ("history"));
+	setWindowTitle (APPNAME_DISPLAY " - Edit history");
+	
+	populateList ();
+	updateButtons ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void HistoryDialog::populateList () {
+	qHistoryList->clear ();
+	
+	for (HistoryEntry* entry : History::entries) {
+		str zText;
+		
+		switch (entry->type ()) {
+		case HISTORY_Addition:
+			{
+				AdditionHistory* addentry = static_cast<AdditionHistory*> (entry);
+				zText.format ("Added %s", LDObject::objectListContents (addentry->paObjs).chars());
+			}
+			break;
+		
+		case HISTORY_QuadSplit:
+			{
+				QuadSplitHistory* splitentry = static_cast<QuadSplitHistory*> (entry);
+				ulong ulCount = splitentry->paQuads.size ();
+				zText.format ("Split %lu quad%s to triangles", ulCount, PLURAL (ulCount));
+				break;
+			}
+		
+		default:
+			zText = "???";
+			break;
+		}
+		
+		QListWidgetItem* qItem = new QListWidgetItem;
+		qItem->setText (zText);
+		qHistoryList->addItem (qItem);
+	}
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void HistoryDialog::slot_undo () {
+	History::undo ();
+	updateButtons ();
+}
+
+// =============================================================================
+void HistoryDialog::slot_redo () {
+	History::redo ();
+	updateButtons ();
+}
+
+// =============================================================================
+void HistoryDialog::slot_clear () {
+	if (QMessageBox::question (this, "Confirm", "Are you sure you want to "
+		"clear the edit history?\nThis cannot be undone.",
+		(QMessageBox::Yes | QMessageBox::No), QMessageBox::No) != QMessageBox::Yes)
+	{
+		// Canceled
+		return;
+	}
+	
+	History::clear ();
+	populateList ();
+}
+
+// =============================================================================
+void HistoryDialog::updateButtons () {
+	qUndoButton->setEnabled (ACTION_NAME (undo)->isEnabled ());
+	qRedoButton->setEnabled (ACTION_NAME (redo)->isEnabled ());
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zz_historyDialog.h	Wed Apr 10 19:26:14 2013 +0300
@@ -0,0 +1,48 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 Santeri `arezey` Piippo
+ *  
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ZZ_HISTORYDIALOG_H
+#define ZZ_HISTORYDIALOG_H
+
+#include <qdialog.h>
+#include <qdialogbuttonbox.h>
+#include <qlistwidget.h>
+#include <qpushbutton.h>
+#include "gui.h"
+
+class HistoryDialog : public QDialog {
+	Q_OBJECT
+	
+public:
+	explicit HistoryDialog (QWidget* parent = nullptr, Qt::WindowFlags f = 0);
+	void populateList ();
+	
+	QListWidget* qHistoryList;
+	QPushButton* qUndoButton, *qRedoButton, *qClearButton;
+	QDialogButtonBox* qButtons;
+	
+private:
+	void updateButtons ();
+	
+private slots:
+	void slot_undo ();
+	void slot_redo ();
+	void slot_clear ();
+};
+
+#endif // ZZ_HISTORYDIALOG_H
\ No newline at end of file

mercurial