Make documents members of the main window

Sat, 05 Sep 2015 23:03:24 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 05 Sep 2015 23:03:24 +0300
changeset 978
4603d8fd063e
parent 977
dc3ceb65cda7
child 979
880d3fe9ac7c

Make documents members of the main window

src/addObjectDialog.cpp file | annotate | diff | comparison | revisions
src/basics.cpp file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/dialogs/configdialog.cpp file | annotate | diff | comparison | revisions
src/editHistory.cpp file | annotate | diff | comparison | revisions
src/editmodes/abstractEditMode.cpp file | annotate | diff | comparison | revisions
src/editmodes/magicWandMode.cpp file | annotate | diff | comparison | revisions
src/glCompiler.cpp file | annotate | diff | comparison | revisions
src/glCompiler.h file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/guiutilities.cpp file | annotate | diff | comparison | revisions
src/hierarchyelement.cpp file | annotate | diff | comparison | revisions
src/hierarchyelement.h 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/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/partDownloader.cpp file | annotate | diff | comparison | revisions
src/primitives.cpp file | annotate | diff | comparison | revisions
src/toolsets/algorithmtoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/algorithmtoolset.h file | annotate | diff | comparison | revisions
src/toolsets/basictoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/basictoolset.h file | annotate | diff | comparison | revisions
src/toolsets/extprogramtoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/filetoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/movetoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/viewtoolset.cpp file | annotate | diff | comparison | revisions
--- a/src/addObjectDialog.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/addObjectDialog.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -390,7 +390,7 @@
 	if (newObject)
 	{
 		int idx = g_win->getInsertionPoint();
-		CurrentDocument()->insertObj (idx, obj);
+		g_win->currentDocument()->insertObj (idx, obj);
 	}
 
 	g_win->refresh();
--- a/src/basics.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/basics.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -219,19 +219,6 @@
 
 // =============================================================================
 //
-void LDBoundingBox::calculateFromCurrentDocument()
-{
-	reset();
-
-	if (CurrentDocument() == null)
-		return;
-
-	for (LDObject* obj : CurrentDocument()->objects())
-		calcObject (obj);
-}
-
-// =============================================================================
-//
 void LDBoundingBox::calcObject (LDObject* obj)
 {
 	switch (obj->type())
--- a/src/basics.h	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/basics.h	Sat Sep 05 23:03:24 2015 +0300
@@ -165,10 +165,6 @@
 	// Clears the bounding box
 	void reset();
 
-	// Calculates the bounding box's values from the objects in the current
-	// document.
-	void calculateFromCurrentDocument();
-
 	// Returns the length of the bounding box on the longest measure.
 	double longestMeasurement() const;
 
--- a/src/dialogs/configdialog.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/dialogs/configdialog.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -275,9 +275,8 @@
 	}
 
 	m_window->syncSettings();
-	LDDocument::current()->reloadAllSubfiles();
+	currentDocument()->reloadAllSubfiles();
 	LoadLogoStuds();
-
 	m_window->R()->setBackground();
 	m_window->doFullRefresh();
 	m_window->updateDocumentList();
