Now compiles again

Sun, 04 Oct 2015 02:52:03 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sun, 04 Oct 2015 02:52:03 +0300
changeset 998
5be0ce31ce60
parent 997
1b49f34e533d
child 999
213a7c7a3ce4

Now compiles again

src/addObjectDialog.cpp file | annotate | diff | comparison | revisions
src/colors.cpp file | annotate | diff | comparison | revisions
src/colors.h file | annotate | diff | comparison | revisions
src/dialogs/colorselector.cpp file | annotate | diff | comparison | revisions
src/dialogs/configdialog.cpp file | annotate | diff | comparison | revisions
src/documentmanager.cpp file | annotate | diff | comparison | revisions
src/documentmanager.h file | annotate | diff | comparison | revisions
src/glCompiler.cpp file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/ldDocument.cpp file | annotate | diff | comparison | revisions
src/ldDocument.h file | annotate | diff | comparison | revisions
src/ldObject.cpp file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/partdownloadrequest.cpp file | annotate | diff | comparison | revisions
src/partdownloadrequest.h file | annotate | diff | comparison | revisions
src/primitives.cpp file | annotate | diff | comparison | revisions
src/toolsets/algorithmtoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/extprogramtoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/filetoolset.cpp file | annotate | diff | comparison | revisions
--- a/src/addObjectDialog.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/addObjectDialog.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -281,6 +281,7 @@
 
 // =============================================================================
 // =============================================================================
