work on saving

Mon, 27 Sep 2021 21:04:45 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 27 Sep 2021 21:04:45 +0300
changeset 140
2f383e88acf4
parent 139
72098474d362
child 141
185eb297dc1e

work on saving

CMakeLists.txt file | annotate | diff | comparison | revisions
src/documentmanager.cpp file | annotate | diff | comparison | revisions
src/header.cpp file | annotate | diff | comparison | revisions
src/header.h file | annotate | diff | comparison | revisions
src/linetypes/subfilereference.cpp file | annotate | diff | comparison | revisions
src/model.cpp file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
src/parser.cpp file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Wed Sep 22 14:03:43 2021 +0300
+++ b/CMakeLists.txt	Mon Sep 27 21:04:45 2021 +0300
@@ -34,6 +34,7 @@
 	src/documentmanager.cpp
 	src/edithistory.cpp
 	src/geometry.cpp
+	src/header.cpp
 	src/libraries.cpp
 	src/invert.cpp
 	src/main.cpp
--- a/src/documentmanager.cpp	Wed Sep 22 14:03:43 2021 +0300
+++ b/src/documentmanager.cpp	Mon Sep 27 21:04:45 2021 +0300
@@ -89,7 +89,7 @@
 	QFile file{path};
 	const QString name = pathToName(path);
 	file.open(QFile::ReadOnly | QFile::Text);
-	std::unique_ptr<Model> newModel = std::make_unique<Model>();
+	std::unique_ptr<Model> newModel = std::make_unique<Model>(path);
 	QTextStream textStream{&file};
 	Model::EditContext editor = newModel->edit();
 	Parser parser{file};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/header.cpp	Mon Sep 27 21:04:45 2021 +0300
@@ -0,0 +1,85 @@
+/*
+ *  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 "header.h"
+
+const QString LDHeader::caLicenseString = "0 !LICENSE Redistributable under CCAL version 2.0";
+const QString LDHeader::nonCaLicenseString = "0 !LICENSE Not redistributable";
+
+static const QMap<QString, LDHeader::FileType> typeStrings = {
+	{"Part", LDHeader::Part},
+	{"Subpart", LDHeader::Subpart},
+	{"Shortcut", LDHeader::Shortcut},
+	{"Primitive", LDHeader::Primitive},
+	{"8_Primitive", LDHeader::Primitive_8},
+	{"48_Primitive", LDHeader::Primitive_48},
+	{"Configuration", LDHeader::Configuration},
+};
+
+QString headerTypeToString(const LDHeader::FileType fileType)
+{
+	QMapIterator<QString, LDHeader::FileType> it{::typeStrings};
+	while (it.hasNext())
+	{
+		it.next();
+		if (it.value() == fileType)
+		{
+			return it.key();
+		}
+	}
+	return "Part";
+}
+
+LDHeader::FileType headerTypeFromString(const QString& string)
+{
+	return ::typeStrings.value(string, LDHeader::Part);
+}
+
+QString headerToString(const LDHeader& header)
+{
+	QString result;
+	result += "0 " + header.description + "\r\n";
+	result += "Name: " + header.name + "\r\n";
+	result += "Author: " + header.author + "\r\n";
+	if (header.type != LDHeader::NoHeader)
+	{
+		result += "0 !LDRAW Unofficial_" + headerTypeToString(header.type) + "\r\n";
+	}
+	switch (header.license)
+	{
+	case LDHeader::UnspecifiedLicense:
+		break;
+	case LDHeader::CaLicense:
+		result += LDHeader::caLicenseString + "\r\n";
+		break;
+	case LDHeader::NonCaLicense:
+		result += LDHeader::nonCaLicenseString + "\r\n";
+		break;
+	}
+	if (not header.help.isEmpty())
+	{
+		result += "\r\n";
+		for (const QString& helpLine : header.help.split("\n"))
+		{
+			result += "0 !HELP " + helpLine + "\r\n";
+		}
+	}
+	result += "\r\n";
+	// FIXME: continue
+	return result;
+}
--- a/src/header.h	Wed Sep 22 14:03:43 2021 +0300
+++ b/src/header.h	Mon Sep 27 21:04:45 2021 +0300
@@ -22,6 +22,8 @@
 
 struct LDHeader
 {
+	static const QString caLicenseString;
+	static const QString nonCaLicenseString;
 	struct HistoryEntry
 	{
 		QDate date;
@@ -63,4 +65,8 @@
 	static decltype(license) defaultLicense();
 };
 
+LDHeader::FileType headerTypeFromString(const QString& string);
+QString headerTypeToString(const LDHeader::FileType fileType);
+QString headerToString(const LDHeader& header);
+
 Q_DECLARE_OPERATORS_FOR_FLAGS(QFlags<LDHeader::Qualifier>)
--- a/src/linetypes/subfilereference.cpp	Wed Sep 22 14:03:43 2021 +0300
+++ b/src/linetypes/subfilereference.cpp	Mon Sep 27 21:04:45 2021 +0300
@@ -36,7 +36,13 @@
 
 QString ldraw::SubfileReference::textRepresentation() const
 {
-	return referenceName + " " + utility::vertexToStringParens(this->position());
+	QString out;
+	if (this->isInverted)
+	{
+		out += "0 BFC INVERTNEXT\r\n";
+	}
+	out += referenceName + " " + utility::vertexToStringParens(this->position());
+	return out;
 }
 
 void ldraw::SubfileReference::getPolygons
--- a/src/model.cpp	Wed Sep 22 14:03:43 2021 +0300
+++ b/src/model.cpp	Mon Sep 27 21:04:45 2021 +0300
@@ -17,6 +17,7 @@
  */
 
 #include <QBrush>
