From 0392694560d530c14aced7ac21f85b18b676a685 Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@osirion.org>
Date: Tue, 21 Feb 2012 22:30:21 +0000
Subject: Initial support to preserve ini file comments

---
 src/editorwindow.cc     | 10 ++++++----
 src/entityproperties.cc | 25 ++++++++++++++++++++++---
 src/entityproperties.h  |  4 ++--
 src/inistream.cc        |  9 +++++++++
 src/inistream.h         | 14 +++++++++++---
 src/properties.cc       |  5 ++++-
 src/properties.h        | 18 ++++++++++++++++--
 src/zoneproperties.cc   | 13 +++++++++++++
 8 files changed, 83 insertions(+), 15 deletions(-)

diff --git a/src/editorwindow.cc b/src/editorwindow.cc
index 446f6d7..a15ed43 100644
--- a/src/editorwindow.cc
+++ b/src/editorwindow.cc
@@ -77,6 +77,7 @@ bool EditorWindow::loadFile(const QString &filename)
 			in_subsection = false;
 			
 			if (ini.got_section("zone")) {
+				editorwindow_zoneproperties.set_comment(ini.comment());
 				in_entity = false;
 				
 			} else if (ini.got_section("entity")) {
@@ -116,9 +117,10 @@ bool EditorWindow::loadFile(const QString &filename)
 			if (in_entity) {
 				entity = editorwindow_mapwidget->addEntity();
 				entity->properties()->set_type(ini.section());
+				entity->properties()->set_comment(ini.comment());
 			}
 			if (entity && in_subsection) {
-				entity->properties()->add_subsection_header(ini.section());
+				entity->properties()->add_subsection_header(ini.section(), ini.comment());
 			}
 
 		} else if(ini.got_key()) {
@@ -143,11 +145,11 @@ bool EditorWindow::loadFile(const QString &filename)
 					entity->properties()->add_info(str);
 
 				} else if (ini.got_key()) {
-					entity->properties()->add_value(ini.key(), ini.value());
+					entity->properties()->add_value(ini.key(), ini.value(), ini.comment());
 				}
 			
 			} else if (entity && in_subsection) {
-				entity->properties()->add_subsection_value(ini.key(), ini.value());
+				entity->properties()->add_subsection_value(ini.key(), ini.value(), ini.comment());
 				
 			} else if (ini.in_section("zone")) {
 				
@@ -159,7 +161,7 @@ bool EditorWindow::loadFile(const QString &filename)
 					editorwindow_zoneproperties.add_info(str);
 
 				} else if (ini.got_key()) {
-					editorwindow_zoneproperties.add_value(ini.key(), ini.value());
+					editorwindow_zoneproperties.add_value(ini.key(), ini.value(), ini.comment());
 				}
 			}
 			
diff --git a/src/entityproperties.cc b/src/entityproperties.cc
index bbef6c9..e9ed1d0 100644
--- a/src/entityproperties.cc
+++ b/src/entityproperties.cc
@@ -19,12 +19,15 @@ EntityProperties::~EntityProperties()
 {
 }
 
-void EntityProperties::add_subsection_header(const QString &header)
+void EntityProperties::add_subsection_header(const QString &header, const QString &comment)
 {
 	if (properties_subsections.size()) {
 		properties_subsections += '\n';
 	}
-		
+	
+	if (comment.size())
+		properties_subsections += comment;
+	
 	properties_subsections += '[';
 	properties_subsections += header;
 	properties_subsections += ']';
@@ -32,8 +35,11 @@ void EntityProperties::add_subsection_header(const QString &header)
 		
 }
 
