Work on edit history

Wed, 22 Sep 2021 12:30:48 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 22 Sep 2021 12:30:48 +0300
changeset 136
e8444e0d7f1a
parent 135
d384df40c8e7
child 137
fb9990772357

Work on edit history

CMakeLists.txt file | annotate | diff | comparison | revisions
src/document.h file | annotate | diff | comparison | revisions
src/edithistory.cpp file | annotate | diff | comparison | revisions
src/edithistory.h file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
src/modeleditcontext.cpp file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Wed Sep 22 00:25:31 2021 +0300
+++ b/CMakeLists.txt	Wed Sep 22 12:30:48 2021 +0300
@@ -25,7 +25,7 @@
 source_group("3.2 Widgets" REGULAR_EXPRESSION "src/(ui|widgets)/.+\\.(cpp|h|ui)")
 source_group("3.1 Settings editor" REGULAR_EXPRESSION "src/settingseditor/.+\\.(cpp|h|ui)")
 source_group("3 User interface" REGULAR_EXPRESSION "src/(mainwindow|document|documentmanager|uiutilities)\\.(cpp|h|ui)")
-source_group("2 Model handling" REGULAR_EXPRESSION "src/(model|modeleditcontext|libraries|colors|parser|vertexmap)\\.(cpp|h|ui)")
+source_group("2 Model handling" REGULAR_EXPRESSION "src/(model|modeleditcontext|libraries|colors|parser|vertexmap|edithistory)\\.(cpp|h|ui)")
 source_group("6 Editing tools" REGULAR_EXPRESSION "src/tools/.+\\.(cpp|h|ui)")
 
 set (LDFORGE_SOURCES
--- a/src/document.h	Wed Sep 22 00:25:31 2021 +0300
+++ b/src/document.h	Wed Sep 22 12:30:48 2021 +0300
@@ -23,6 +23,7 @@
 #include "ui/canvas.h"
 #include "model.h"
 #include "vertexmap.h"
+#include "edithistory.h"
 
 namespace Ui
 {
@@ -67,4 +68,8 @@
 	QVector<class BaseTool*> tools;
 	BaseTool* selectedTool = nullptr;
 	QMap<BaseTool*, QAction*> toolActions;
+	/**
+	 * @brief History information of edits to this model
+	 */
+	EditHistory editHistory;
 };
--- a/src/edithistory.cpp	Wed Sep 22 00:25:31 2021 +0300
+++ b/src/edithistory.cpp	Wed Sep 22 12:30:48 2021 +0300
@@ -1,4 +1,23 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2020 Teemu 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 "edithistory.h"
+#include "modeleditcontext.h"
 
 EditHistory::EditHistory()
 {
--- a/src/edithistory.h	Wed Sep 22 00:25:31 2021 +0300
+++ b/src/edithistory.h	Wed Sep 22 12:30:48 2021 +0300
@@ -1,7 +1,24 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2020 Teemu 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/>.
+ */
+
 #pragma once
 #include "main.h"
 #include "model.h"
-#include "modeleditcontext.h"
 
 class AbstractHistoryEntry
 {
@@ -13,14 +30,14 @@
 class InsertHistoryEntry : public AbstractHistoryEntry
 {
 public:
-	InsertHistoryEntry(int position, const QString& code) :
+	InsertHistoryEntry(int position, const QByteArray& state) :
 		position{position},
-		code{code} {}
+		state{state} {}
 	void undo(Model::EditContext& editContext) override;
 	void redo(Model::EditContext& editContext) override;
 protected:
 	int position;
-	QString code;
+	QByteArray state;
 };
 
 class DeleteHistoryEntry : public InsertHistoryEntry
@@ -33,21 +50,51 @@
 class EditHistoryEntry : public AbstractHistoryEntry
 {
 public:
-	EditHistoryEntry(int position, const QString& codeBefore, const QString& codeAfter) :
+	EditHistoryEntry(int position, const QByteArray& stateBefore, const QByteArray& stateAfter) :
 		position{position},
-		codeBefore{codeBefore},
-		codeAfter{codeAfter} {}
+		stateBefore{stateBefore},
+		stateAfter{stateAfter} {}
 	void undo(Model::EditContext& editContext) override;
 	void redo(Model::EditContext& editContext) override;
 private:
 	int position;
-	QString codeBefore;
-	QString codeAfter;
+	QByteArray stateBefore;
+	QByteArray stateAfter;
 };
 
 class EditHistory
 {
 public:
-	using Changeset = QVector<std::unique_ptr<AbstractHistoryEntry>>;
+	using Changeset = std::vector<std::unique_ptr<AbstractHistoryEntry>>;
 	EditHistory();
+	/**
+	 * @brief Adds a new entry into the edit history. Creates a new changeset if there is not one already open.
+	 * If behind in history, deletes all history entries in front.
+	 */
+	template<typename T, typename... Rs>
+	void add(Rs&&... args)
+	{
+		if (not this->changesetOpen)
+		{
+			while (this->position < this->changesets.size())
+			{
+				this->changesets.erase(this->changesets.end() - 1);
+			}
+			if (this->changesets.empty())
+			{
+				this->changesets.emplace_back();
+			}
+			this->changesetOpen = true;
+		}
+		this->changesets.back().emplace_back(args...);
+	}
+	void commit()
+	{
+		this->changesetOpen = false;
+		this->position += 1;
+	}
+private:
+	std::vector<Changeset> changesets;
+	std::size_t position = 0;
+	bool changesetOpen = false;
 };
\ No newline at end of file
--- a/src/model.h	Wed Sep 22 00:25:31 2021 +0300
+++ b/src/model.h	Wed Sep 22 12:30:48 2021 +0300
@@ -65,6 +65,7 @@
 	void apply(Fn f) const;
 Q_SIGNALS:
 	void objectAdded(ldraw::id_t id, int position);
+	void objectModified(ldraw::id_t id, int position);
 private:
 	using ModelObjectPointer = std::unique_ptr<ldraw::Object>;
 	template<typename T, typename... Args>
@@ -98,6 +99,9 @@
 	std::map<ldraw::id_t, ldraw::Object*> objectsById;
 	mutable std::vector<gl::Polygon> cachedPolygons;
 	mutable bool needRecache = true;
+	/**
+	 * @brief Amount of model edit contexts active
+	 */
 	int editCounter = 0;
 };
 
--- a/src/modeleditcontext.cpp	Wed Sep 22 00:25:31 2021 +0300
+++ b/src/modeleditcontext.cpp	Wed Sep 22 12:30:48 2021 +0300
@@ -31,6 +31,7 @@
 	{
 		this->model().objectModified(id);
 	}
+	this->model().editFinished();
 }
 
 ldraw::id_t Model::EditContext::append(std::unique_ptr<ldraw::Object>&& object)

mercurial