+#include <QFile>
 #include <QFont>
 #include "model.h"
 #include "modeleditcontext.h"
@@ -25,8 +26,17 @@
  * @brief Constructs a model
  * @param parent QObject parent to pass forward
  */
-Model::Model(QObject* parent) :
-	QAbstractListModel{parent}
+Model::Model(QObject* parent) : 
+	Model{"", parent} {}
+
+/**
+ * @brief Constructs a model
+ * @param path Path that was used to open the model
+ * @param parent QObject parent to pass forward
+ */
+Model::Model(const QString& path, QObject *parent) :
+	QAbstractListModel{parent},
+	path{path}
 {
 	connect(this, &Model::dataChanged, [&](){ this->needRecache = true; });
 }
@@ -256,3 +266,20 @@
 {
 	return this->body[unsigned_cast(index.row())].get();
 }
+
+/**
+ * @brief Write out the model as text
+ */
+void Model::save() const
+{
+	QFile file{this->path};
+	if (file.open(QIODevice::WriteOnly))
+	{
+		QTextStream out{&file};
+		for (const ModelObjectPointer& object : this->body)
+		{
+			out << object.get()->textRepresentation() << "\r\n";
+		}
+		file.close();
+	}
+}
\ No newline at end of file
--- a/src/model.h	Wed Sep 22 14:03:43 2021 +0300
+++ b/src/model.h	Mon Sep 27 21:04:45 2021 +0300
@@ -34,6 +34,7 @@
 	Q_OBJECT
 public:
 	class EditContext;
+	Model(const QString& path, QObject* parent = nullptr);
 	Model(QObject* parent = nullptr);
 	Model(const Model&) = delete;
 	int size() const;
@@ -61,6 +62,7 @@
 	Get2Result<R> get2(ldraw::Id<R> id) const;
 	template<typename R, typename Fn>
 	void apply(Fn f) const;
+	void save() const;
 Q_SIGNALS:
 	void objectAdded(ldraw::id_t id, int position);
 	void objectModified(ldraw::id_t id, int position);
--- a/src/parser.cpp	Wed Sep 22 14:03:43 2021 +0300
+++ b/src/parser.cpp	Mon Sep 27 21:04:45 2021 +0300
@@ -48,16 +48,6 @@
 	return QString::fromUtf8(this->device.readLine()).trimmed();
 }
 
-static const QMap<QString, LDHeader::FileType> typeStrings {
-	{"Part", LDHeader::Part},
-	{"Subpart", LDHeader::Subpart},
-	{"Shortcut", LDHeader::Shortcut},
-	{"Primitive", LDHeader::Primitive},
-	{"8_Primitive", LDHeader::Primitive_8},
-	{"48_Primitive", LDHeader::Primitive_48},
-	{"Configuration", LDHeader::Configuration},
-};
-
 /*
  * Parses a single line of the header.
  * Possible parse results:
@@ -91,7 +81,7 @@
 			// consideration.
 			if (partTypeString.startsWith("Unofficial_"))
 				partTypeString = partTypeString.mid(strlen("Unofficial_"));
-			header.type = typeStrings.value(partTypeString, LDHeader::Part);
+			header.type = headerTypeFromString(partTypeString);
 			header.qualfiers = {};
 			if (tokens.contains("Alias"))
 				header.qualfiers |= LDHeader::Alias;
@@ -183,12 +173,12 @@
 		header.cmdline = line.mid(strlen("0 !CMDLINE "));
 		return ParseSuccess;
 	}
-	else if (line.startsWith("0 !LICENSE Redistributable under CCAL version 2.0"))
+	else if (line.startsWith(LDHeader::caLicenseString))
 	{
 		header.license = LDHeader::CaLicense;
 		return ParseSuccess;
 	}
-	else if (line.startsWith("0 !LICENSE Not redistributable"))
+	else if (line.startsWith(LDHeader::nonCaLicenseString))
 	{
 		header.license = LDHeader::NonCaLicense;
 		return ParseSuccess;

mercurial