-void EntityProperties::add_subsection_value(const QString &key, const QString &value)
+void EntityProperties::add_subsection_value(const QString &key, const QString &value, const QString &comment)
 {
+	if (comment.size())
+		properties_subsections += comment;
+	
 	properties_subsections += key;
 	properties_subsections += '=';
 	properties_subsections += value;
@@ -42,6 +48,19 @@ void EntityProperties::add_subsection_value(const QString &key, const QString &v
 
 void EntityProperties::save(QTextStream &textstream)
 {
+	// comments
+	if (comment().size()) {
+		// QTextStream operates on QString, not on QString const
+		QString commentbuffer = comment();
+		QTextStream commentstream(&commentbuffer);
+		QString line;
+		while (!commentstream.atEnd()) {
+			line = commentstream.readLine(1024);
+			textstream << line << '\n';
+		}
+		textstream << '\n';
+	}
+	
 	textstream << "[" << type() << "]" << '\n';
 	if (label().size())
 		textstream << "label=" << label() << '\n';
diff --git a/src/entityproperties.h b/src/entityproperties.h
index a47fc53..edf7f38 100644
--- a/src/entityproperties.h
+++ b/src/entityproperties.h
@@ -64,12 +64,12 @@ public:
 	/**
 	 * @brief add a header to the subsection string of this object
 	 * */
-	void add_subsection_header(const QString &header);
+	void add_subsection_header(const QString &header, const QString &comment);
 	
 	/**
 	 * @brief add a value key pair to the subsection string of this object
 	 * */
-	void add_subsection_value(const QString &key, const QString &value);
+	void add_subsection_value(const QString &key, const QString &value,const QString &comment);
 	
 	/**
 	 * @brief set the type string of this object
diff --git a/src/inistream.cc b/src/inistream.cc
index c89056f..7a73ea9 100644
--- a/src/inistream.cc
+++ b/src/inistream.cc
@@ -51,6 +51,9 @@ bool IniStream::getline(QTextStream &textstream)
 
 		if (line[0] == '#' || line[0] == ';') {
 			//  line with comment
+			comment_next += line;
+			comment_next += '\n';
+			
 		} else {
 			// section header
 			if (line.size() > 2 && line.startsWith('[') && line.endsWith(']')) {
@@ -61,6 +64,9 @@ bool IniStream::getline(QTextStream &textstream)
 				section_current = section_current.trimmed();
 				section_current.toLower();
 
+				comment_current = comment_next;
+				comment_next.clear();
+				
 				last_read_was_section = true;
 				return true;
 			} else {
@@ -78,6 +84,9 @@ bool IniStream::getline(QTextStream &textstream)
 						value_current.remove(0, key_current.size() + 1);
 						value_current = value_current.trimmed();
 						
+						comment_current = comment_next;
+						comment_next.clear();
+						
 						last_read_was_key = true;
 						return true;
 					}
diff --git a/src/inistream.h b/src/inistream.h
index 08a6ef4..5ff1237 100644
--- a/src/inistream.h
+++ b/src/inistream.h
@@ -31,17 +31,17 @@ public:
 	bool getline(QTextStream &textstream);
 
 	/// current section label
-	inline QString section() const {
+	inline const QString & section() const {
 		return section_current;
 	}
 
 	/// current key
-	inline QString key() const {
+	inline const QString & key() const {
 		return key_current;
 	}
 
 	/// current value
-	inline QString value() const {
+	inline const QString & value() const {
 		return value_current;
 	}
 	
@@ -49,6 +49,11 @@ public:
 	inline unsigned int line() const {
 		return line_number;
 	}
+	
+	/// comment string for the current section or key/value pair
+	inline const QString & comment() const {
+		return comment_current;
+	}
 
 	/// true if the last read statement was a section header
 	bool got_section() const;
@@ -94,6 +99,9 @@ private:
 	QString 		section_current;
 	QString 		key_current;
 	QString 		value_current;
+	
+	QString			comment_current;
+	QString			comment_next;
 
 	bool 			last_read_was_key;
 	bool 			last_read_was_section;
diff --git a/src/properties.cc b/src/properties.cc
index f5e2159..87633f7 100644
--- a/src/properties.cc
+++ b/src/properties.cc
@@ -18,8 +18,11 @@ Properties::~Properties()
 {
 }
 
-void Properties::add_value(const QString &key, const QString &value)
+void Properties::add_value(const QString &key, const QString &value, const QString &comment)
 {
+	if (comment.size())
+		properties_values += comment;
+	
 	properties_values += key;
 	properties_values += '=';
 	properties_values += value;
diff --git a/src/properties.h b/src/properties.h
index 6faf885..c6147e4 100644
--- a/src/properties.h
+++ b/src/properties.h
@@ -56,7 +56,13 @@ public:
 		return properties_color;
 	}
 
-		
+	/**
+	 * @brief returns the comment string of this object
+	 * */
+	inline const QString &comment() const {
+		return properties_comment;
+	}
+	
 	/**
 	 * @brief returns the info string of this object
 	 * */
@@ -73,6 +79,13 @@ public:
 	
 	/* ---- mutators ---- */
 	
+	/**
+	 * @brief set the comments string of this object
+	 * */
+	inline void set_comment(const QString &text) {
+		properties_comment = text;
+	}
+	
 	/**
 	 * @brief set the info string of this object
 	 * */
@@ -95,7 +108,7 @@ public:
 	/**
 	 * @brief add a value key pair to the values string
 	 * */
-	void add_value(const QString &key, const QString &value);
+	void add_value(const QString &key, const QString &value, const QString &comment);
 	
 	/**
 	 * @brief set the object label
@@ -151,6 +164,7 @@ public:
 	}
 	
 private:
+	QString			properties_comment;
 	QString			properties_label;
 	QString			properties_name;
 	
diff --git a/src/zoneproperties.cc b/src/zoneproperties.cc
index 35d994a..43e4804 100644
--- a/src/zoneproperties.cc
+++ b/src/zoneproperties.cc
@@ -20,6 +20,19 @@ ZoneProperties::~ZoneProperties()
 
 void ZoneProperties::save(QTextStream & textstream)
 {
+	// comments
+	if (comment().size()) {
+		// QTextStream operates on QString, not on QString const
+		QString commentbuffer = comment();
+		QTextStream commentstream(&commentbuffer);
+		QString line;
+		while (!commentstream.atEnd()) {
+			line = commentstream.readLine(1024);
+			textstream << line << '\n';
+		}
+		textstream << '\n';
+	}
+	
 	textstream << "[zone]" << '\n';
 	
 	if (name().size())
-- 
cgit v1.2.3