+#include "documentmanager.h"
 void AddObjectDialog::staticDialog (const LDObjectType type, LDObject* obj)
 {
 	setlocale (LC_ALL, "C");
@@ -363,9 +364,9 @@
 			if (name.length() == 0)
 				return; // no subfile filename
 
-			LDDocument* file = GetDocument (name);
+			LDDocument* document = g_win->documents()->getDocumentByName (name);
 
-			if (not file)
+			if (not document)
 			{
 				Critical (format ("Couldn't open `%1': %2", name, strerror (errno)));
 				return;
@@ -377,7 +378,7 @@
 				ref->setCoordinate (ax, dlg.dsb_coords[ax]->value());
 
 			ref->setTransform (transform);
-			ref->setFileInfo (file);
+			ref->setFileInfo (document);
 		} break;
 
 		default:
--- a/src/colors.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/colors.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -17,43 +17,26 @@
  */
 
 #include <QFile>
+#include <QMessageBox>
 #include "main.h"
 #include "colors.h"
 #include "ldDocument.h"
 #include "miscallenous.h"
 #include "mainwindow.h"
+#include "documentmanager.h"
 
-struct ColorDataEntry
-{
-	QString name;
-	QString hexcode;
-	QColor faceColor;
-	QColor edgeColor;
-};
+static ColorData* colorData = nullptr;
 
-static ColorDataEntry ColorData[512];
-
-void InitColors()
+void initColors()
 {
 	print ("Initializing color information.\n");
-
-	// Always make sure there's 16 and 24 available. They're special like that.
-	ColorData[MainColor].faceColor =
-	ColorData[MainColor].hexcode = "#AAAAAA";
-	ColorData[MainColor].edgeColor = Qt::black;
-	ColorData[MainColor].name = "Main color";
-
-	ColorData[EdgeColor].faceColor =
-	ColorData[EdgeColor].edgeColor =
-	ColorData[EdgeColor].hexcode = "#000000";
-	ColorData[EdgeColor].name = "Edge color";
-
-	parseLDConfig();
+	static ColorData colors;
+	colorData = &colors;
 }
 
 bool LDColor::isValid() const
 {
-	if (isLDConfigColor() and ColorData[index()].name.isEmpty())
+	if (isLDConfigColor() and data().name.isEmpty())
 		return false; // Unknown LDConfig color
 
 	return m_index != -1;
@@ -61,7 +44,12 @@
 
 bool LDColor::isLDConfigColor() const
 {
-	return index() >= 0 and index() < countof (ColorData);
+	return colorData->contains (index());
+}
+
+const ColorData::Entry& LDColor::data() const
+{
+	return colorData->get (index());
 }
 
 QString LDColor::name() const
@@ -69,7 +57,7 @@
 	if (isDirect())
 		return "0x" + QString::number (index(), 16).toUpper();
 	else if (isLDConfigColor())
-		return ColorData[index()].name;
+		return data().name;
 	else if (index() == -1)
 		return "null color";
 	else
@@ -97,7 +85,7 @@
 	}
 	else if (isLDConfigColor())
 	{
-		return ColorData[index()].faceColor;
+		return data().faceColor;
 	}
 	else
 	{
@@ -108,21 +96,21 @@
 QColor LDColor::edgeColor() const
 {
 	if (isDirect())
-		return Luma (faceColor()) < 48 ? Qt::white : Qt::black;
+		return ::luma (faceColor()) < 48 ? Qt::white : Qt::black;
 	else if (isLDConfigColor())
-		return ColorData[index()].edgeColor;
+		return data().edgeColor;
 	else
 		return Qt::black;
 }
 
 int LDColor::luma() const
 {
-	return Luma (faceColor());
+	return ::luma (faceColor());
 }
 
 int LDColor::edgeLuma() const
 {
-	return Luma (edgeColor());
+	return ::luma (edgeColor());
 }
 
 qint32 LDColor::index() const
@@ -143,30 +131,65 @@
 	return index() >= 0x02000000;
 }
 
-int Luma (const QColor& col)
+int luma (const QColor& col)
 {
 	return (0.2126f * col.red()) + (0.7152f * col.green()) + (0.0722f * col.blue());
 }
 
-int CountLDConfigColors()
+ColorData::ColorData()
 {
-	return countof (ColorData);
+	if (colorData == nullptr)
+		colorData = this;
+
+	// Initialize main and edge colors, they're special like that.
+	m_data[MainColor].faceColor =
+	m_data[MainColor].hexcode = "#AAAAAA";
+	m_data[MainColor].edgeColor = Qt::black;
+	m_data[MainColor].name = "Main color";
+	m_data[EdgeColor].faceColor =
+	m_data[EdgeColor].edgeColor =
+	m_data[EdgeColor].hexcode = "#000000";
+	m_data[EdgeColor].name = "Edge color";
+	loadFromLdconfig();
+}
+
+ColorData::~ColorData()
+{
+	if (colorData == this)
+		colorData = nullptr;
 }
 
-void parseLDConfig()
+bool ColorData::contains (int code) const
 {
-	QFile* fp = OpenLDrawFile ("LDConfig.ldr", false);
+	return code >= 0 and code < EntryCount;
+}
+
+const ColorData::Entry& ColorData::get (int code) const
+{
+	if (not contains (code))
+		throw std::runtime_error ("Attempted to get non-existant color information");
 
-	if (fp == nullptr)
+	return m_data[code];
+}
+
+void ColorData::loadFromLdconfig()
+{
+	if (not g_win)
+		return;
+
+	QString path = g_win->documents()->findDocumentPath ("LDConfig.ldr", false);
+	QFile fp (path);
+
+	if (not fp.open (QIODevice::ReadOnly))
 	{
-		Critical (QObject::tr ("Unable to open LDConfig.ldr for parsing."));
+		QMessageBox::critical (nullptr, "Error", "Unable to open LDConfig.ldr for parsing: " + fp.errorString());
 		return;
 	}
 
-	// Read in the lines
-	while (not fp->atEnd())
+	// TODO: maybe LDConfig can be loaded as a Document? Or would that be overkill?
+	while (not fp.atEnd())
 	{
-		QString line = QString::fromUtf8 (fp->readLine());
+		QString line = QString::fromUtf8 (fp.readLine());
 
 		if (line.isEmpty() or line[0] != '0')
 			continue; // empty or illogical
@@ -175,58 +198,47 @@
 		line.remove ('\n');
 
 		// Parse the line
-		LDConfigParser pars (line, ' ');
-
-		int code = 0, alpha = 255;
-		QString name, facename, edgename, valuestr;
+		LDConfigParser parser (line, ' ');
+		QString name;
+		QString facename;
+		QString edgename;
+		QString codestring;
 
 		// Check 0 !COLOUR, parse the name
-		if (not pars.compareToken (0, "0") or
-			not pars.compareToken (1, "!COLOUR") or
-			not pars.getToken (name, 2))
-		{
+		if (not parser.compareToken (0, "0") or not parser.compareToken (1, "!COLOUR") or not parser.getToken (name, 2))
 			continue;
-		}
 
 		// Replace underscores in the name with spaces for readability
 		name.replace ("_", " ");
 
-		// Get the CODE tag
-		if (not pars.parseLDConfigTag ("CODE", valuestr))
+		if (not parser.parseTag ("CODE", codestring))
 			continue;
 
-		// Ensure that the code is within [0 - 511]
 		bool ok;
-		code = valuestr.toShort (&ok);
+		int code = codestring.toShort (&ok);
 
-		if (not ok or code < 0 or code >= 512)
+		if (not ok or not contains (code))
 			continue;
 
-		// VALUE and EDGE tags
-		if (not pars.parseLDConfigTag ("VALUE", facename) or not pars.parseLDConfigTag ("EDGE", edgename))
+		if (not parser.parseTag ("VALUE", facename) or not parser.parseTag ("EDGE", edgename))
 			continue;
 
 		// Ensure that our colors are correct
-		QColor faceColor (facename),
-			edgeColor (edgename);
+		QColor faceColor (facename);
+		QColor edgeColor (edgename);
 
 		if (not faceColor.isValid() or not edgeColor.isValid())
 			continue;
 
-		// Parse alpha if given.
-		if (pars.parseLDConfigTag ("ALPHA", valuestr))
-			alpha = qBound (0, valuestr.toInt(), 255);
-
-		ColorDataEntry& entry = ColorData[code];
+		Entry& entry = m_data[code];
 		entry.name = name;
 		entry.faceColor = faceColor;
 		entry.edgeColor = edgeColor;
 		entry.hexcode = facename;
-		entry.faceColor.setAlpha (alpha);
+
+		if (parser.parseTag ("ALPHA", codestring))
+			entry.faceColor.setAlpha (qBound (0, codestring.toInt(), 255));
 	}
-
-	fp->close();
-	fp->deleteLater();
 }
 
 // =============================================================================
@@ -280,7 +292,7 @@
 //
 // Helper function for parseLDConfig
 //
-bool LDConfigParser::parseLDConfigTag (char const* tag, QString& val)
+bool LDConfigParser::parseTag (char const* tag, QString& val)
 {
 	int pos;
 
--- a/src/colors.h	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/colors.h	Sun Oct 04 02:52:03 2015 +0300
@@ -20,6 +20,28 @@
 #include <QColor>
 #include "basics.h"
 
+class ColorData
+{
+public:
+	struct Entry
+	{
+		QString name;
+		QString hexcode;
+		QColor faceColor;
+		QColor edgeColor;
+	};
+
+	enum { EntryCount = 512 };
+	ColorData();
+	~ColorData();
+	void loadFromLdconfig();
+	bool contains (int code) const;
+	const Entry& get (int code) const;
+
+private:
+	Entry m_data[EntryCount];
+};
+
 class LDColor
 {
 public:
@@ -56,6 +78,8 @@
 	bool operator>= (LDColor other) const { return index() >= other.index(); }
 
 private:
+	const ColorData::Entry& data() const;
+
 	qint32 m_index;
 };
 
@@ -70,7 +94,7 @@
 	bool getToken (QString& val, const int pos);
 	bool findToken (int& result, char const* needle, int args);
 	bool compareToken (int inPos, QString text);
-	bool parseLDConfigTag (char const* tag, QString& val);
+	bool parseTag (char const* tag, QString& val);
 
 	inline QString operator[] (const int idx)
 	{
@@ -82,10 +106,8 @@
 	int m_pos;
 };
 
-void InitColors();
-int Luma (const QColor& col);
-int CountLDConfigColors();
-void parseLDConfig();
+void initColors();
+int luma (const QColor& col);
 
 enum
 {
--- a/src/dialogs/colorselector.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/dialogs/colorselector.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -59,7 +59,7 @@
 				color.setAlphaF (m_config->mainColorAlpha());
 			}
 
-			QString color2name (Luma (color) < 80 ? "white" : "black");
+			QString color2name (luma (color) < 80 ? "white" : "black");
 			button->setAutoFillBackground (true);
 			button->setStyleSheet (format ("background-color: rgba(%1, %2, %3, %4); color: %5",
 				color.red(), color.green(), color.blue(), color.alpha(), color2name));
--- a/src/dialogs/configdialog.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/dialogs/configdialog.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -36,6 +36,7 @@
 #include "../miscallenous.h"
 #include "../glRenderer.h"
 #include "../guiutilities.h"
+#include "../documentmanager.h"
 #include "colorselector.h"
 #include "configdialog.h"
 #include "ui_configdialog.h"
@@ -276,7 +277,7 @@
 
 	m_window->syncSettings();
 	currentDocument()->reloadAllSubfiles();
-	LoadLogoStuds();
+	m_documents->loadLogoedStuds();
 	m_window->renderer()->setBackground();
 	m_window->doFullRefresh();
 	m_window->updateDocumentList();
--- a/src/documentmanager.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/documentmanager.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -16,24 +16,31 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QApplication>
 #include <QFileInfo>
 #include <QFile>
 #include "documentmanager.h"
 #include "ldDocument.h"
 #include "mainwindow.h"
 #include "partdownloader.h"
+#include "documentloader.h"
+#include "glRenderer.h"
+
+ConfigOption (QStringList RecentFiles)
+ConfigOption (bool TryDownloadMissingFiles = false)
 
 enum
 {
-	MAX_RECENT_FILES = 10
+	MaxRecentFiles = 10
 };
 
 DocumentManager::DocumentManager (QObject* parent) :
 	QObject (parent),
-	g_loadingMainFile (false),
-	g_loadingLogoedStuds (false),
-	g_logoedStud (nullptr),
-	g_logoedStud2 (nullptr) {}
+	HierarchyElement (parent),
+	m_loadingMainFile (false),
+	m_isLoadingLogoedStuds (false),
+	m_logoedStud (nullptr),
+	m_logoedStud2 (nullptr) {}
 
 DocumentManager::~DocumentManager()
 {
@@ -42,9 +49,8 @@
 
 void DocumentManager::clear()
 {
-	for (DocumentMapIterator it (m_documents); it.hasNext();)
+	for (LDDocument* document : m_documents)
 	{
-		LDDocument* document = it.next().value();
 		document->close();
 		delete document;
 	}
@@ -54,12 +60,15 @@
 
 LDDocument* DocumentManager::getDocumentByName (QString filename)
 {
-	// Try find the file in the list of loaded files
 	LDDocument* doc = findDocumentByName (filename);
 
-	// If it's not loaded, try open it
-	if (not doc)
+	if (doc == nullptr)
+	{
+		bool tmp = m_loadingMainFile;
+		m_loadingMainFile = false;
 		doc = openDocument (filename, true, true);
+		m_loadingMainFile = tmp;
+	}
 
 	return doc;
 }
@@ -71,7 +80,7 @@
 	LDDocument* file = nullptr;
 	QString shortName = LDDocument::shortenName (path);
 
-	for (LDDocument* doc : m_window->allDocuments())
+	for (LDDocument* doc : m_documents)
 	{
 		if (doc->name() == shortName)
 		{
@@ -85,7 +94,7 @@
 	if (documentToReplace and not documentToReplace->isSafeToClose())
 		return;
 
-	g_loadingMainFile = true;
+	m_loadingMainFile = true;
 
 	// If we're replacing an existing document, clear the document and
 	// make it ready for being loaded to.
@@ -107,7 +116,7 @@
 			Critical (format (tr ("Failed to open %1: %2"), path, strerror (errno)));
 		}
 
-		g_loadingMainFile = false;
+		m_loadingMainFile = false;
 		return;
 	}
 
@@ -116,7 +125,7 @@
 	m_window->changeDocument (file);
 	m_window->doFullRefresh();
 	addRecentFile (path);
-	g_loadingMainFile = false;
+	m_loadingMainFile = false;
 
 	// If there were problems loading subfile references, try see if we can find these
 	// files on the parts tracker.
@@ -147,10 +156,8 @@
 
 LDDocument* DocumentManager::findDocumentByName (QString name)
 {
-	for (DocumentMapIterator it (m_documents); it.hasNext();)
+	for (LDDocument* document : m_documents)
 	{
-		LDDocument* document = it.next().value();
-
 		if (isOneOf (name, document->name(), document->defaultName()))
 			return document;
 	}
@@ -185,48 +192,42 @@
 
 QString DocumentManager::findDocumentPath (QString relativePath, bool subdirs)
 {
-	QString fullPath;
-
 	// LDraw models use backslashes as path separators. Replace those into forward slashes for Qt.
 	relativePath.replace ("\\", "/");
 
 	// Try find it relative to other currently open documents. We want a file in the immediate vicinity of a current
 	// part model to override stock LDraw stuff.
-	QString reltop = Basename (Dirname (relativePath));
+	QString relativeTopDir = Basename (Dirname (relativePath));
 
-	for (LDDocument* doc : m_window->allDocuments())
+	for (LDDocument* document : m_documents)
 	{
-		QString partpath = format ("%1/%2", Dirname (doc->fullPath()), relativePath);
-		QFile f (partpath);
+		QString partpath = format ("%1/%2", Dirname (document->fullPath()), relativePath);
+		QFileInfo fileinfo (partpath);
 
-		if (f.exists())
+		if (fileinfo.exists())
 		{
-			// ensure we don't mix subfiles and 48-primitives with non-subfiles and non-48
-			QString proptop = Basename (Dirname (partpath));
-
-			bool bogus = false;
+			// Ensure we don't mix subfiles and 48-primitives with non-subfiles and non-48
+			QString partTopDir = Basename (Dirname (partpath));
 
-			for (QString s : g_specialSubdirectories)
+			for (QString subdir : g_specialSubdirectories)
 			{
-				if ((proptop == s and reltop != s) or (reltop == s and proptop != s))
-				{
-					bogus = true;
-					break;
-				}
+				if ((partTopDir == subdir) != (relativeTopDir == subdir))
+					goto skipthis;
 			}
 
-			if (not bogus)
-				return partpath;
+			return partpath;
 		}
+skipthis:
+		continue;
 	}
 
-	if (QFile::exists (relativePath))
+	if (QFileInfo::exists (relativePath))
 		return relativePath;
 
 	// Try with just the LDraw path first
-	fullPath = format ("%1" DIRSLASH "%2", m_window->configBag()->lDrawPath(), relativePath);
+	QString fullPath = format ("%1" DIRSLASH "%2", m_window->configBag()->lDrawPath(), relativePath);
 
-	if (QFile::exists (fullPath))
+	if (QFileInfo::exists (fullPath))
 		return fullPath;
 
 	if (subdirs)
@@ -277,7 +278,7 @@
 	if (numWarnings)
 		*numWarnings = 0;
 
-	DocumentLoader* loader = new DocumentLoader (g_loadingMainFile);
+	DocumentLoader* loader = new DocumentLoader (m_loadingMainFile);
 	loader->read (fp);
 	loader->start();
 
@@ -348,7 +349,7 @@
 
 	load->addObjects (objs);
 
-	if (g_loadingMainFile)
+	if (m_loadingMainFile)
 	{
 		m_window->changeDocument (load);
 		m_window->renderer()->setDocument (load);
@@ -359,12 +360,6 @@
 	return load;
 }
 
-void DocumentManager::closeAllDocuments()
-{
-	for (LDDocument* file : m_window->allDocuments())
-		file->close();
-}
-
 void DocumentManager::addRecentFile (QString path)
 {
 	QStringList recentFiles = m_window->configBag()->recentFiles();
@@ -380,7 +375,7 @@
 	}
 
 	// If there's too many recent files, drop one out.
-	while (recentFiles.size() > (MAX_RECENT_FILES - 1))
+	while (recentFiles.size() > (MaxRecentFiles - 1))
 		recentFiles.removeAt (0);
 
 	// Add the file
@@ -392,9 +387,9 @@
 
 bool DocumentManager::isSafeToCloseAll()
 {
-	for (LDDocument* f : m_window->allDocuments())
+	for (LDDocument* document : m_documents)
 	{
-		if (not f->isSafeToClose())
+		if (not document->isSafeToClose())
 			return false;
 	}
 
@@ -403,17 +398,19 @@
 
 void DocumentManager::loadLogoedStuds()
 {
-	if (g_loadingLogoedStuds or (g_logoedStud and g_logoedStud2))
+	if (m_isLoadingLogoedStuds or (m_logoedStud and m_logoedStud2))
 		return;
 
-	g_loadingLogoedStuds = true;
-	g_logoedStud = openDocument ("stud-logo.dat", true, true);
-	g_logoedStud2 = openDocument ("stud2-logo.dat", true, true);
-	print (tr ("Logoed studs loaded.\n"));
-	g_loadingLogoedStuds = false;
+	m_isLoadingLogoedStuds = true;
+	m_logoedStud = openDocument ("stud-logo.dat", true, true);
+	m_logoedStud2 = openDocument ("stud2-logo.dat", true, true);
+	m_isLoadingLogoedStuds = false;
+
+	if (m_logoedStud and m_logoedStud2)
+		print (tr ("Logoed studs loaded.\n"));
 }
 
-bool DocumentManager::preInline (LDDocument* doc, LDObjectList& objs)
+bool DocumentManager::preInline (LDDocument* doc, LDObjectList& objs, bool deep, bool renderinline)
 {
 	// Possibly substitute with logoed studs:
 	// stud.dat -> stud-logo.dat
@@ -423,9 +420,23 @@
 		// Ensure logoed studs are loaded first
 		loadLogoedStuds();
 
-		if (doc->name() == "stud.dat" and g_logoedStud)
-			return g_logoedStud->inlineContents (deep, renderinline);
-		else if (doc->name() == "stud2.dat" and g_logoedStud2)
-			return g_logoedStud2->inlineContents (deep, renderinline);
+		if (doc->name() == "stud.dat" and m_logoedStud)
+		{
+			objs = m_logoedStud->inlineContents (deep, renderinline);
+			return true;
+		}
+		else if (doc->name() == "stud2.dat" and m_logoedStud2)
+		{
+			objs = m_logoedStud2->inlineContents (deep, renderinline);
+			return true;
+		}
 	}
+	return false;
 }
+
+LDDocument* DocumentManager::createNew()
+{
+	LDDocument* document = new LDDocument (this);
+	m_documents.insert (document);
+	return document;
+}
--- a/src/documentmanager.h	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/documentmanager.h	Sun Oct 04 02:52:03 2015 +0300
@@ -17,6 +17,7 @@
  */
 
 #pragma once
+#include <QSet>
 #include "main.h"
 #include "hierarchyelement.h"
 
@@ -25,33 +26,32 @@
 	Q_OBJECT
 
 public:
-	using DocumentMap = QHash<QString, LDDocument*>;
-	using DocumentMapIterator = QHashIterator<QString, LDDocument*>;
+	using Documents = QSet<LDDocument*>;
 
 	DocumentManager (QObject* parent = nullptr);
 	~DocumentManager();
 
 	void addRecentFile (QString path);
+	const Documents& allDocuments() const { return m_documents; }
 	void clear();
-	void closeAllDocuments();
+	LDDocument* createNew();
 	LDDocument* findDocumentByName (QString name);
 	QString findDocumentPath (QString relpath, bool subdirs);
 	LDDocument* getDocumentByName (QString filename);
 	bool isSafeToCloseAll();
+	LDObjectList loadFileContents (QFile* fp, int* numWarnings, bool* ok);
 	void loadLogoedStuds();
-	LDDocument* openDocument (QString path, bool search, bool implicit, LDDocument* fileToOverride, bool* aborted);
+	LDDocument* openDocument (QString path, bool search, bool implicit, LDDocument* fileToOverride = nullptr, bool* aborted = nullptr);
 	QFile* openLDrawFile (QString relpath, bool subdirs, QString* pathpointer);
 	void openMainModel (QString path);
-	bool preInline (LDDocument* doc, LDObjectList& objs);
+	bool preInline (LDDocument* doc, LDObjectList&, bool deep, bool renderinline);
 
 private:
-	DocumentMap m_documents;
-	bool g_loadingMainFile;
-	bool g_loadingLogoedStuds;
-	LDDocument* g_logoedStud;
-	LDDocument* g_logoedStud2;
-
-	LDObjectList loadFileContents (QFile* fp, int* numWarnings, bool* ok);
+	Documents m_documents;
+	bool m_loadingMainFile;
+	bool m_isLoadingLogoedStuds;
+	LDDocument* m_logoedStud;
+	LDDocument* m_logoedStud2;
 };
 
 static const QStringList g_specialSubdirectories ({ "s", "48", "8" });
\ No newline at end of file
--- a/src/glCompiler.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/glCompiler.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -151,7 +151,7 @@
 		}
 		else if (poly.color == EdgeColor)
 		{
-			qcol = Luma (QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white;
+			qcol = luma (QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white;
 		}
 		else
 		{
--- a/src/glRenderer.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/glRenderer.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -40,6 +40,7 @@
 #include "messageLog.h"
 #include "glCompiler.h"
 #include "primitives.h"
+#include "documentmanager.h"
 
 const LDFixedCamera g_FixedCameras[6] =
 {
@@ -336,7 +337,7 @@
 		return;
 
 	color.setAlpha (255);
-	m_useDarkBackground = Luma (color) < 80;
+	m_useDarkBackground = luma (color) < 80;
 	m_backgroundColor = color;
 	qglClearColor (color);
 }
@@ -607,7 +608,7 @@
 {
 	QPen linepen (m_thinBorderPen);
 	linepen.setWidth (2);
-	linepen.setColor (Luma (m_backgroundColor) < 40 ? Qt::white : Qt::black);
+	linepen.setColor (luma (m_backgroundColor) < 40 ? Qt::white : Qt::black);
 	return linepen;
 }
 
@@ -1581,7 +1582,7 @@
 		QString primitiveName = item->primitive()->name;
 		LDSubfile* ref = LDSpawn<LDSubfile>();
 		ref->setColor (MainColor);
-		ref->setFileInfo (GetDocument (primitiveName));
+		ref->setFileInfo (m_documents->getDocumentByName (primitiveName));
 		ref->setPosition (Origin);
 		ref->setTransform (IdentityMatrix);
 		currentDocument()->insertObj (m_window->suggestInsertPoint(), ref);
--- a/src/ldDocument.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/ldDocument.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -32,9 +32,7 @@
 #include "ldpaths.h"
 #include "documentloader.h"
 #include "dialogs/openprogressdialog.h"
-
-ConfigOption (QStringList RecentFiles)
-ConfigOption (bool TryDownloadMissingFiles = false)
+#include "documentmanager.h"
 
 LDDocument::LDDocument (DocumentManager* parent) :
 	QObject (parent),
@@ -54,10 +52,11 @@
 
 LDDocument::~LDDocument()
 {
+	m_beingDestroyed = true;
+
 	for (int i = 0; i < m_objects.size(); ++i)
-		delete m_objects[i];
+		m_objects[i]->destroy();
 
-	m_beingDestroyed = true;
 	delete m_history;
 	delete m_gldata;
 }
@@ -456,17 +455,11 @@
 				// Subfile
 				CheckTokenCount (tokens, 15);
 				CheckTokenNumbers (tokens, 1, 13);
-
-				// Try open the file. Disable g_loadingMainFile temporarily since we're
-				// not loading the main file now, but the subfile in question.
-				bool tmp = g_loadingMainFile;
-				g_loadingMainFile = false;
-				LDDocument* load = GetDocument (tokens[14]);
-				g_loadingMainFile = tmp;
+				LDDocument* document = g_win->documents()->getDocumentByName (tokens[14]);
 
 				// If we cannot open the file, mark it an error. Note we cannot use LDParseError
 				// here because the error object needs the document reference.
-				if (not load)
+				if (not document)
 				{
 					LDError* obj = LDSpawn<LDError> (line, format ("Could not open %1", tokens[14]));
 					obj->setFileReferenced (tokens[14]);
@@ -483,7 +476,7 @@
 					transform[i] = tokens[i + 5].toDouble(); // 5 - 13
 
 				obj->setTransform (transform);
-				obj->setFileInfo (load);
+				obj->setFileInfo (document);
 				return obj;
 			}
 
@@ -562,7 +555,7 @@
 		if (obj->type() == OBJ_Subfile)
 		{
 			LDSubfile* ref = static_cast<LDSubfile*> (obj);
-			LDDocument* fileInfo = GetDocument (ref->fileInfo()->name());
+			LDDocument* fileInfo = m_documents->getDocumentByName (ref->fileInfo()->name());
 
 			if (fileInfo)
 			{
@@ -794,9 +787,9 @@
 // -----------------------------------------------------------------------------
 LDObjectList LDDocument::inlineContents (bool deep, bool renderinline)
 {
-	LDObjectList objs, objcache;
+	LDObjectList objs;
 
-	if (m_manager->preInline (this, objs))
+	if (m_manager->preInline (this, objs, deep, renderinline))
 		return objs; // Manager dealt with this inline
 
 	for (LDObject* obj : objects())
--- a/src/ldDocument.h	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/ldDocument.h	Sun Oct 04 02:52:03 2015 +0300
@@ -123,14 +123,5 @@
 
 // Parses a string line containing an LDraw object and returns the object parsed.
 LDObject* ParseLine (QString line);
-
-// Is it safe to close all files?
-bool IsSafeToCloseAll();
-
-LDObjectList LoadFileContents (QFile* f, int* numWarnings, bool* ok = nullptr);
-
-const LDObjectList& selectedObjects();
-void AddRecentFile (QString path);
-void LoadLogoStuds();
 QString Basename (QString path);
 QString Dirname (QString path);
--- a/src/ldObject.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/ldObject.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -281,8 +281,8 @@
 
 	// Remove this object from the list of LDObjects
 	g_allObjects.erase (g_allObjects.find (id()));
-
 	m_isDestroyed = true;
+	delete this;
 }
 
 // =============================================================================
--- a/src/main.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/main.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -32,6 +32,7 @@
 #include "dialogs.h"
 #include "crashCatcher.h"
 #include "ldpaths.h"
+#include "documentmanager.h"
 
 MainWindow* g_win = nullptr;
 const Vertex Origin (0.0f, 0.0f, 0.0f);
@@ -51,13 +52,13 @@
 	LDPaths* paths = new LDPaths (win);
 	paths->checkPaths();
 	paths->deleteLater();
-	InitColors();
+	initColors();
 	LoadPrimitives();
 	win->show();
 
 	// Process the command line
 	for (int arg = 1; arg < argc; ++arg)
-		OpenMainModel (QString::fromLocal8Bit (argv[arg]));
+		win->documents()->openMainModel (QString::fromLocal8Bit (argv[arg]));
 
 	return app.exec();
 }
\ No newline at end of file
--- a/src/mainwindow.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/mainwindow.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -56,9 +56,6 @@
 #include "glCompiler.h"
 #include "documentmanager.h"
 
-static bool g_isSelectionLocked = false;
-static QMap<QAction*, QKeySequence> g_defaultShortcuts;
-
 ConfigOption (bool ColorizeObjectsList = true)
 ConfigOption (QString QuickColorToolbar = "4:25:14:27:2:3:11:1:22:|:0:72:71:15")
 ConfigOption (bool ListImplicitFiles = false)
@@ -74,7 +71,8 @@
 	m_externalPrograms (nullptr),
 	m_settings (makeSettings (this)),
 	m_documents (new DocumentManager (this)),
-	m_currentDocument (nullptr)
+	m_currentDocument (nullptr),
+	m_isSelectionLocked (false)
 {
 	g_win = this;
 	ui.setupUi (this);
@@ -106,7 +104,7 @@
 	applyToActions ([&](QAction* act)
 	{
 		connect (act, SIGNAL (triggered()), this, SLOT (actionTriggered()));
-		g_defaultShortcuts[act] = act->shortcut();
+		m_defaultShortcuts[act] = act->shortcut();
 	});
 
 	updateGridToolBar();
@@ -377,7 +375,7 @@
 	// Lock the selection while we do this so that refreshing the object list
 	// doesn't trigger selection updating so that the selection doesn't get lost
 	// while this is done.
-	g_isSelectionLocked = true;
+	m_isSelectionLocked = true;
 	m_objectsInList.clear();
 
 	for (int i = 0; i < ui.objectList->count(); ++i)
@@ -492,7 +490,7 @@
 		ui.objectList->insertItem (ui.objectList->count(), item);
 	}
 
-	g_isSelectionLocked = false;
+	m_isSelectionLocked = false;
 	updateSelection();
 	scrollToSelection();
 }
@@ -514,7 +512,7 @@
 //
 void MainWindow::selectionChanged()
 {
-	if (g_isSelectionLocked == true or m_currentDocument == nullptr)
+	if (m_isSelectionLocked == true or m_currentDocument == nullptr)
 		return;
 
 	LDObjectList priorSelection = selectedObjects();
@@ -554,7 +552,7 @@
 void MainWindow::recentFileClicked()
 {
 	QAction* qAct = static_cast<QAction*> (sender());
-	OpenMainModel (qAct->text());
+	documents()->openMainModel (qAct->text());
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -625,7 +623,7 @@
 //
 void MainWindow::updateSelection()
 {
-	g_isSelectionLocked = true;
+	m_isSelectionLocked = true;
 	QItemSelection itemselect;
 	int top = -1;
 	int bottom = -1;
@@ -664,7 +662,7 @@
 
 	// Select multiple objects at once for performance reasons
 	ui.objectList->selectionModel()->select (itemselect, QItemSelectionModel::ClearAndSelect);
-	g_isSelectionLocked = false;
+	m_isSelectionLocked = false;
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -695,7 +693,7 @@
 void MainWindow::closeEvent (QCloseEvent* ev)
 {
 	// Check whether it's safe to close all files.
-	if (not IsSafeToCloseAll())
+	if (not m_documents->isSafeToCloseAll())
 	{
 		ev->ignore();
 		return;
@@ -859,7 +857,7 @@
 		print ("Saved to %1 (%2)", path, MakePrettyFileSize (savesize));
 
 		// Add it to recent files
-		AddRecentFile (path);
+		m_documents->addRecentFile (path);
 		return true;
 	}
 
@@ -932,7 +930,7 @@
 	while (m_tabs->count() > 0)
 		m_tabs->removeTab (0);
 
-	for (LDDocument* document : m_documents)
+	for (LDDocument* document : m_documents->allDocuments())
 	{
 		if (not document->isCache())
 		{
@@ -990,7 +988,7 @@
 	int tabIndex = m_tabs->currentIndex();
 
 	// Find the file pointer of the item that was selected.
-	for (LDDocument* document : m_documents)
+	for (LDDocument* document : m_documents->allDocuments())
 	{
 		if (not document->isCache() and document->tabIndex() == tabIndex)
 		{
@@ -1072,12 +1070,10 @@
 //
 void MainWindow::closeTab (int tabindex)
 {
-	LDDocument* doc = FindDocument (m_tabs->tabData (tabindex).toString());
+	LDDocument* doc = m_documents->findDocumentByName (m_tabs->tabData (tabindex).toString());
 
-	if (doc == nullptr)
-		return;
-
-	doc->close();
+	if (doc)
+		doc->close();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -1107,7 +1103,7 @@
 	{
 		QString const key = "shortcut_" + act->objectName();
 
-		if (g_defaultShortcuts[act] != act->shortcut())
+		if (m_defaultShortcuts[act] != act->shortcut())
 			m_settings->setValue (key, act->shortcut());
 		else
 			m_settings->remove (key);
@@ -1136,7 +1132,7 @@
 //
 QKeySequence MainWindow::defaultShortcut (QAction* act)
 {
-	return g_defaultShortcuts[act];
+	return m_defaultShortcuts[act];
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -1221,9 +1217,7 @@
 //
 LDDocument* MainWindow::newDocument (bool cache)
 {
-	LDDocument* document = new LDDocument (this);
-	m_documents.append (document);
-
+	LDDocument* document = m_documents->createNew();
 	connect (document->history(), SIGNAL (undone()), this, SLOT (historyTraversed()));
 	connect (document->history(), SIGNAL (redone()), this, SLOT (historyTraversed()));
 	connect (document->history(), SIGNAL (stepAdded()), this, SLOT (updateActions()));
@@ -1236,13 +1230,6 @@
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-const QList<LDDocument*>& MainWindow::allDocuments()
-{
-	return m_documents;
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
 LDDocument* MainWindow::currentDocument()
 {
 	return m_currentDocument;
@@ -1278,6 +1265,7 @@
 //
 void MainWindow::closeInitialDocument()
 {
+/*
 	if (m_documents.size() == 2 and
 		m_documents[0]->name().isEmpty() and
 		not m_documents[1]->name().isEmpty() and
@@ -1285,6 +1273,7 @@
 	{
 		m_documents.first()->close();
 	}
+*/
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -1301,7 +1290,7 @@
 	LDDocument* old = currentDocument();
 
 	// Find a replacement document to use
-	for (LDDocument* doc : m_documents)
+	for (LDDocument* doc : m_documents->allDocuments())
 	{
 		if (doc != old and not doc->isCache())
 		{
--- a/src/mainwindow.h	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/mainwindow.h	Sun Oct 04 02:52:03 2015 +0300
@@ -70,7 +70,6 @@
 	~MainWindow();
 
 	void addMessage (QString msg);
-	const QList<LDDocument*>& allDocuments();
 	void applyToActions (std::function<void(QAction*)> function);
 	void buildObjectList();
 	void changeDocument (LDDocument* f);
@@ -149,6 +148,8 @@
 	DocumentManager* m_documents;
 	LDDocument* m_currentDocument;
 	DoubleMap<LDObject*, QListWidgetItem*> m_objectsInList;
+	bool m_isSelectionLocked;
+	QMap<QAction*, QKeySequence> m_defaultShortcuts;
 
 private slots:
 	void selectionChanged();
--- a/src/partdownloadrequest.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/partdownloadrequest.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -26,9 +26,11 @@
 #include "partdownloader.h"
 #include "partdownloadrequest.h"
 #include "mainwindow.h"
+#include "documentmanager.h"
 
 PartDownloadRequest::PartDownloadRequest (QString url, QString dest, bool primary, PartDownloader* parent) :
 	QObject (parent),
+	HierarchyElement (parent),
 	m_state (State::Requesting),
 	m_prompt (parent),
 	m_url (url),
@@ -207,16 +209,16 @@
 	}
 
 	// Try to load this file now.
-	LDDocument* f = OpenDocument (filePath(), false, not isPrimary());
+	LDDocument* document = m_documents->openDocument (filePath(), false, not isPrimary());
 
-	if (f == nullptr)
+	if (document == nullptr)
 		return;
 
 	// Iterate through this file and check for errors. If there's any that stems
 	// from unknown file references, try resolve that by downloading the reference.
 	// This is why downloading a part may end up downloading multiple files, as
 	// it resolves dependencies.
-	for (LDObject* obj : f->objects())
+	for (LDObject* obj : document->objects())
 	{
 		LDError* err = dynamic_cast<LDError*> (obj);
 
@@ -227,12 +229,12 @@
 		prompt()->downloadFromPartsTracker (dest);
 	}
 
-	prompt()->addFile (f);
+	prompt()->addFile (document);
 
 	if (isPrimary())
 	{
-		AddRecentFile (filePath());
-		prompt()->setPrimaryFile (f);
+		m_documents->addRecentFile (filePath());
+		prompt()->setPrimaryFile (document);
 	}
 
 	prompt()->checkIfFinished();
--- a/src/partdownloadrequest.h	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/partdownloadrequest.h	Sun Oct 04 02:52:03 2015 +0300
@@ -18,10 +18,11 @@
 
 #pragma once
 #include "main.h"
+#include "hierarchyelement.h"
 
 class PartDownloader;
 
-class PartDownloadRequest : public QObject
+class PartDownloadRequest : public QObject, public HierarchyElement
 {
 	Q_OBJECT
 
--- a/src/primitives.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/primitives.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -26,6 +26,7 @@
 #include "miscallenous.h"
 #include "colors.h"
 #include "ldpaths.h"
+#include "documentmanager.h"
 
 QList<PrimitiveCategory*> g_PrimitiveCategories;
 QList<Primitive> g_primitives;
@@ -650,7 +651,7 @@
 LDDocument* GetPrimitive (PrimitiveType type, int segs, int divs, int num)
 {
 	QString name = MakeRadialFileName (type, segs, divs, num);
-	LDDocument* f = GetDocument (name);
+	LDDocument* f = g_win->documents()->getDocumentByName (name);
 
 	if (f)
 		return f;
--- a/src/toolsets/algorithmtoolset.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/toolsets/algorithmtoolset.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -32,6 +32,7 @@
 #include "../colors.h"
 #include "../ldObjectMath.h"
 #include "../ldobjectiterator.h"
+#include "../documentmanager.h"
 #include "ui_replcoords.h"
 #include "ui_editraw.h"
 #include "ui_flip.h"
@@ -516,7 +517,7 @@
 				digits.prepend ("0");
 
 			fullsubname = subdirname + "/" + Basename (parentpath) + "s" + digits + ".dat";
-		} while (FindDocument ("s\\" + Basename (fullsubname)) or QFile (fullsubname).exists());
+		} while (m_documents->findDocumentByName ("s\\" + Basename (fullsubname)) or QFile (fullsubname).exists());
 	}
 
 	// Determine the BFC winding type used in the main document - it is to
--- a/src/toolsets/extprogramtoolset.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/toolsets/extprogramtoolset.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -34,6 +34,7 @@
 #include "../radioGroup.h"
 #include "../editHistory.h"
 #include "../dialogs.h"
+#include "../documentmanager.h"
 #include "extprogramtoolset.h"
 #include "ui_ytruder.h"
 #include "ui_intersector.h"
@@ -315,7 +316,9 @@
 		return;
 	}
 
-	LDObjectList objs = LoadFileContents (&f, nullptr);
+	// TODO: I don't like how I need to go to the document manager to load objects from a file...
+	// We're not loading this as a document so it shouldn't be necessary.
+	LDObjectList objs = m_documents->loadFileContents (&f, nullptr, nullptr);
 
 	// If we replace the objects, delete the selection now.
 	if (replace)
--- a/src/toolsets/filetoolset.cpp	Tue Sep 22 23:38:19 2015 +0300
+++ b/src/toolsets/filetoolset.cpp	Sun Oct 04 02:52:03 2015 +0300
@@ -27,6 +27,7 @@
 #include "../dialogs/configdialog.h"
 #include "../dialogs/ldrawpathdialog.h"
 #include "../dialogs/newpartdialog.h"
+#include "../documentmanager.h"
 #include "filetoolset.h"
 #include "ui_makeprim.h"
 
@@ -57,7 +58,7 @@
 	if (name.isEmpty())
 		return;
 
-	OpenMainModel (name);
+	m_documents->openMainModel (name);
 }
 
 void FileToolset::save()
@@ -72,7 +73,7 @@
 
 void FileToolset::saveAll()
 {
-	for (LDDocument* file : m_window->allDocuments())
+	for (LDDocument* file : m_documents->allDocuments())
 		m_window->save (file, false);
 }
 
@@ -86,10 +87,8 @@
 
 void FileToolset::closeAll()
 {
-	if (not IsSafeToCloseAll())
-		return;
-
-	CloseAllDocuments();
+	if (m_documents->isSafeToCloseAll())
+		m_documents->clear();
 }
 
 void FileToolset::settings()
@@ -126,7 +125,8 @@
 		return;
 	}
 
-	LDObjectList objs = LoadFileContents (&f, nullptr);
+	// TODO: shouldn't need to go to the document manager to parse a file
+	LDObjectList objs = m_documents->loadFileContents (&f, nullptr, nullptr);
 
 	currentDocument()->clearSelection();
 

mercurial