src/historyDialog.cpp

changeset 183
f1b8cb53d2a2
child 185
6fea53f1ffc2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/historyDialog.cpp	Wed May 08 15:19:06 2013 +0300
@@ -0,0 +1,283 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 Santeri 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 "historyDialog.h"
+#include "history.h"
+#include "colors.h"
+#include <qboxlayout.h>
+#include <qmessagebox.h>
+
+EXTERN_ACTION (undo);
+EXTERN_ACTION (redo);
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+HistoryDialog::HistoryDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) {
+	historyList = new QListWidget;
+	undoButton = new QPushButton ("Undo");
+	redoButton = new QPushButton ("Redo");
+	clearButton = new QPushButton ("Clear");
+	buttons = new QDialogButtonBox (QDialogButtonBox::Close);
+	
+	historyList->setAlternatingRowColors (true);
+	
+	undoButton->setIcon (getIcon ("undo"));
+	redoButton->setIcon (getIcon ("redo"));
+	
+	connect (undoButton, SIGNAL (clicked ()), this, SLOT (slot_undo ()));
+	connect (redoButton, SIGNAL (clicked ()), this, SLOT (slot_redo ()));
+	connect (clearButton, SIGNAL (clicked ()), this, SLOT (slot_clear ()));
+	connect (buttons, SIGNAL (rejected ()), this, SLOT (reject ()));
+	connect (historyList, SIGNAL (itemSelectionChanged ()), this, SLOT (slot_selChanged ()));
+	
+	QVBoxLayout* qButtonLayout = new QVBoxLayout;
+	qButtonLayout->setDirection (QBoxLayout::TopToBottom);
+	qButtonLayout->addWidget (undoButton);
+	qButtonLayout->addWidget (redoButton);
+	qButtonLayout->addWidget (clearButton);
+	qButtonLayout->addStretch ();
+	
+	QGridLayout* qLayout = new QGridLayout;
+	qLayout->setColumnStretch (0, 1);
+	qLayout->addWidget (historyList, 0, 0, 2, 1);
+	qLayout->addLayout (qButtonLayout, 0, 1);
+	qLayout->addWidget (buttons, 1, 1);
+	
+	setLayout (qLayout);
+	setWindowIcon (getIcon ("history"));
+	setWindowTitle (APPNAME " - Edit history");
+	
+	populateList ();
+	updateButtons ();
+	updateSelection ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void HistoryDialog::populateList () {
+	historyList->clear ();
+	
+	QListWidgetItem* qItem = new QListWidgetItem;
+	qItem->setText ("[[ initial state ]]");
+	qItem->setIcon (getIcon ("empty"));
+	historyList->addItem (qItem);
+	
+	for (HistoryEntry* entry : 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 ulCount = subentry->paQuads.size ();
+				text.format ("Split %lu quad%s to triangles", ulCount, PLURAL (ulCount));
+				
+				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)->zName.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;
+		}
+		
+		QListWidgetItem* item = new QListWidgetItem;
+		item->setText (text);
+		item->setIcon (entryIcon);
+		historyList->addItem (item);
+	}
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void HistoryDialog::slot_undo () {
+	History::undo ();
+	updateButtons ();
+	updateSelection ();
+}
+
+// =============================================================================
+void HistoryDialog::slot_redo () {
+	History::redo ();
+	updateButtons ();
+	updateSelection ();
+}
+
+void HistoryDialog::updateSelection () {
+	historyList->setCurrentItem (historyList->item (History::pos () + 1));
+}
+
+// =============================================================================
+void HistoryDialog::slot_clear () {
+	if (!confirm ("Are you sure you want to clear the edit history?\nThis cannot be undone."))
+		return; // Canceled
+	
+	History::clear ();
+	populateList ();
+	updateButtons ();
+}
+
+// =============================================================================
+void HistoryDialog::updateButtons () {
+	undoButton->setEnabled (ACTION (undo)->isEnabled ());
+	redoButton->setEnabled (ACTION (redo)->isEnabled ());
+}
+
+// =============================================================================
+void HistoryDialog::slot_selChanged () {
+	if (historyList->selectedItems ().size () != 1)
+		return;
+	
+	QListWidgetItem* qItem = historyList->selectedItems ()[0];
+	
+	// Find the index of the edit
+	long lIdx;
+	for (lIdx = 0; lIdx < historyList->count (); ++lIdx)
+		if (historyList->item (lIdx) == qItem)
+			break;
+	
+	// qHistoryList is 0-based, History is -1-based, thus decrement
+	// the index now
+	lIdx--;
+	
+	if (lIdx == History::pos ())
+		return;
+	
+	// Seek to the selected edit by repeadetly undoing or redoing.
+	while (History::pos () != lIdx) {
+		if (History::pos () > lIdx)
+			History::undo ();
+		else
+			History::redo ();
+	}
+	
+	updateButtons ();
+}
\ No newline at end of file

mercurial