--- a/src/editHistory.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/editHistory.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -172,7 +172,7 @@
 //
 void EditHistory::undo() const
 {
-	LDObject* obj = CurrentDocument()->getObject (index());
+	LDObject* obj = g_win->currentDocument()->getObject (index());
 	LDObject* newobj = ParseLine (oldCode());
 	obj->replace (newobj);
 	g_win->R()->compileObject (newobj);
@@ -182,7 +182,7 @@
 //
 void EditHistory::redo() const
 {
-	LDObject* obj = CurrentDocument()->getObject (index());
+	LDObject* obj = g_win->currentDocument()->getObject (index());
 	LDObject* newobj = ParseLine (newCode());
 	obj->replace (newobj);
 	g_win->R()->compileObject (newobj);
--- a/src/editmodes/abstractEditMode.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/editmodes/abstractEditMode.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -62,16 +62,9 @@
 	AbstractEditMode (renderer),
 	m_polybrush (QBrush (QColor (64, 192, 0, 128)))
 {
-	// Disable the context menu - we need the right mouse button
-	// for removing vertices.
-	renderer->setContextMenuPolicy (Qt::NoContextMenu);
-
-	// Use the crosshair cursor when drawing.
+	renderer->setContextMenuPolicy (Qt::NoContextMenu); // We need the right mouse button for removing vertices
 	renderer->setCursor (Qt::CrossCursor);
-
-	// Clear the selection when beginning to draw.
-	CurrentDocument()->clearSelection();
-
+	m_window->currentDocument()->clearSelection();
 	m_window->updateSelection();
 	m_drawedVerts.clear();
 }
--- a/src/editmodes/magicWandMode.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/editmodes/magicWandMode.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -26,7 +26,7 @@
 	Super (renderer)
 {
 	// Get vertex<->object data
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : currentDocument()->objects())
 	{
 		// Note: this deliberately only takes vertex-objects into account.
 		// The magic wand does not process subparts.
@@ -77,7 +77,7 @@
 	{
 		if (type == Set)
 		{
-			CurrentDocument()->clearSelection();
+			currentDocument()->clearSelection();
 			m_window->buildObjList();
 		}
 
@@ -179,7 +179,7 @@
 	switch (type)
 	{
 	case Set:
-		CurrentDocument()->clearSelection();
+		currentDocument()->clearSelection();
 	case Additive:
 		for (LDObject* obj : m_selection)
 			obj->select();
--- a/src/glCompiler.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/glCompiler.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -241,7 +241,7 @@
 //
 void GLCompiler::unstage (LDObject* obj)
 {
-	m_staged.removeOne (obj);
+	m_staged.remove (obj);
 }
 
 // =============================================================================
@@ -259,15 +259,8 @@
 //
 void GLCompiler::compileStaged()
 {
-	removeDuplicates (m_staged);
-
-	for (auto it = m_staged.begin(); it != m_staged.end(); ++it)
-	{
-		if (*it == null)
-			continue;
-
-		compileObject (*it);
-	}
+	for (QSetIterator<LDObject*> it (m_staged); it.hasNext();)
+		compileObject (it.next());
 
 	m_staged.clear();
 }
@@ -292,11 +285,8 @@
 			continue;
 		}
 
-		if (it.key()->document() == CurrentDocument()
-			and not it.key()->isHidden())
-		{
+		if (it.key()->document() == currentDocument() and not it.key()->isHidden())
 			vbodata += it->data[vbonum];
-		}
 
 		++it;
 	}
@@ -311,17 +301,13 @@
 
 // =============================================================================
 //
-void GLCompiler::dropObject (LDObject* obj)
+void GLCompiler::dropObjectInfo (LDObject* obj)
 {
-	auto it = m_objectInfo.find (obj);
-
-	if (it != m_objectInfo.end())
+	if (m_objectInfo.contains (obj))
 	{
-		m_objectInfo.erase (it);
+		m_objectInfo.remove (obj);
 		needMerge();
 	}
-
-	unstage (obj);
 }
 
 // =============================================================================
@@ -335,7 +321,7 @@
 
 	ObjectVBOInfo info;
 	info.isChanged = true;
-	dropObject (obj);
+	dropObjectInfo (obj);
 
 	switch (obj->type())
 	{
--- a/src/glCompiler.h	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/glCompiler.h	Sat Sep 05 23:03:24 2015 +0300
@@ -21,6 +21,7 @@
 #include "glRenderer.h"
 #include "glShared.h"
 #include <QMap>
+#include <QSet>
 
 // =============================================================================
 //
@@ -36,7 +37,7 @@
 	GLCompiler (GLRenderer* renderer);
 	~GLCompiler();
 	void				compileDocument (LDDocument* doc);
-	void				dropObject (LDObject* obj);
+	void				dropObjectInfo (LDObject* obj);
 	void				initialize();
 	QColor				getColorForPolygon (LDPolygon& poly, LDObject* topobj,
 											EVBOComplement complement) const;
@@ -70,11 +71,11 @@
 	void			compilePolygon (LDPolygon& poly, LDObject* topobj, ObjectVBOInfo* objinfo);
 
 	QMap<LDObject*, ObjectVBOInfo>	m_objectInfo;
-	LDObjectList						m_staged; // Objects that need to be compiled
-	GLuint									m_vbo[g_numVBOs];
-	bool									m_vboChanged[g_numVBOs];
-	int										m_vboSizes[g_numVBOs];
-	GLRenderer*								m_renderer;
+	QSet<LDObject*>					m_staged; // Objects that need to be compiled
+	GLuint							m_vbo[g_numVBOs];
+	bool							m_vboChanged[g_numVBOs];
+	int								m_vboSizes[g_numVBOs];
+	GLRenderer*						m_renderer;
 };
 
 #define CHECK_GL_ERROR() { CheckGLErrorImpl (__FILE__, __LINE__); }
--- a/src/glRenderer.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/glRenderer.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -100,7 +100,8 @@
 //
 GLRenderer::GLRenderer (QWidget* parent) :
 	QGLWidget (parent),
-	HierarchyElement (parent)
+	HierarchyElement (parent),
+	m_document (nullptr)
 {
 	m_isPicking = false;
 	m_camera = (ECamera) m_config->camera();
@@ -342,7 +343,7 @@
 	if (not RendererInitialized)
 		return;
 
-	compiler()->compileDocument (CurrentDocument());
+	compiler()->compileDocument (currentDocument());
 	refresh();
 }
 
@@ -913,10 +914,10 @@
 	// Clear the selection if we do not wish to add to it.
 	if (not additive)
 	{
-		LDObjectList oldsel = Selection();
-		CurrentDocument()->clearSelection();
+		LDObjectList oldSelection = selectedObjects();
+		currentDocument()->clearSelection();
 
-		for (LDObject* obj : oldsel)
+		for (LDObject* obj : oldSelection)
 			compileObject (obj);
 	}
 
@@ -992,7 +993,7 @@
 	m_window->updateSelection();
 
 	// Recompile the objects now to update their color
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 		compileObject (obj);
 
 	if (removedObj)
@@ -1137,8 +1138,11 @@
 //
 void GLRenderer::forgetObject (LDObject* obj)
 {
-	if (compiler() != null)
-		compiler()->dropObject (obj);
+	compiler()->dropObjectInfo (obj);
+	compiler()->unstage (obj);
+
+	if (m_objectAtCursor == obj)
+		m_objectAtCursor = nullptr;
 }
 
 // =============================================================================
@@ -1582,7 +1586,7 @@
 		ref->setFileInfo (GetDocument (primName));
 		ref->setPosition (Origin);
 		ref->setTransform (IdentityMatrix);
-		LDDocument::current()->insertObj (m_window->getInsertionPoint(), ref);
+		currentDocument()->insertObj (m_window->getInsertionPoint(), ref);
 		ref->select();
 		m_window->buildObjList();
 		m_window->R()->refresh();
--- a/src/guiutilities.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/guiutilities.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -56,7 +56,7 @@
 {
 	QMap<LDColor, int> counts;
 
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : currentDocument()->objects())
 	{
 		if (not obj->isColored() or not obj->color().isValid())
 			continue;
--- a/src/hierarchyelement.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/hierarchyelement.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -26,8 +26,17 @@
 	m_config = m_window->configBag();
 }
 
-
 GuiUtilities* HierarchyElement::guiUtilities() const
 {
 	return m_window->guiUtilities();
 }
+
+LDDocument* HierarchyElement::currentDocument()
+{
+	return m_window->currentDocument();
+}
+
+const LDObjectList& HierarchyElement::selectedObjects()
+{
+	return m_window->selectedObjects();
+}
--- a/src/hierarchyelement.h	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/hierarchyelement.h	Sat Sep 05 23:03:24 2015 +0300
@@ -1,9 +1,11 @@
 #pragma once
 #include <QObject>
+#include "main.h"
 
 class MainWindow;
 class ConfigurationValueBag;
 class GuiUtilities;
+class LDDocument;
 
 //
 // Objects that are to take part in the MainWindow's hierarchy multiple-inherit from this class to get a few useful
@@ -14,6 +16,8 @@
 public:
 	HierarchyElement (QObject* parent);
 
+	const LDObjectList& selectedObjects();
+	LDDocument* currentDocument();
 	GuiUtilities* guiUtilities() const;
 
 protected:
--- a/src/ldDocument.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/ldDocument.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -36,20 +36,19 @@
 ConfigOption (bool TryDownloadMissingFiles = false)
 
 static bool g_loadingMainFile = false;
-static const int g_maxRecentFiles = 10;
+enum { MAX_RECENT_FILES = 10 };
 static bool g_aborted = false;
 static LDDocument* g_logoedStud;
 static LDDocument* g_logoedStud2;
-static QList<LDDocument*> g_allDocuments;
-static QList<LDDocument*> g_explicitDocuments;
-static LDDocument* g_currentDocument;
 static bool g_loadingLogoedStuds = false;
 
 const QStringList g_specialSubdirectories ({ "s", "48", "8" });
 
 // =============================================================================
 //
-LDDocument::LDDocument() :
+LDDocument::LDDocument (QObject* parent) :
+	QObject (parent),
+	HierarchyElement (parent),
 	m_history (new History),
 	m_isImplicit (true),
 	m_flags (0),
@@ -61,21 +60,12 @@
 	setTabIndex (-1);
 	m_history->setDocument (this);
 	m_needsReCache = true;
-	g_allDocuments << this;
-}
-
-// =============================================================================
-//
-LDDocument* LDDocument::createNew()
-{
-	return new LDDocument();
 }
 
 // =============================================================================
 //
 LDDocument::~LDDocument()
 {
-	g_allDocuments.removeOne (this);
 	m_flags |= DOCF_IsBeingDestroyed;
 	delete m_history;
 	delete m_gldata;
@@ -91,53 +81,33 @@
 
 		if (a == false)
 		{
-			g_explicitDocuments << this;
 			print ("Opened %1", name());
 
 			// Implicit files are not compiled by the GL renderer. Now that this
 			// part is no longer implicit, it needs to be compiled.
-			if (g_win != null)
-				g_win->R()->compiler()->compileDocument (this);
+			m_window->R()->compiler()->compileDocument (this);
 		}
 		else
 		{
-			g_explicitDocuments.removeOne (this);
 			print ("Closed %1", name());
 		}
 
-		if (g_win != null)
-			g_win->updateDocumentList();
+		m_window->updateDocumentList();
 
-		// If the current document just became implicit (e.g. it was 'closed'),
-		// we need to get a new current document.
-		if (current() == this and isImplicit())
-		{
-			if (explicitDocuments().isEmpty())
-				newFile();
-			else
-				setCurrent (explicitDocuments().first());
-		}
+		// If the current document just became implicit (i.e. user closed it), we need to get a new one to show.
+		if (currentDocument() == this and a)
+			m_window->currentDocumentClosed();
 	}
 }
 
 // =============================================================================
 //
-QList<LDDocument*> const& LDDocument::explicitDocuments()
-{
-	return g_explicitDocuments;
-}
-
-// =============================================================================
-//
 LDDocument* FindDocument (QString name)
 {
-	for (LDDocument* file : g_allDocuments)
+	for (LDDocument* document : g_win->allDocuments())
 	{
-		if (file == null)
-			continue;
-
-		if (isOneOf (name, file->name(), file->defaultName()))
-			return file;
+		if (isOneOf (name, document->name(), document->defaultName()))
+			return document;
 	}
 
 	return nullptr;
@@ -178,22 +148,15 @@
 {
 	QString fullPath;
 
-	// LDraw models use Windows-style path separators. If we're not on Windows,
-	// replace the path separator now before opening any files. Qt expects
-	// forward-slashes as directory separators.
-#ifndef WIN32
+	// LDraw models use backslashes as path separators. Replace those into forward slashes for Qt.
 	relpath.replace ("\\", "/");
-#endif // WIN32
 
-	// Try find it relative to other currently open documents. We want a file
-	// in the immediate vicinity of a current model to override stock LDraw stuff.
+	// 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 (relpath));
 
-	for (LDDocument* doc : g_allDocuments)
+	for (LDDocument* doc : g_win->allDocuments())
 	{
-		if (doc == null)
-			continue;
-
 		QString partpath = format ("%1/%2", Dirname (doc->fullPath()), relpath);
 		QFile f (partpath);
 
@@ -229,8 +192,8 @@
 
 	if (subdirs)
 	{
-		// Look in sub-directories: parts and p. Also look in net_downloadpath, since that's
-		// where we download parts from the PT to.
+		// Look in sub-directories: parts and p. Also look in the download path, since that's where we download parts
+		// from the PT to.
 		QStringList dirs = { g_win->configBag()->lDrawPath(), g_win->configBag()->downloadFilePath() };
 		for (const QString& topdir : dirs)
 		{
@@ -453,8 +416,7 @@
 	if (not fp)
 		return nullptr;
 
-	LDDocument* load = (fileToOverride != null ? fileToOverride : LDDocument::createNew());
-	load->setImplicit (implicit);
+	LDDocument* load = (fileToOverride != null ? fileToOverride : g_win->newDocument (implicit));
 	load->setFullPath (fullpath);
 	load->setName (LDDocument::shortenName (load->fullPath()));
 
@@ -477,7 +439,7 @@
 
 	if (g_loadingMainFile)
 	{
-		LDDocument::setCurrent (load);
+		g_win->changeDocument (load);
 		g_win->R()->setDocument (load);
 		print (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings);
 	}
@@ -496,10 +458,9 @@
 	// If we have unsaved changes, warn and give the option of saving.
 	if (hasUnsavedChanges())
 	{
-		QString message = format (QObject::tr ("There are unsaved changes to %1. Should it be saved?"), 
-getDisplayName());
+		QString message = format (tr ("There are unsaved changes to %1. Should it be saved?"), getDisplayName());
 
-		int button = msgbox::question (g_win, QObject::tr ("Unsaved Changes"), message,
+		int button = msgbox::question (m_window, QObject::tr ("Unsaved Changes"), message,
 			(msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel);
 
 		switch (button)
@@ -509,8 +470,8 @@
 				// If we don't have a file path yet, we have to ask the user for one.
 				if (name().length() == 0)
 				{
-					QString newpath = QFileDialog::getSaveFileName (g_win, QObject::tr ("Save As"),
-						CurrentDocument()->name(), QObject::tr ("LDraw files (*.dat *.ldr)"));
+					QString newpath = QFileDialog::getSaveFileName (m_window, QObject::tr ("Save As"),
+						name(), QObject::tr ("LDraw files (*.dat *.ldr)"));
 
 					if (newpath.length() == 0)
 						return false;
@@ -523,7 +484,7 @@
 					message = format (QObject::tr ("Failed to save %1 (%2)\nDo you still want to close?"),
 						name(), strerror (errno));
 
-					if (msgbox::critical (g_win, QObject::tr ("Save Failure"), message,
+					if (msgbox::critical (m_window, QObject::tr ("Save Failure"), message,
 						(msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No)
 					{
 						return false;
@@ -547,28 +508,12 @@
 //
 void CloseAllDocuments()
 {
-	for (LDDocument* file : g_explicitDocuments)
+	for (LDDocument* file : g_win->allDocuments())
 		file->dismiss();
 }
 
 // =============================================================================
 //
-void newFile()
-{
-	// Create a new anonymous file and set it to our current
-	LDDocument* f = LDDocument::createNew();
-	f->setName ("");
-	f->setImplicit (false);
-	LDDocument::setCurrent (f);
-	LDDocument::closeInitialFile();
-	g_win->R()->setDocument (f);
-	g_win->doFullRefresh();
-	g_win->updateTitle();
-	g_win->updateActions();
-}
-
-// =============================================================================
-//
 void AddRecentFile (QString path)
 {
 	QStringList recentFiles = g_win->configBag()->recentFiles();
@@ -584,7 +529,7 @@
 	}
 
 	// If there's too many recent files, drop one out.
-	while (recentFiles.size() > (g_maxRecentFiles - 1))
+	while (recentFiles.size() > (MAX_RECENT_FILES - 1))
 		recentFiles.removeAt (0);
 
 	// Add the file
@@ -604,9 +549,9 @@
 	LDDocument* file = nullptr;
 	QString shortName = LDDocument::shortenName (path);
 
-	for (LDDocument* doc : g_allDocuments)
+	for (LDDocument* doc : g_win->allDocuments())
 	{
-		if (doc != null and doc->name() == shortName)
+		if (doc->name() == shortName)
 		{
 			documentToReplace = doc;
 			break;
@@ -644,16 +589,9 @@
 	}
 
 	file->setImplicit (false);
-
-	// If we have an anonymous, unchanged file open as the only open file
-	// (aside of the one we just opened), close it now.
-	LDDocument::closeInitialFile();
-
-	// Rebuild the object tree view now.
-	LDDocument::setCurrent (file);
+	g_win->closeInitialDocument();
+	g_win->changeDocument (file);
 	g_win->doFullRefresh();
-
-	// Add it to the recent files list.
 	AddRecentFile (path);
 	g_loadingMainFile = false;
 
@@ -709,7 +647,7 @@
 		{
 			QString newname = shortenName (path);
 			nameComment->setText (format ("Name: %1", newname));
-			g_win->buildObjList();
+			m_window->buildObjList();
 		}
 	}
 
@@ -740,9 +678,8 @@
 	setSavePosition (history()->position());
 	setFullPath (path);
 	setName (shortenName (path));
-
-	g_win->updateDocumentListItem (this);
-	g_win->updateTitle();
+	m_window->updateDocumentListItem (this);
+	m_window->updateTitle();
 	return true;
 }
 
@@ -1041,8 +978,8 @@
 
 	m_needsReCache = true;
 
-	if (this == CurrentDocument())
-		g_win->buildObjList();
+	if (this == m_window->currentDocument())
+		m_window->buildObjList();
 }
 
 // =============================================================================
@@ -1053,7 +990,7 @@
 	m_objects << obj;
 	addKnownVertices (obj);
 	obj->setDocument (this);
-	g_win->R()->compileObject (obj);
+	m_window->R()->compileObject (obj);
 	return getObjectCount() - 1;
 }
 
@@ -1075,7 +1012,7 @@
 	history()->add (new AddHistory (pos, obj));
 	m_objects.insert (pos, obj);
 	obj->setDocument (this);
-	g_win->R()->compileObject (obj);
+	m_window->R()->compileObject (obj);
 	
 
 #ifdef DEBUG
@@ -1124,7 +1061,7 @@
 //
 bool IsSafeToCloseAll()
 {
-	for (LDDocument* f : LDDocument::explicitDocuments())
+	for (LDDocument* f : g_win->allDocuments())
 	{
 		if (not f->isSafeToClose())
 			return false;
@@ -1153,7 +1090,7 @@
 	m_objects[idx]->setDocument (nullptr);
 	obj->setDocument (this);
 	addKnownVertices (obj);
-	g_win->R()->compileObject (obj);
+	m_window->R()->compileObject (obj);
 	m_objects[idx] = obj;
 	needVertexMerge();
 }
@@ -1268,7 +1205,7 @@
 	// Possibly substitute with logoed studs:
 	// stud.dat -> stud-logo.dat
 	// stud2.dat -> stud-logo2.dat
-	if (g_win->configBag()->useLogoStuds() and renderinline)
+	if (m_config->useLogoStuds() and renderinline)
 	{
 		// Ensure logoed studs are loaded first
 		LoadLogoStuds();
@@ -1303,63 +1240,6 @@
 
 // =============================================================================
 //
-LDDocument* LDDocument::current()
-{
-	return g_currentDocument;
-}
-
-// =============================================================================
-// Sets the given file as the current one on display. At some point in time this
-// was an operation completely unheard of. ;)
-//
-// TODO: f can be temporarily null. This probably should not be the case.
-// =============================================================================
-void LDDocument::setCurrent (LDDocument* f)
-{
-	// Implicit files were loaded for caching purposes and must never be set
-	// current.
-	if (f != null and f->isImplicit())
-		return;
-
-	g_currentDocument = f;
-
-	if (g_win and f)
-	{
-		// A ton of stuff needs to be updated
-		g_win->updateDocumentListItem (f);
-		g_win->buildObjList();
-		g_win->updateTitle();
-		g_win->R()->setDocument (f);
-		g_win->R()->compiler()->needMerge();
-		print ("Changed file to %1", f->getDisplayName());
-	}
-}
-
-// =============================================================================
-//
-int LDDocument::countExplicitFiles()
-{
-	return g_explicitDocuments.size();
-}
-
-// =============================================================================
-// This little beauty closes the initial file that was open at first when opening
-// a new file over it.
-// =============================================================================
-void LDDocument::closeInitialFile()
-{
-	if (g_explicitDocuments.size() == 2 and
-		g_explicitDocuments[0]->name().isEmpty() and
-		not g_explicitDocuments[1]->name().isEmpty() and
-		not g_explicitDocuments[0]->hasUnsavedChanges())
-	{
-		LDDocument* filetoclose = g_explicitDocuments.first();
-		filetoclose->dismiss();
-	}
-}
-
-// =============================================================================
-//
 void LoadLogoStuds()
 {
 	if (g_loadingLogoedStuds or (g_logoedStud and g_logoedStud2))
@@ -1379,7 +1259,7 @@
 	if (not obj->isSelected() and obj->document() == this)
 	{
 		m_sel << obj;
-		g_win->R()->compileObject (obj);
+		m_window->R()->compileObject (obj);
 		obj->setSelected (true);
 	}
 }
@@ -1391,7 +1271,7 @@
 	if (obj->isSelected() and obj->document() == this)
 	{
 		m_sel.removeOne (obj);
-		g_win->R()->compileObject (obj);
+		m_window->R()->compileObject (obj);
 		obj->setSelected (false);
 	}
 }
@@ -1402,7 +1282,7 @@
 {
 	for (LDObject* obj : m_sel)
 	{
-		g_win->R()->compileObject (obj);
+		m_window->R()->compileObject (obj);
 		obj->setSelected (false);
 	}
 
@@ -1460,4 +1340,4 @@
 void LDDocument::needVertexMerge()
 {
 	m_needVertexMerge = true;
-}
+}
\ No newline at end of file
--- a/src/ldDocument.h	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/ldDocument.h	Sat Sep 05 23:03:24 2015 +0300
@@ -49,9 +49,9 @@
 // The default name is a placeholder, initially suggested name for a file. The
 // primitive generator uses this to give initial names to primitives.
 //
-class LDDocument
+class LDDocument : public QObject, public HierarchyElement
 {
-public:
+	Q_OBJECT
 	PROPERTY (public,	QString,				name,			setName,			STOCK_WRITE)
 	PROPERTY (private,	LDObjectList,		objects, 		setObjects,			STOCK_WRITE)
 	PROPERTY (private,	LDObjectList,		cache, 			setCache,			STOCK_WRITE)
@@ -64,13 +64,8 @@
 	PROPERTY (public,	QList<LDPolygon>,	polygonData,	setPolygonData,		STOCK_WRITE)
 	PROPERTY (private,	LDDocumentFlags,	flags,			setFlags,			STOCK_WRITE)
 
-	QMap<LDObject*, QVector<Vertex>> m_objectVertices;
-	QVector<Vertex> m_vertices;
-	bool m_verticesOutdated;
-	bool m_needVertexMerge;
-
 public:
-	LDDocument();
+	LDDocument (QObject* parent);
 	~LDDocument();
 
 	int addObject (LDObject* obj); // Adds an object to this file at the end of the file.
@@ -134,15 +129,8 @@
 		setImplicit (true);
 	}
 
-	static LDDocument* current();
-	static void setCurrent (LDDocument* f);
-	static void closeInitialFile();
-	static int countExplicitFiles();
-	static LDDocument* createNew();
-
 	// Turns a full path into a relative path
 	static QString shortenName (QString a);
-	static QList<LDDocument*> const& explicitDocuments();
 	void mergeVertices();
 
 protected:
@@ -158,6 +146,11 @@
 	friend class GLRenderer;
 
 private:
+	
+	QMap<LDObject*, QVector<Vertex>> m_objectVertices;
+	QVector<Vertex> m_vertices;
+	bool m_verticesOutdated;
+	bool m_needVertexMerge;
 	LDObjectList			m_sel;
 	LDGLData*				m_gldata;
 
@@ -166,14 +159,6 @@
 	bool					m_needsReCache;
 };
 
-inline LDDocument* CurrentDocument()
-{
-	return LDDocument::current();
-}
-
-// Close all current loaded files and start off blank.
-void newFile();
-
 // Opens the given file as the main file. Everything is closed first.
 void OpenMainModel (QString path);
 
@@ -202,11 +187,7 @@
 
 LDObjectList LoadFileContents (QFile* f, int* numWarnings, bool* ok = null);
 
-inline const LDObjectList& Selection()
-{
-	return CurrentDocument()->getSelection();
-}
-
+const LDObjectList& selectedObjects();
 void AddRecentFile (QString path);
 void LoadLogoStuds();
 QString Basename (QString path);
--- a/src/ldObject.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/ldObject.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -293,6 +293,8 @@
 //
 void LDObject::destroy()
 {
+	print ("Destroying %1\n", this);
+
 	// Don't bother during program termination (FIXME)
 	if (IsExiting() == false)
 	{
@@ -787,7 +789,7 @@
 		{
 			obj->document()->addToHistory (new EditHistory (idx, before, after));
 			g_win->R()->compileObject (obj);
-			CurrentDocument()->redoVertices();
+			g_win->currentDocument()->redoVertices();
 		}
 	}
 	else
--- a/src/mainwindow.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/mainwindow.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -53,6 +53,7 @@
 #include "toolsets/toolset.h"
 #include "dialogs/configdialog.h"
 #include "guiutilities.h"
+#include "glCompiler.h"
 
 static bool g_isSelectionLocked = false;
 static QMap<QAction*, QKeySequence> g_defaultShortcuts;
@@ -70,7 +71,8 @@
 	m_guiUtilities (new GuiUtilities (this)),
 	ui (*new Ui_MainWindow),
 	m_externalPrograms (nullptr),
-	m_settings (makeSettings (this))
+	m_settings (makeSettings (this)),
+	m_currentDocument (nullptr)
 {
 	g_win = this;
 	ui.setupUi (this);
@@ -86,7 +88,7 @@
 
 	connect (ui.objectList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_selectionChanged()));
 	connect (ui.objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this, SLOT (slot_editObject (QListWidgetItem*)));
-	connect (m_tabs, SIGNAL (currentChanged(int)), this, SLOT (changeCurrentFile()));
+	connect (m_tabs, SIGNAL (currentChanged(int)), this, SLOT (tabSelected()));
 	connect (m_tabs, SIGNAL (tabCloseRequested (int)), this, SLOT (closeTab (int)));
 
 	if (ActivePrimitiveScanner() != null)
@@ -98,7 +100,6 @@
 	m_msglog->setRenderer (R());
 	m_renderer->setMessageLog (m_msglog);
 	m_quickColors = LoadQuickColorList();
-	slot_selectionChanged();
 	setStatusBar (new QStatusBar);
 	updateActions();
 
@@ -167,7 +168,8 @@
 			toolbar->hide();
 	}
 
-	newFile();
+	createBlankDocument();
+	m_renderer->setDocument (m_currentDocument);
 
 	// If this is the first start, get the user to configuration. Especially point
 	// them to the profile tab, it's the most important form to fill in.
@@ -210,12 +212,8 @@
 //
 void MainWindow::endAction()
 {
-	// Add a step in the history now.
-	CurrentDocument()->addHistoryStep();
-
-	// Update the list item of the current file - we may need to draw an icon
-	// now that marks it as having unsaved changes.
-	updateDocumentListItem (CurrentDocument());
+	m_currentDocument->addHistoryStep();
+	updateDocumentListItem (m_currentDocument);
 	refresh();
 }
 
@@ -324,20 +322,20 @@
 	QString title = format (APPNAME " " VERSION_STRING);
 
 	// Append our current file if we have one
-	if (CurrentDocument())
+	if (m_currentDocument)
 	{
 		title += ": ";
-		title += CurrentDocument()->getDisplayName();
+		title += m_currentDocument->getDisplayName();
 
-		if (CurrentDocument()->getObjectCount() > 0 and
-			CurrentDocument()->getObject (0)->type() == OBJ_Comment)
+		if (m_currentDocument->getObjectCount() > 0 and
+			m_currentDocument->getObject (0)->type() == OBJ_Comment)
 		{
 			// Append title
-			LDComment* comm = static_cast <LDComment*> (CurrentDocument()->getObject (0));
+			LDComment* comm = static_cast <LDComment*> (m_currentDocument->getObject (0));
 			title += format (": %1", comm->text());
 		}
 
-		if (CurrentDocument()->hasUnsavedChanges())
+		if (m_currentDocument->hasUnsavedChanges())
 			title += '*';
 	}
 
@@ -357,10 +355,10 @@
 //
 int MainWindow::deleteSelection()
 {
-	if (Selection().isEmpty())
+	if (selectedObjects().isEmpty())
 		return 0;
 
-	LDObjectList selCopy = Selection();
+	LDObjectList selCopy = selectedObjects();
 
 	// Delete the objects that were being selected
 	for (LDObject* obj : selCopy)
@@ -374,7 +372,7 @@
 //
 void MainWindow::buildObjList()
 {
-	if (not CurrentDocument())
+	if (not m_currentDocument)
 		return;
 
 	// Lock the selection while we do this so that refreshing the object list
@@ -387,7 +385,7 @@
 
 	ui.objectList->clear();
 
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : m_currentDocument->objects())
 	{
 		QString descr;
 
@@ -503,10 +501,10 @@
 //
 void MainWindow::scrollToSelection()
 {
-	if (Selection().isEmpty())
+	if (selectedObjects().isEmpty())
 		return;
 
-	LDObject* obj = Selection().last();
+	LDObject* obj = selectedObjects().last();
 	ui.objectList->scrollToItem (obj->qObjListEntry);
 }
 
@@ -514,16 +512,16 @@
 //
 void MainWindow::slot_selectionChanged()
 {
-	if (g_isSelectionLocked == true or CurrentDocument() == null)
+	if (g_isSelectionLocked == true or m_currentDocument == null)
 		return;
 
-	LDObjectList priorSelection = Selection();
+	LDObjectList priorSelection = selectedObjects();
 
 	// Get the objects from the object list selection
-	CurrentDocument()->clearSelection();
+	m_currentDocument->clearSelection();
 	const QList<QListWidgetItem*> items = ui.objectList->selectedItems();
 
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : m_currentDocument->objects())
 	{
 		for (QListWidgetItem* item : items)
 		{
@@ -540,7 +538,7 @@
 	updateSelection();
 
 	// Update the GL renderer
-	LDObjectList compound = priorSelection + Selection();
+	LDObjectList compound = priorSelection + selectedObjects();
 	removeDuplicates (compound);
 
 	for (LDObject* obj : compound)
@@ -576,7 +574,7 @@
 	if (not color.isValid())
 		return;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		if (not obj->isColored())
 			continue; // uncolored object
@@ -594,11 +592,11 @@
 int MainWindow::getInsertionPoint()
 {
 	// If we have a selection, put the item after it.
-	if (not Selection().isEmpty())
-		return Selection().last()->lineNumber() + 1;
+	if (not selectedObjects().isEmpty())
+		return selectedObjects().last()->lineNumber() + 1;
 
 	// Otherwise place the object at the end.
-	return CurrentDocument()->getObjectCount();
+	return m_currentDocument->getObjectCount();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -626,7 +624,7 @@
 	int top = -1;
 	int bottom = -1;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		if (obj->qObjListEntry == null)
 			continue;
@@ -666,7 +664,7 @@
 {
 	LDColor result;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		if (not obj->isColored())
 			continue; // This one doesn't use color so it doesn't have a say
@@ -711,12 +709,12 @@
 //
 void MainWindow::spawnContextMenu (const QPoint pos)
 {
-	const bool single = (Selection().size() == 1);
-	LDObject* singleObj = single ? Selection().first() : nullptr;
+	const bool single = (selectedObjects().size() == 1);
+	LDObject* singleObj = single ? selectedObjects().first() : nullptr;
 
 	bool hasSubfiles = false;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		if (obj->type() == OBJ_Subfile)
 		{
@@ -758,7 +756,7 @@
 	contextMenu->addAction (ui.actionModeDraw);
 	contextMenu->addAction (ui.actionModeCircle);
 
-	if (not Selection().isEmpty())
+	if (not selectedObjects().isEmpty())
 	{
 		contextMenu->addSeparator();
 		contextMenu->addAction (ui.actionSubfileSelection);
@@ -779,7 +777,7 @@
 {
 	LDObjectList objs;
 
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : m_currentDocument->objects())
 	{
 		if (not obj->isColored() or obj->color() != color)
 			continue;
@@ -808,7 +806,7 @@
 //
 void MainWindow::slot_editObject (QListWidgetItem* listitem)
 {
-	for (LDObject* it : CurrentDocument()->objects())
+	for (LDObject* it : m_currentDocument->objects())
 	{
 		if (it->qObjListEntry == listitem)
 		{
@@ -822,6 +820,9 @@
 //
 bool MainWindow::save (LDDocument* doc, bool saveAs)
 {
+	if (doc->isImplicit())
+		return false;
+
 	QString path = doc->fullPath();
 	int64 savesize;
 
@@ -847,7 +848,7 @@
 
 	if (doc->save (path, &savesize))
 	{
-		if (doc == CurrentDocument())
+		if (doc == m_currentDocument)
 			updateTitle();
 
 		print ("Saved to %1 (%2)", path, MakePrettyFileSize (savesize));
@@ -925,12 +926,15 @@
 	while (m_tabs->count() > 0)
 		m_tabs->removeTab (0);
 
-	for (LDDocument* f : LDDocument::explicitDocuments())
+	for (LDDocument* document : m_documents)
 	{
-		// Add an item to the list for this file and store the tab index
-		// in the document so we can find documents by tab index.
-		f->setTabIndex (m_tabs->addTab (""));
-		updateDocumentListItem (f);
+		if (not document->isImplicit())
+		{
+			// Add an item to the list for this file and store the tab index
+			// in the document so we can find documents by tab index.
+			document->setTabIndex (m_tabs->addTab (""));
+			updateDocumentListItem (document);
+		}
 	}
 
 	m_updatingTabs = false;
@@ -953,7 +957,7 @@
 
 	// If this is the current file, it also needs to be the selected item on
 	// the list.
-	if (doc == CurrentDocument())
+	if (doc == m_currentDocument)
 		m_tabs->setCurrentIndex (doc->tabIndex());
 
 	m_tabs->setTabText (doc->tabIndex(), doc->getDisplayName());
@@ -969,30 +973,26 @@
 // A file is selected from the list of files on the left of the screen. Find out
 // which file was picked and change to it.
 //
-void MainWindow::changeCurrentFile()
+void MainWindow::tabSelected()
 {
 	if (m_updatingTabs)
 		return;
 
-	LDDocument* file = nullptr;
+	LDDocument* switchee = nullptr;
 	int tabIndex = m_tabs->currentIndex();
 
 	// Find the file pointer of the item that was selected.
-	for (LDDocument* it : LDDocument::explicitDocuments())
+	for (LDDocument* document : m_documents)
 	{
-		if (it->tabIndex() == tabIndex)
+		if (not document->isImplicit() and document->tabIndex() == tabIndex)
 		{
-			file = it;
+			switchee = document;
 			break;
 		}
 	}
 
-	// If we picked the same file we're currently on, we don't need to do
-	// anything.
-	if (file == null or file == CurrentDocument())
-		return;
-
-	LDDocument::setCurrent (file);
+	if (switchee and switchee != m_currentDocument)
+		changeDocument (switchee);
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -1001,7 +1001,7 @@
 {
 #if 0
 	ui.objectList->clear();
-	LDDocument* f = getCurrentDocument();
+	LDDocument* f = getm_currentDocument;
 
 for (LDObject* obj : *f)
 		ui.objectList->addItem (obj->qObjListEntry);
@@ -1015,9 +1015,9 @@
 //
 void MainWindow::updateActions()
 {
-	if (CurrentDocument() != null and CurrentDocument()->history() != null)
+	if (m_currentDocument != null and m_currentDocument->history() != null)
 	{
-		History* his = CurrentDocument()->history();
+		History* his = m_currentDocument->history();
 		int pos = his->position();
 		ui.actionUndo->setEnabled (pos != -1);
 		ui.actionRedo->setEnabled (pos < (long) his->getSize() - 1);
@@ -1153,11 +1153,15 @@
 	return new QSettings (path, QSettings::IniFormat, parent);
 }
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
 void MainWindow::syncSettings()
 {
 	m_settings->sync();
 }
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
 QVariant MainWindow::getConfigValue (QString name)
 {
 	QVariant value = m_settings->value (name, m_configOptions.defaultValueByName (name));
@@ -1166,6 +1170,111 @@
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
+void MainWindow::createBlankDocument()
+{
+	// Create a new anonymous file and set it to our current
+	LDDocument* f = newDocument();
+	f->setName ("");
+	changeDocument (f);
+	closeInitialDocument();
+	doFullRefresh();
+	updateActions();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+LDDocument* MainWindow::newDocument (bool cache)
+{
+	m_documents.append (new LDDocument (this));
+	m_documents.last()->setImplicit (cache);
+	return m_documents.last();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+const QList<LDDocument*>& MainWindow::allDocuments()
+{
+	return m_documents;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+LDDocument* MainWindow::currentDocument()
+{
+	return m_currentDocument;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+// TODO: document may be null, this shouldn't be the case
+//
+void MainWindow::changeDocument (LDDocument* document)
+{
+	// Implicit files were loaded for caching purposes and may never be switched to.
+	if (document != null and document->isImplicit())
+		return;
+
+	m_currentDocument = document;
+
+	if (document)
+	{
+		// A ton of stuff needs to be updated
+		updateDocumentListItem (document);
+		buildObjList();
+		updateTitle();
+		m_renderer->setDocument (document);
+		m_renderer->compiler()->needMerge();
+		print ("Changed document to %1", document->getDisplayName());
+	}
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+// This little beauty closes the initial file that was open at first when opening a new file over it.
+//
+void MainWindow::closeInitialDocument()
+{
+	if (m_documents.size() == 2 and
+		m_documents[0]->name().isEmpty() and
+		not m_documents[1]->name().isEmpty() and
+		not m_documents[0]->hasUnsavedChanges())
+	{
+		m_documents.first()->dismiss();
+	}
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+const LDObjectList& MainWindow::selectedObjects()
+{
+	return m_currentDocument->getSelection();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void MainWindow::currentDocumentClosed()
+{
+	LDDocument* old = currentDocument();
+
+	// Find a replacement document to use
+	for (LDDocument* doc : m_documents)
+	{
+		if (doc != old and not doc->isImplicit())
+		{
+			changeDocument (doc);
+			break;
+		}
+	}
+
+	if (currentDocument() == old)
+	{
+		// Failed to change to a suitable document, open a new one.
+		createBlankDocument();
+	}
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
 QImage GetImageFromScreencap (uchar* data, int w, int h)
 {
 	// GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well.
--- a/src/mainwindow.h	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/mainwindow.h	Sat Sep 05 23:03:24 2015 +0300
@@ -167,6 +167,14 @@
 	void syncSettings();
 	QVariant getConfigValue (QString name);
 	class QSettings* getSettings() { return m_settings; }
+	void createBlankDocument();
+	LDDocument* newDocument (bool cache = false);
+	const QList<LDDocument*>& allDocuments();
+	LDDocument* currentDocument();
+	void changeDocument (LDDocument* f);
+	void closeInitialDocument();
+	const LDObjectList& selectedObjects();
+	void currentDocumentClosed();
 
 	class ExtProgramToolset* externalPrograms()
 	{
@@ -180,7 +188,7 @@
 
 public slots:
 	void updatePrimitives();
-	void changeCurrentFile();
+	void tabSelected();
 	void closeTab (int tabindex);
 	void ringToolHiResClicked (bool clicked);
 	void circleToolSegmentsChanged();
@@ -207,6 +215,8 @@
 	QMap<QAction*, ToolInfo> m_toolmap;
 	class ExtProgramToolset* m_externalPrograms;
 	class QSettings* m_settings;
+	QList<LDDocument*> m_documents;
+	LDDocument* m_currentDocument;
 
 private slots:
 	void slot_selectionChanged();
--- a/src/partDownloader.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/partDownloader.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -269,7 +269,7 @@
 //
 void PartDownloader::downloadFile (QString dest, QString url, bool primary)
 {
-	const int row = form()->progress->rowCount();
+	int row = form()->progress->rowCount();
 
 	// Don't download files repeadetly.
 	if (filesToDownload().indexOf (dest) != -1)
@@ -312,7 +312,7 @@
 		if (not req->isFinished())
 			return;
 
-        if (req->state() == PartDownloadRequest::State::Failed)
+		if (req->state() == PartDownloadRequest::State::Failed)
 			failed = true;
 	}
 
@@ -324,12 +324,12 @@
 	// Update everything now
 	if (primaryFile() != null)
 	{
-		LDDocument::setCurrent (primaryFile());
+		g_win->changeDocument (primaryFile());
 		g_win->doFullRefresh();
 		g_win->R()->resetAngles();
 	}
 
-		for (LDDocument* f : m_files)
+	for (LDDocument* f : m_files)
 		f->reloadAllSubfiles();
 
 	if (m_config->autoCloseDownloadDialog() and not failed)
--- a/src/primitives.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/primitives.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -613,8 +613,8 @@
 	if (divs == HighResolution)
 		descr.insert (0, "Hi-Res ");
 
-	LDDocument* f = LDDocument::createNew();
-	f->setDefaultName (name);
+	LDDocument* document = g_win->newDocument();
+	document->setDefaultName (name);
 
 	QString author = APPNAME;
 	QString license = "";
@@ -637,12 +637,12 @@
 		 << LDSpawn<LDBFC> (BFCStatement::CertifyCCW)
 		 << LDSpawn<LDEmpty>();
 
-	f->setImplicit (false);
-	f->history()->setIgnoring (false);
-	f->addObjects (objs);
-	f->addObjects (MakePrimitive (type, segs, divs, num));
-	f->addHistoryStep();
-	return f;
+	document->setImplicit (false);
+	document->history()->setIgnoring (false);
+	document->addObjects (objs);
+	document->addObjects (MakePrimitive (type, segs, divs, num));
+	document->addHistoryStep();
+	return document;
 }
 
 // =============================================================================
--- a/src/toolsets/algorithmtoolset.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/toolsets/algorithmtoolset.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -51,7 +51,7 @@
 {
 	int num = 0;
 
-	for (LDObjectIterator<LDQuad> it (Selection()); it.isValid(); ++it)
+	for (LDObjectIterator<LDQuad> it (selectedObjects()); it.isValid(); ++it)
 	{
 		// Find the index of this quad
 		int index = it->lineNumber();
@@ -63,8 +63,8 @@
 
 		// Replace the quad with the first triangle and add the second triangle
 		// after the first one.
-		CurrentDocument()->setObject (index, triangles[0]);
-		CurrentDocument()->insertObj (index + 1, triangles[1]);
+		currentDocument()->setObject (index, triangles[0]);
+		currentDocument()->insertObj (index + 1, triangles[1]);
 		num++;
 	}
 
@@ -73,10 +73,10 @@
 
 void AlgorithmToolset::editRaw()
 {
-	if (Selection().size() != 1)
+	if (selectedObjects().size() != 1)
 		return;
 
-	LDObject* obj = Selection()[0];
+	LDObject* obj = selectedObjects()[0];
 	QDialog* dlg = new QDialog;
 	Ui::EditRawUI ui;
 
@@ -101,7 +101,7 @@
 
 void AlgorithmToolset::makeBorders()
 {
-	LDObjectList objs = Selection();
+	LDObjectList objs = selectedObjects();
 	int num = 0;
 
 	for (LDObject* obj : objs)
@@ -136,7 +136,7 @@
 				continue;
 
 			long idx = obj->lineNumber() + i + 1;
-			CurrentDocument()->insertObj (idx, lines[i]);
+			currentDocument()->insertObj (idx, lines[i]);
 			++num;
 		}
 	}
@@ -149,7 +149,7 @@
 	setlocale (LC_ALL, "C");
 	int num = 0;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj);
 
@@ -212,7 +212,7 @@
 	if (ui.y->isChecked()) sel << Y;
 	if (ui.z->isChecked()) sel << Z;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		for (int i = 0; i < obj->numVertices(); ++i)
 		{
@@ -255,7 +255,7 @@
 	if (ui.y->isChecked()) sel << Y;
 	if (ui.z->isChecked()) sel << Z;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		for (int i = 0; i < obj->numVertices(); ++i)
 		{
@@ -276,7 +276,7 @@
 {
 	int num = 0;
 
-	for (LDObjectIterator<LDCondLine> it (Selection()); it.isValid(); ++it)
+	for (LDObjectIterator<LDCondLine> it (selectedObjects()); it.isValid(); ++it)
 	{
 		it->toEdgeLine();
 		++num;
@@ -285,9 +285,9 @@
 	print (tr ("Converted %1 conditional lines"), num);
 }
 
-bool AlgorithmToolset::isColorUsed (LDColor color) const
+bool AlgorithmToolset::isColorUsed (LDColor color)
 {
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : currentDocument()->objects())
 	{
 		if (obj->isColored() and obj->color() == color)
 			return true;
@@ -312,7 +312,7 @@
 		return;
 	}
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		if (not obj->isColored())
 			continue;
@@ -346,7 +346,7 @@
 		ui->m_comment->text()));
 
 	// Find a spot to place the new comment
-	for (obj = CurrentDocument()->getObject (0);
+	for (obj = currentDocument()->getObject (0);
 		obj and obj->next() and not obj->next()->isScemantic();
 		obj = obj->next())
 	{
@@ -362,12 +362,12 @@
 	}
 
 	int idx = obj ? obj->lineNumber() : 0;
-	CurrentDocument()->insertObj (idx++, comment);
+	currentDocument()->insertObj (idx++, comment);
 
 	// If we're adding a history line right before a scemantic object, pad it
 	// an empty line
 	if (obj and obj->next() and obj->next()->isScemantic())
-		CurrentDocument()->insertObj (idx, new LDEmpty);
+		currentDocument()->insertObj (idx, new LDEmpty);
 
 	m_window->buildObjList();
 	delete ui;
@@ -384,7 +384,7 @@
 
 	m_config->setSplitLinesSegments (segments);
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		if (not isOneOf (obj->type(), OBJ_Line, OBJ_CondLine))
 			continue;
@@ -419,7 +419,7 @@
 		int ln = obj->lineNumber();
 
 		for (LDObject* seg : newsegs)
-			CurrentDocument()->insertObj (ln++, seg);
+			currentDocument()->insertObj (ln++, seg);
 
 		obj->destroy();
 	}
@@ -430,10 +430,10 @@
 
 void AlgorithmToolset::subfileSelection()
 {
-	if (Selection().size() == 0)
+	if (selectedObjects().size() == 0)
 		return;
 
-	QString			parentpath (CurrentDocument()->fullPath());
+	QString			parentpath (currentDocument()->fullPath());
 
 	// BFC type of the new subfile - it shall inherit the BFC type of the parent document
 	BFCStatement	bfctype (BFCStatement::NoCertify);
@@ -445,7 +445,7 @@
 	QString			subtitle;
 
 	// Comment containing the title of the parent document
-	LDComment*	titleobj = dynamic_cast<LDComment*> (CurrentDocument()->getObject (0));
+	LDComment*	titleobj = dynamic_cast<LDComment*> (currentDocument()->getObject (0));
 
 	// License text for the subfile
 	QString			license (PreferredLicenseText());
@@ -457,7 +457,7 @@
 	QString			fullsubname;
 
 	// Where to insert the subfile reference?
-	int				refidx (Selection()[0]->lineNumber());
+	int				refidx (selectedObjects()[0]->lineNumber());
 
 	// Determine title of subfile
 	if (titleobj != null)
@@ -471,7 +471,7 @@
 
 	// If this the parent document isn't already in s/, we need to stuff it into
 	// a subdirectory named s/. Ensure it exists!
-	QString topdirname = Basename (Dirname (CurrentDocument()->fullPath()));
+	QString topdirname = Basename (Dirname (currentDocument()->fullPath()));
 
 	if (topdirname != "s")
 	{
@@ -521,7 +521,7 @@
 
 	// Determine the BFC winding type used in the main document - it is to
 	// be carried over to the subfile.
-	for (LDObjectIterator<LDBFC> it (CurrentDocument()); it.isValid(); ++it)
+	for (LDObjectIterator<LDBFC> it (currentDocument()); it.isValid(); ++it)
 	{
 		if (isOneOf (it->statement(), BFCStatement::CertifyCCW, BFCStatement::CertifyCW, BFCStatement::NoCertify))
 		{
@@ -531,11 +531,11 @@
 	}
 
 	// Get the body of the document in LDraw code
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 		code << obj->asText();
 
 	// Create the new subfile document
-	LDDocument* doc = LDDocument::createNew();
+	LDDocument* doc = m_window->newDocument();
 	doc->setImplicit (false);
 	doc->setFullPath (fullsubname);
 	doc->setName (LDDocument::shortenName (fullsubname));
@@ -567,7 +567,7 @@
 	{
 		// Save was successful. Delete the original selection now from the
 		// main document.
-		for (LDObject* obj : Selection())
+		for (LDObject* obj : selectedObjects())
 			obj->destroy();
 
 		// Add a reference to the new subfile to where the selection was
@@ -576,7 +576,7 @@
 		ref->setFileInfo (doc);
 		ref->setPosition (Origin);
 		ref->setTransform (IdentityMatrix);
-		CurrentDocument()->insertObj (refidx, ref);
+		currentDocument()->insertObj (refidx, ref);
 
 		// Refresh stuff
 		m_window->updateDocumentList();
--- a/src/toolsets/algorithmtoolset.h	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/toolsets/algorithmtoolset.h	Sat Sep 05 23:03:24 2015 +0300
@@ -38,5 +38,5 @@
 	Q_INVOKABLE void subfileSelection();
 
 private:
-	bool isColorUsed (class LDColor color) const;
+	bool isColorUsed (class LDColor color);
 };
\ No newline at end of file
--- a/src/toolsets/basictoolset.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/toolsets/basictoolset.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -34,15 +34,11 @@
 BasicToolset::BasicToolset (MainWindow *parent) :
 	Toolset (parent) {}
 
-static int CopyToClipboard()
+int BasicToolset::copyToClipboard()
 {
-	LDObjectList objs = Selection();
-	int num = 0;
-
-	// Clear the clipboard first.
+	LDObjectList objs = selectedObjects();
+	int count = 0;
 	qApp->clipboard()->clear();
-
-	// Now, copy the contents into the clipboard.
 	QString data;
 
 	for (LDObject* obj : objs)
@@ -51,23 +47,23 @@
 			data += "\n";
 
 		data += obj->asText();
-		++num;
+		++count;
 	}
 
 	qApp->clipboard()->setText (data);
-	return num;
+	return count;
 }
 
 void BasicToolset::cut()
 {
-	int num = CopyToClipboard();
+	int num = copyToClipboard();
 	m_window->deleteSelection();
 	print (tr ("%1 objects cut"), num);
 }
 
 void BasicToolset::copy()
 {
-	int num = CopyToClipboard();
+	int num = copyToClipboard();
 	print (tr ("%1 objects copied"), num);
 }
 
@@ -75,13 +71,13 @@
 {
 	const QString clipboardText = qApp->clipboard()->text();
 	int idx = m_window->getInsertionPoint();
-	CurrentDocument()->clearSelection();
+	currentDocument()->clearSelection();
 	int num = 0;
 
 	for (QString line : clipboardText.split ("\n"))
 	{
 		LDObject* pasted = ParseLine (line);
-		CurrentDocument()->insertObj (idx++, pasted);
+		currentDocument()->insertObj (idx++, pasted);
 		pasted->select();
 		++num;
 	}
@@ -99,7 +95,7 @@
 
 void BasicToolset::doInline (bool deep)
 {
-	for (LDObjectIterator<LDSubfile> it (Selection()); it.isValid(); ++it)
+	for (LDObjectIterator<LDSubfile> it (selectedObjects()); it.isValid(); ++it)
 	{
 		// Get the index of the subfile so we know where to insert the
 		// inlined contents.
@@ -115,7 +111,7 @@
 				QString line = inlineobj->asText();
 				inlineobj->destroy();
 				LDObject* newobj = ParseLine (line);
-				CurrentDocument()->insertObj (idx++, newobj);
+				currentDocument()->insertObj (idx++, newobj);
 				newobj->select();
 			}
 	
@@ -137,19 +133,19 @@
 
 void BasicToolset::undo()
 {
-	CurrentDocument()->undo();
+	currentDocument()->undo();
 }
 
 void BasicToolset::redo()
 {
-	CurrentDocument()->redo();
+	currentDocument()->redo();
 }
 
 void BasicToolset::uncolor()
 {
 	int num = 0;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		if (not obj->isColored())
 			continue;
@@ -180,13 +176,13 @@
 	if (dlg->exec() == QDialog::Rejected)
 		return;
 
-	CurrentDocument()->clearSelection();
+	currentDocument()->clearSelection();
 
 	for (QString line : QString (inputbox->toPlainText()).split ("\n"))
 	{
 		LDObject* obj = ParseLine (line);
 
-		CurrentDocument()->insertObj (idx, obj);
+		currentDocument()->insertObj (idx, obj);
 		obj->select();
 		idx++;
 	}
@@ -197,10 +193,10 @@
 
 void BasicToolset::setColor()
 {
-	if (Selection().isEmpty())
+	if (selectedObjects().isEmpty())
 		return;
 
-	LDObjectList objs = Selection();
+	LDObjectList objs = selectedObjects();
 
 	// If all selected objects have the same color, said color is our default
 	// value to the color selection dialog.
@@ -220,7 +216,7 @@
 
 void BasicToolset::invert()
 {
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 		obj->invert();
 }
 
@@ -261,10 +257,10 @@
 
 void BasicToolset::edit()
 {
-	if (Selection().size() != 1)
+	if (selectedObjects().size() != 1)
 		return;
 
-	LDObject* obj = Selection().first();
+	LDObject* obj = selectedObjects().first();
 	AddObjectDialog::staticDialog (obj->type(), obj);
 }
 
--- a/src/toolsets/basictoolset.h	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/toolsets/basictoolset.h	Sat Sep 05 23:03:24 2015 +0300
@@ -54,5 +54,6 @@
 	Q_INVOKABLE void undo();
 
 private:
+	int copyToClipboard();
 	void doInline (bool deep);
 };
--- a/src/toolsets/extprogramtoolset.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/toolsets/extprogramtoolset.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -205,7 +205,7 @@
 //
 void ExtProgramToolset::writeSelection (QString fname)
 {
-	writeObjects (Selection(), fname);
+	writeObjects (selectedObjects(), fname);
 }
 
 // =============================================================================
@@ -214,7 +214,7 @@
 {
 	LDObjectList objects;
 
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : currentDocument()->objects())
 	{
 		if (not obj->isColored() or obj->color() != color)
 			continue;
@@ -325,7 +325,7 @@
 		m_window->deleteByColor (color);
 
 	// Insert the new objects
-	CurrentDocument()->clearSelection();
+	currentDocument()->clearSelection();
 
 	for (LDObject* obj : objs)
 	{
@@ -335,7 +335,7 @@
 			continue;
 		}
 
-		CurrentDocument()->addObject (obj);
+		currentDocument()->addObject (obj);
 		obj->select();
 	}
 
--- a/src/toolsets/filetoolset.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/toolsets/filetoolset.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -39,15 +39,15 @@
 
 	if (dlg->exec() == QDialog::Accepted)
 	{
-		newFile();
-		dlg->fillHeader (CurrentDocument());
+		m_window->createBlankDocument();
+		dlg->fillHeader (currentDocument());
 		m_window->doFullRefresh();
 	}
 }
 
 void FileToolset::newFile()
 {
-	newFile();
+	m_window->createBlankDocument();
 }
 
 void FileToolset::open()
@@ -62,26 +62,26 @@
 
 void FileToolset::save()
 {
-	m_window->save (CurrentDocument(), false);
+	m_window->save (currentDocument(), false);
 }
 
 void FileToolset::saveAs()
 {
-	m_window->save (CurrentDocument(), true);
+	m_window->save (currentDocument(), true);
 }
 
 void FileToolset::saveAll()
 {
-	for (LDDocument* file : LDDocument::explicitDocuments())
+	for (LDDocument* file : m_window->allDocuments())
 		m_window->save (file, false);
 }
 
 void FileToolset::close()
 {
-	if (not CurrentDocument()->isSafeToClose())
+	if (not currentDocument()->isSafeToClose())
 		return;
 
-	CurrentDocument()->dismiss();
+	currentDocument()->dismiss();
 }
 
 void FileToolset::closeAll()
@@ -128,11 +128,11 @@
 
 	LDObjectList objs = LoadFileContents (&f, null);
 
-	CurrentDocument()->clearSelection();
+	currentDocument()->clearSelection();
 
 	for (LDObject* obj : objs)
 	{
-		CurrentDocument()->insertObj (idx, obj);
+		currentDocument()->insertObj (idx, obj);
 		obj->select();
 		m_window->R()->compileObject (obj);
 
@@ -145,7 +145,7 @@
 
 void FileToolset::exportTo()
 {
-	if (Selection().isEmpty())
+	if (selectedObjects().isEmpty())
 		return;
 
 	QString fname = QFileDialog::getSaveFileName();
@@ -161,7 +161,7 @@
 		return;
 	}
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		QString contents = obj->asText();
 		QByteArray data = contents.toUtf8();
@@ -177,7 +177,7 @@
 
 void FileToolset::openSubfiles()
 {
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		LDSubfile* ref = dynamic_cast<LDSubfile*> (obj);
 
--- a/src/toolsets/movetoolset.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/toolsets/movetoolset.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -27,7 +27,7 @@
 
 void MoveToolset::moveSelection (bool up)
 {
-	LDObjectList objs = Selection();
+	LDObjectList objs = selectedObjects();
 	LDObject::moveObjects (objs, up);
 	m_window->buildObjList();
 }
@@ -65,7 +65,7 @@
 	// Apply the grid values
 	vect *= gridCoordinateSnap();
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 		obj->move (vect);
 }
 
@@ -106,32 +106,32 @@
 
 void MoveToolset::rotateXPos()
 {
-	RotateObjects (1, 0, 0, getRotateActionAngle(), Selection());
+	RotateObjects (1, 0, 0, getRotateActionAngle(), selectedObjects());
 }
 
 void MoveToolset::rotateYPos()
 {
-	RotateObjects (0, 1, 0, getRotateActionAngle(), Selection());
+	RotateObjects (0, 1, 0, getRotateActionAngle(), selectedObjects());
 }
 
 void MoveToolset::rotateZPos()
 {
-	RotateObjects (0, 0, 1, getRotateActionAngle(), Selection());
+	RotateObjects (0, 0, 1, getRotateActionAngle(), selectedObjects());
 }
 
 void MoveToolset::rotateXNeg()
 {
-	RotateObjects (-1, 0, 0, getRotateActionAngle(), Selection());
+	RotateObjects (-1, 0, 0, getRotateActionAngle(), selectedObjects());
 }
 
 void MoveToolset::rotateYNeg()
 {
-	RotateObjects (0, -1, 0, getRotateActionAngle(), Selection());
+	RotateObjects (0, -1, 0, getRotateActionAngle(), selectedObjects());
 }
 
 void MoveToolset::rotateZNeg()
 {
-	RotateObjects (0, 0, -1, getRotateActionAngle(), Selection());
+	RotateObjects (0, 0, -1, getRotateActionAngle(), selectedObjects());
 }
 
 void MoveToolset::configureRotationPoint()
--- a/src/toolsets/viewtoolset.cpp	Mon Aug 31 23:36:08 2015 +0300
+++ b/src/toolsets/viewtoolset.cpp	Sat Sep 05 23:03:24 2015 +0300
@@ -33,27 +33,27 @@
 
 void ViewToolset::selectAll()
 {
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : currentDocument()->objects())
 		obj->select();
 }
 
 void ViewToolset::selectByColor()
 {
-	if (Selection().isEmpty())
+	if (selectedObjects().isEmpty())
 		return;
 
 	QList<LDColor> colors;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		if (obj->isColored())
 			colors << obj->color();
 	}
 
 	removeDuplicates (colors);
-	CurrentDocument()->clearSelection();
+	currentDocument()->clearSelection();
 
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : currentDocument()->objects())
 	{
 		if (colors.contains (obj->color()))
 			obj->select();
@@ -62,13 +62,13 @@
 
 void ViewToolset::selectByType()
 {
-	if (Selection().isEmpty())
+	if (selectedObjects().isEmpty())
 		return;
 
 	QList<LDObjectType> types;
 	QStringList subfilenames;
 
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 	{
 		types << obj->type();
 
@@ -78,9 +78,9 @@
 
 	removeDuplicates (types);
 	removeDuplicates (subfilenames);
-	CurrentDocument()->clearSelection();
+	currentDocument()->clearSelection();
 
-	for (LDObject* obj : CurrentDocument()->objects())
+	for (LDObject* obj : currentDocument()->objects())
 	{
 		LDObjectType type = obj->type();
 
@@ -109,7 +109,7 @@
 	uchar* imgdata = m_window->R()->getScreencap (w, h);
 	QImage img = GetImageFromScreencap (imgdata, w, h);
 
-	QString root = Basename (CurrentDocument()->name());
+	QString root = Basename (currentDocument()->name());
 
 	if (root.right (4) == ".dat")
 		root.chop (4);
@@ -133,19 +133,19 @@
 
 void ViewToolset::visibilityToggle()
 {
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 		obj->setHidden (not obj->isHidden());
 }
 
 void ViewToolset::visibilityHide()
 {
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 		obj->setHidden (true);
 }
 
 void ViewToolset::visibilityReveal()
 {
-	for (LDObject* obj : Selection())
+	for (LDObject* obj : selectedObjects())
 		obj->setHidden (false);
 }
 
@@ -257,16 +257,16 @@
 	int defval = 0;
 	LDObject* obj;
 
-	if (Selection().size() == 1)
-		defval = Selection()[0]->lineNumber();
+	if (selectedObjects().size() == 1)
+		defval = selectedObjects()[0]->lineNumber();
 
 	int idx = QInputDialog::getInt (null, "Go to line", "Go to line:", defval,
-		1, CurrentDocument()->getObjectCount(), 1, &ok);
+		1, currentDocument()->getObjectCount(), 1, &ok);
 
-	if (not ok or (obj = CurrentDocument()->getObject (idx - 1)) == null)
+	if (not ok or (obj = currentDocument()->getObject (idx - 1)) == null)
 		return;
 
-	CurrentDocument()->clearSelection();
+	currentDocument()->clearSelection();
 	obj->select();
 	m_window->updateSelection();
 }

mercurial