Cleanup progresses

Sat, 22 Aug 2015 18:10:28 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 22 Aug 2015 18:10:28 +0300
changeset 946
9cbd658b63f9
parent 945
c310073e4f22
child 947
edc8fc0f37f2

Cleanup progresses

CMakeLists.txt file | annotate | diff | comparison | revisions
src/actions.cc file | annotate | diff | comparison | revisions
src/actionsEdit.cc file | annotate | diff | comparison | revisions
src/addObjectDialog.cc file | annotate | diff | comparison | revisions
src/basics.cc file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/colorSelector.cc file | annotate | diff | comparison | revisions
src/colorSelector.h file | annotate | diff | comparison | revisions
src/colors.cc file | annotate | diff | comparison | revisions
src/colors.h file | annotate | diff | comparison | revisions
src/configDialog.cc file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cc file | annotate | diff | comparison | revisions
src/editmodes/drawMode.cc file | annotate | diff | comparison | revisions
src/editmodes/rectangleMode.cc file | annotate | diff | comparison | revisions
src/extPrograms.cc file | annotate | diff | comparison | revisions
src/format.h file | annotate | diff | comparison | revisions
src/glCompiler.cc file | annotate | diff | comparison | revisions
src/glRenderer.cc file | annotate | diff | comparison | revisions
src/ldConfig.cc file | annotate | diff | comparison | revisions
src/ldConfig.h file | annotate | diff | comparison | revisions
src/ldDocument.cc file | annotate | diff | comparison | revisions
src/ldDocument.h file | annotate | diff | comparison | revisions
src/ldObject.cc file | annotate | diff | comparison | revisions
src/ldObject.h file | annotate | diff | comparison | revisions
src/mainWindow.cc file | annotate | diff | comparison | revisions
src/mainWindow.h file | annotate | diff | comparison | revisions
src/primitives.cc file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sat Aug 22 15:58:50 2015 +0300
+++ b/CMakeLists.txt	Sat Aug 22 18:10:28 2015 +0300
@@ -51,7 +51,6 @@
 	src/extPrograms.cc
 	src/glRenderer.cc
 	src/glCompiler.cc
-	src/ldConfig.cc
 	src/ldDocument.cc
 	src/ldObject.cc
     src/ldObjectMath.cpp
@@ -80,7 +79,6 @@
 	src/ringFinder.h
 	src/ldDocument.h
 	src/addObjectDialog.h
-	src/ldConfig.h
 	src/partDownloader.h
 	src/ldObject.h
     src/ldObjectMath.h
--- a/src/actions.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/actions.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -855,7 +855,7 @@
 
 		// Add a reference to the new subfile to where the selection was
 		LDSubfile* ref (LDSpawn<LDSubfile>());
-		ref->setColor (MainColor());
+		ref->setColor (MainColor);
 		ref->setFileInfo (doc);
 		ref->setPosition (Origin);
 		ref->setTransform (IdentityMatrix);
--- a/src/actionsEdit.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/actionsEdit.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -306,10 +306,10 @@
 
 		for (int i = 0; i < obj->numVertices(); ++i)
 		{
-			QSharedPointer<LDVertex> vert (LDSpawn<LDVertex>());
-			vert->pos = obj->vertex (i);
-			vert->setColor (obj->color());
-			CurrentDocument()->insertObj (++ln, vert);
+			LDVertex* vertex = new LDVertex();
+			vertex->pos = obj->vertex (i);
+			vertex->setColor (obj->color());
+			CurrentDocument()->insertObj (++ln, vertex);
 			++num;
 		}
 	}
@@ -624,16 +624,15 @@
 //
 void MainWindow::slot_actionAutocolor()
 {
-	int colnum = 0;
 	LDColor color;
 
-	for (colnum = 0;
-		 colnum < CountLDConfigColors() and
-			((color = LDColor::fromIndex (colnum)) == null or
-			IsColorUsed (color));
-		colnum++) {}
+	for (color = 0; color.isLDConfigColor(); ++color)
+	{
+		if (color.isValid() and not IsColorUsed (color))
+			break;
+	}
 
-	if (colnum >= CountLDConfigColors())
+	if (not color.isLDConfigColor())
 	{
 		print (tr ("Cannot auto-color: all colors are in use!"));
 		return;
@@ -647,7 +646,7 @@
 		obj->setColor (color);
 	}
 
-	print (tr ("Auto-colored: new color is [%1] %2"), colnum, color.name());
+	print (tr ("Auto-colored: new color is [%1] %2"), color.index(), color.name());
 	refresh();
 }
 
@@ -692,7 +691,7 @@
 	}
 
 	int idx = obj ? obj->lineNumber() : 0;
-	CurrentDocument()->insertObj (idx++, comm);
+	CurrentDocument()->insertObj (idx++, comment);
 
 	// If we're adding a history line right before a scemantic object, pad it
 	// an empty line
--- a/src/addObjectDialog.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/addObjectDialog.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -132,7 +132,7 @@
 		if (obj != null)
 			m_color = obj->color();
 		else
-			m_color = (type == OBJ_CondLine or type == OBJ_Line) ? EdgeColor() : MainColor();
+			m_color = (type == OBJ_CondLine or type == OBJ_Line) ? EdgeColor : MainColor;
 
 		pb_color = new QPushButton;
 		setButtonBackground (pb_color, m_color);
@@ -239,7 +239,7 @@
 	button->setIcon (GetIcon ("palette"));
 	button->setAutoFillBackground (true);
 
-	if (color != null)
+	if (color.isValid())
 		button->setStyleSheet (format ("background-color: %1", color.hexcode()));
 }
 
--- a/src/basics.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/basics.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -237,24 +237,24 @@
 {
 	switch (obj->type())
 	{
-		case OBJ_Line:
-		case OBJ_Triangle:
-		case OBJ_Quad:
-		case OBJ_CondLine:
-			for (int i = 0; i < obj->numVertices(); ++i)
-				calcVertex (obj->vertex (i));
-			break;
+	case OBJ_Line:
+	case OBJ_Triangle:
+	case OBJ_Quad:
+	case OBJ_CondLine:
+		for (int i = 0; i < obj->numVertices(); ++i)
+			calcVertex (obj->vertex (i));
+		break;
 
-		case OBJ_Subfile:
-			for (LDObject* obj : static_cast<LDSubfile*> (obj)->inlineContents (true, false))
-			{
-				calcObject (obj);
-				obj->destroy();
-			}
-			break;
+	case OBJ_Subfile:
+		for (LDObject* it : static_cast<LDSubfile*> (obj)->inlineContents (true, false))
+		{
+			calcObject (it);
+			it->destroy();
+		}
+		break;
 
-		default:
-			break;
+	default:
+		break;
 	}
 }
 
--- a/src/basics.h	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/basics.h	Sat Aug 22 18:10:28 2015 +0300
@@ -22,7 +22,6 @@
 #include <QStringList>
 #include <QMetaType>
 #include <QVector3D>
-#include <QSharedPointer>
 #include <functional>
 #include "macros.h"
 
--- a/src/colorSelector.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/colorSelector.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -32,7 +32,7 @@
 #include "miscallenous.h"
 #include "ui_colorsel.h"
 
-static const int g_numColumns = 16;
+enum { NUM_COLUMNS = 16 };
 
 EXTERN_CFGENTRY (String, MainColor)
 EXTERN_CFGENTRY (Float, MainColorAlpha)
@@ -50,19 +50,17 @@
 	QGridLayout* layout = new QGridLayout (this);
 
 	// Spawn color selector buttons
-	for (int i = 0; i < CountLDConfigColors(); ++i)
+	for (LDColor ldcolor; ldcolor.isLDConfigColor(); ++ldcolor)
 	{
-		LDColor ldcolor = LDColor::fromIndex (i);
 		QPushButton* button = new QPushButton (this);
 		button->setMinimumSize (QSize (32, 32));
 		button->setMaximumSize (button->minimumSize());
 
-		if (ldcolor != null)
+		if (ldcolor.isValid ())
 		{
-			QString colorname;
 			QColor color (ldcolor.faceColor());
 
-			if (i == MainColorIndex)
+			if (ldcolor == MainColor)
 			{
 				color = QColor (cfg::MainColor);
 				color.setAlphaF (cfg::MainColorAlpha);
@@ -75,8 +73,8 @@
 			button->setCheckable (true);
 			button->setText (QString::number (ldcolor.index()));
 			button->setToolTip (format ("%1: %2", ldcolor.index(), ldcolor.name()));
-			m_buttons[i] = button;
-			m_buttonsReversed[button] = i;
+			m_buttons[ldcolor.index()] = button;
+			m_buttonsReversed[button] = ldcolor.index();
 			connect (button, SIGNAL (clicked(bool)), this, SLOT (colorButtonClicked()));
 
 			if (ldcolor == selection())
@@ -87,7 +85,7 @@
 			button->setEnabled (false);
 		}
 
-		layout->addWidget (button, i / g_numColumns, i % g_numColumns);
+		layout->addWidget (button, ldcolor.index() / NUM_COLUMNS, ldcolor.index() % NUM_COLUMNS);
 	}
 
 	QWidget* widget = new QWidget();
@@ -122,18 +120,18 @@
 	LDColor color;
 
 	if (Q_UNLIKELY (button == null or it == m_buttonsReversed.end()
-		or (color = LDColor::fromIndex (*it)) == null))
+		or not (color = *it).isValid()))
 	{
 		print ("colorButtonClicked() called with invalid sender");
 		return;
 	}
 
-	if (selection() != null)
+	if (selection().isValid())
 	{
-		auto it2 = m_buttons.find (selection().index());
+		auto button = m_buttons.find (selection().index());
 
-		if (it2 != m_buttons.end())
-			(*it2)->setChecked (false);
+		if (button != m_buttons.end())
+			(*button)->setChecked (false);
 	}
 
 	setSelection (color);
@@ -145,7 +143,7 @@
 //
 void ColorSelector::drawColorInfo()
 {
-	if (selection() == null)
+	if (not selection().isValid())
 	{
 		ui->colorLabel->setText ("---");
 		ui->iconLabel->setPixmap (QPixmap());
@@ -168,11 +166,11 @@
 
 // =============================================================================
 //
-void ColorSelector::selectDirectColor (QColor col)
+void ColorSelector::selectDirectColor (QColor color)
 {
-	int32 idx = (ui->transparentDirectColor->isChecked() ? 0x03000000 : 0x02000000);
-	idx |= (col.red() << 16) | (col.green() << 8) | (col.blue());
-	setSelection (LDColor::fromIndex (idx));
+	qint32 colorIndex = (ui->transparentDirectColor->isChecked() ? 0x03000000 : 0x02000000);
+	colorIndex |= (color.red() << 16) | (color.green() << 8) | (color.blue());
+	setSelection (colorIndex);
 	drawColorInfo();
 }
 
@@ -180,7 +178,7 @@
 //
 void ColorSelector::chooseDirectColor()
 {
-	QColor defcolor = selection() != null ? selection().faceColor() : Qt::white;
+	QColor defcolor = selection() != -1 ? selection().faceColor() : Qt::white;
 	QColor newcolor = QColorDialog::getColor (defcolor);
 
 	if (not newcolor.isValid())
@@ -193,10 +191,8 @@
 //
 void ColorSelector::transparentCheckboxClicked()
 {
-	if (selection() == null or not selection().isDirect())
-		return;
-
-	selectDirectColor (selection().faceColor());
+	if (selection().isDirect())
+		selectDirectColor (selection().faceColor());
 }
 
 // =============================================================================
@@ -205,7 +201,7 @@
 {
 	ColorSelector dlg (defval, parent);
 
-	if (dlg.exec() and dlg.selection() != null)
+	if (dlg.exec() and dlg.selection().isValid())
 	{
 		val = dlg.selection();
 		return true;
--- a/src/colorSelector.h	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/colorSelector.h	Sat Aug 22 18:10:28 2015 +0300
@@ -21,24 +21,21 @@
 #include "main.h"
 #include "colors.h"
 
-class Ui_ColorSelUI;
-class QGraphicsScene;
-
 class ColorSelector : public QDialog
 {
 	Q_OBJECT
-	PROPERTY (private,	LDColor,	selection,	setSelection,	STOCK_WRITE)
+	PROPERTY (private, LDColor, selection, setSelection, STOCK_WRITE)
 
 public:
-	explicit ColorSelector (LDColor defaultvalue = null, QWidget* parent = null);
+	explicit ColorSelector (LDColor defaultvalue = LDColor::nullColor(), QWidget* parent = null);
 	virtual ~ColorSelector();
-	static bool selectColor (LDColor& val, LDColor defval = null, QWidget* parent = null);
+	static bool selectColor (LDColor& val, LDColor defval = LDColor::nullColor(), QWidget* parent = null);
 
 private:
-	Ui_ColorSelUI*	ui;
+	class Ui_ColorSelUI* ui;
 	QMap<int, QPushButton*> m_buttons;
 	QMap<QPushButton*, int> m_buttonsReversed;
-	bool			m_firstResize;
+	bool m_firstResize;
 
 	void drawColorInfo();
 	void selectDirectColor (QColor col);
--- a/src/colors.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/colors.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -16,79 +16,118 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QFile>
 #include "main.h"
 #include "colors.h"
 #include "ldDocument.h"
 #include "miscallenous.h"
 #include "mainWindow.h"
-#include "ldConfig.h"
-#include <QColor>
 
-static LDColor g_LDConfigColors[512];
+struct ColorDataEntry
+{
+	QString name;
+	QString hexcode;
+	QColor faceColor;
+	QColor edgeColor;
+};
+
+static ColorDataEntry ColorData[512];
 
 void InitColors()
 {
-	LDColorData* col;
 	print ("Initializing color information.\n");
 
 	// Always make sure there's 16 and 24 available. They're special like that.
-	col = new LDColorData;
-	col->m_faceColor =
-	col->m_hexcode = "#AAAAAA";
-	col->m_edgeColor = Qt::black;
-	g_LDConfigColors[16] = col;
+	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";
 
-	col = new LDColorData;
-	col->m_faceColor =
-	col->m_edgeColor =
-	col->m_hexcode = "#000000";
-	g_LDConfigColors[24] = col;
+	parseLDConfig();
+}
 
-	LDConfigParser::parseLDConfig();
+bool LDColor::isValid() const
+{
+	if (isLDConfigColor() and ColorData[index()].name.isEmpty())
+		return false; // Unknown LDConfig color
+
+	return m_index != -1;
 }
 
-LDColor MainColor()
+bool LDColor::isLDConfigColor() const
 {
-	return g_LDConfigColors[MainColorIndex];
+	return index() >= 0 and index() < countof (ColorData);
 }
 
-LDColor EdgeColor()
+QString LDColor::name() const
 {
-	return g_LDConfigColors[EdgeColorIndex];
+	if (isDirect())
+		return "0x" + QString::number (index(), 16).toUpper();
+	else if (isLDConfigColor())
+		return ColorData[index()].name;
+	else if (index() == -1)
+		return "null color";
+	else
+		return "";
+}
+
+QString LDColor::hexcode() const
+{
+	return faceColor().name();
 }
 
-void LDColor::addLDConfigColor (qint32 index, LDColor color)
+QColor LDColor::faceColor() const
 {
-	assert (index >= 0 and index < countof (g_LDConfigColors));
-	g_LDConfigColors[index] = color;
+	if (isDirect())
+	{
+		QColor color;
+		color.setRed ((index() & 0x0FF0000) >> 16);
+		color.setGreen ((index() & 0x000FF00) >> 8);
+		color.setBlue (index() & 0x00000FF);
+
+		if (index() >= 0x3000000)
+			color.setAlpha (128);
+
+		return color;
+	}
+	else if (isLDConfigColor())
+	{
+		return ColorData[index()].faceColor;
+	}
+	else
+	{
+		return Qt::black;
+	}
 }
 
-LDColor LDColor::fromIndex (qint32 index)
+QColor LDColor::edgeColor() const
 {
-	if (index < countof (g_LDConfigColors) and g_LDConfigColors[index] != null)
-		return g_LDConfigColors[index];
-
-	if (index >= 0x2000000)
-	{
-		// Direct color
-		QColor col;
-		col.setRed ((index & 0x0FF0000) >> 16);
-		col.setGreen ((index & 0x000FF00) >> 8);
-		col.setBlue (index & 0x00000FF);
+	if (isDirect())
+		return Luma (faceColor()) < 48 ? Qt::white : Qt::black;
+	else if (isLDConfigColor())
+		return ColorData[index()].edgeColor;
+	else
+		return Qt::black;
+}
 
-		if (index >= 0x3000000)
-			col.setAlpha (128);
+int LDColor::luma() const
+{
+	return Luma (faceColor());
+}
 
-		LDColorData* color = new LDColorData;
-		color->m_name = "0x" + QString::number (index, 16).toUpper();
-		color->m_faceColor = col;
-		color->m_edgeColor = Luma (col) < 48 ? Qt::white : Qt::black;
-		color->m_hexcode = col.name();
-		color->m_index = index;
-		return LDColor (color);
-	}
+int LDColor::edgeLuma() const
+{
+	return Luma (edgeColor());
+}
 
-	return null;
+qint32 LDColor::index() const
+{
+	return m_index;
 }
 
 QString LDColor::indexString() const
@@ -104,26 +143,151 @@
 	return index() >= 0x02000000;
 }
 
-bool LDColor::operator== (LDColor const& other)
-{
-	if ((data() == nullptr) ^ (other == nullptr))
-		return false;
-
-	if (data() != nullptr)
-		return index() == other.index();
-
-	// both are null
-	return true;
-}
-
 int Luma (const QColor& col)
 {
-	return (0.2126f * col.red()) +
-		   (0.7152f * col.green()) +
-		   (0.0722f * col.blue());
+	return (0.2126f * col.red()) + (0.7152f * col.green()) + (0.0722f * col.blue());
 }
 
 int CountLDConfigColors()
 {
-	return countof (g_LDConfigColors);
+	return countof (ColorData);
 }
+
+void parseLDConfig()
+{
+	QFile* fp = OpenLDrawFile ("LDConfig.ldr", false);
+
+	if (fp == nullptr)
+	{
+		Critical (QObject::tr ("Unable to open LDConfig.ldr for parsing."));
+		return;
+	}
+
+	// Read in the lines
+	while (not fp->atEnd())
+	{
+		QString line = QString::fromUtf8 (fp->readLine());
+
+		if (line.isEmpty() or line[0] != '0')
+			continue; // empty or illogical
+
+		line.remove ('\r');
+		line.remove ('\n');
+
+		// Parse the line
+		LDConfigParser pars (line, ' ');
+
+		int code = 0, alpha = 255;
+		QString name, facename, edgename, valuestr;
+
+		// Check 0 !COLOUR, parse the name
+		if (not pars.compareToken (0, "0") or
+			not pars.compareToken (1, "!COLOUR") or
+			not pars.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))
+			continue;
+
+		// Ensure that the code is within [0 - 511]
+		bool ok;
+		code = valuestr.toShort (&ok);
+
+		if (not ok or code < 0 or code >= 512)
+			continue;
+
+		// VALUE and EDGE tags
+		if (not pars.parseLDConfigTag ("VALUE", facename) or not pars.parseLDConfigTag ("EDGE", edgename))
+			continue;
+
+		// Ensure that our colors are correct
+		QColor faceColor (facename),
+			edgeColor (edgename);
+
+		if (not faceColor.isValid() or not edgeColor.isValid())
+			continue;
+
+		// Parse alpha if given.
+		if (pars.parseLDConfigTag ("ALPHA", valuestr))
+			alpha = Clamp (valuestr.toInt(), 0, 255);
+
+		ColorDataEntry& entry = ColorData[code];
+		entry.name = name;
+		entry.faceColor = faceColor;
+		entry.edgeColor = edgeColor;
+		entry.hexcode = facename;
+		entry.faceColor.setAlpha (alpha);
+	}
+
+	fp->close();
+	fp->deleteLater();
+}
+
+// =============================================================================
+//
+LDConfigParser::LDConfigParser (QString inText, char sep)
+{
+	m_tokens = inText.split (sep, QString::SkipEmptyParts);
+	m_pos = -1;
+}
+
+// =============================================================================
+//
+bool LDConfigParser::getToken (QString& val, const int pos)
+{
+	if (pos >= m_tokens.size())
+		return false;
+
+	val = m_tokens[pos];
+	return true;
+}
+
+// =============================================================================
+//
+bool LDConfigParser::findToken (int& result, char const* needle, int args)
+{
+	for (int i = 0; i < (m_tokens.size() - args); ++i)
+	{
+		if (m_tokens[i] == needle)
+		{
+			result = i;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// =============================================================================
+//
+bool LDConfigParser::compareToken (int inPos, QString text)
+{
+	QString tok;
+
+	if (not getToken (tok, inPos))
+		return false;
+
+	return (tok == text);
+}
+
+// =============================================================================
+//
+// Helper function for parseLDConfig
+//
+bool LDConfigParser::parseLDConfigTag (char const* tag, QString& val)
+{
+	int pos;
+
+	// Try find the token and get its position
+	if (not findToken (pos, tag, 1))
+		return false;
+
+	// Get the token after it and store it into val
+	return getToken (val, pos + 1);
+}
\ No newline at end of file
--- a/src/colors.h	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/colors.h	Sat Aug 22 18:10:28 2015 +0300
@@ -20,66 +20,75 @@
 #include <QColor>
 #include "main.h"
 
-#define SHARED_POINTER_DERIVATIVE(T) \
-public: \
-	using Self = T; \
-	using DataType = T##Data; \
-	using Super = QSharedPointer<DataType>; \
-	\
-	T() : Super() {} \
-	T (DataType* data) : Super (data) {} \
-	T (Super const& other) : Super (other) {} \
-	T (QPointer<DataType> const& other) : Super (other) {} \
-	\
-	template <typename Deleter> \
-	T (DataType* data, Deleter dlt) : Super (data, dlt) {} \
-	\
-	inline bool			operator== (decltype(nullptr)) { return data() == nullptr; } \
-	inline bool			operator!= (decltype(nullptr)) { return data() != nullptr; } \
-	inline DataType*	operator->() const = delete;
+class LDColor
+{
+public:
+	LDColor() : m_index (0) {}
+	LDColor (qint32 index) : m_index (index) {}
+	LDColor (const LDColor& other) : m_index (other.m_index) {}
 
-#define SHARED_POINTER_DATA_ACCESS(N) \
-	public: inline decltype(DataType::m_##N) const& N() const { return data()->m_##N; }
+	bool isLDConfigColor() const;
+	bool isValid() const;
+	QString name() const;
+	QString hexcode() const;
+	QColor faceColor() const;
+	QColor edgeColor() const;
+	qint32 index() const;
+	int luma() const;
+	int edgeLuma() const;
+	bool isDirect() const;
+	QString indexString() const;
 
-class LDColor;
+	static LDColor nullColor() { return LDColor (-1); }
 
-struct LDColorData
-{
-	QString m_name;
-	QString m_hexcode;
-	QColor m_faceColor;
-	QColor m_edgeColor;
+	LDColor& operator= (qint32 index) { m_index = index; return *this; }
+	LDColor& operator= (LDColor other) { m_index = other.index(); return *this; }
+	LDColor operator++() { return ++m_index; }
+	LDColor operator++ (int) { return m_index++; }
+	LDColor operator--() { return --m_index; }
+	LDColor operator-- (int) { return m_index--; }
+
+	bool operator== (LDColor other) const { return index() == other.index(); }
+	bool operator!= (LDColor other) const { return index() != other.index(); }
+	bool operator< (LDColor other) const { return index() < other.index(); }
+	bool operator<= (LDColor other) const { return index() <= other.index(); }
+	bool operator> (LDColor other) const { return index() > other.index(); }
+	bool operator>= (LDColor other) const { return index() >= other.index(); }
+
+private:
 	qint32 m_index;
 };
 
-class LDColor : public QSharedPointer<LDColorData>
+//
+// Parses ldconfig.ldr
+//
+class LDConfigParser
 {
-	SHARED_POINTER_DERIVATIVE (LDColor)
-	SHARED_POINTER_DATA_ACCESS (edgeColor)
-	SHARED_POINTER_DATA_ACCESS (faceColor)
-	SHARED_POINTER_DATA_ACCESS (hexcode)
-	SHARED_POINTER_DATA_ACCESS (index)
-	SHARED_POINTER_DATA_ACCESS (name)
+public:
+	LDConfigParser (QString inText, char sep);
+
+	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);
 
-public:
-	QString				indexString() const;
-	bool				isDirect() const;
+	inline QString operator[] (const int idx)
+	{
+		return m_tokens[idx];
+	}
 
-	bool				operator== (Self const& other);
-	static void			addLDConfigColor (qint32 index, LDColor color);
-	static LDColor		fromIndex (qint32 index);
+private:
+	QStringList m_tokens;
+	int m_pos;
 };
 
 void InitColors();
 int Luma (const QColor& col);
 int CountLDConfigColors();
-
-// Main and edge colors
-LDColor MainColor();
-LDColor EdgeColor();
+void parseLDConfig();
 
 enum
 {
-	MainColorIndex = 16,
-	EdgeColorIndex = 24,
+	MainColor = 16,
+	EdgeColor = 24,
 };
--- a/src/configDialog.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/configDialog.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -368,18 +368,18 @@
 		}
 		else
 		{
-			LDColor col (entry.color());
+			LDColor color = entry.color();
 
-			if (col == null)
+			if (color.isValid())
+			{
+				item->setText (color.name());
+				item->setIcon (MakeColorIcon (color, 16));
+			}
+			else
 			{
 				item->setText ("[[unknown color]]");
 				item->setIcon (GetIcon ("error"));
 			}
-			else
-			{
-				item->setText (col.name());
-				item->setIcon (MakeColorIcon (col, 16));
-			}
 		}
 
 		ui->quickColorList->addItem (item);
@@ -416,23 +416,23 @@
 			return; // don't color separators
 	}
 
-	LDColor defval = entry ? entry->color() : null;
-	LDColor val;
+	LDColor defaultValue = entry ? entry->color() : LDColor::nullColor();
+	LDColor value;
 
-	if (not ColorSelector::selectColor (val, defval, this))
+	if (not ColorSelector::selectColor (value, defaultValue, this))
 		return;
 
 	if (entry != null)
 	{
-		entry->setColor (val);
+		entry->setColor (value);
 	}
 	else
 	{
-		LDQuickColor entry (val, null);
+		LDQuickColor newentry (value, null);
 		item = getSelectedQuickColor();
 		int idx = (item) ? getItemRow (item, quickColorItems) + 1 : quickColorItems.size();
-		quickColors.insert (idx, entry);
-		entry = quickColors[idx];
+		quickColors.insert (idx, newentry);
+		entry = &quickColors[idx];
 	}
 
 	updateQuickColorList (entry);
--- a/src/editmodes/circleMode.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/editmodes/circleMode.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -108,7 +108,7 @@
 			ref->setFileInfo (refFile);
 			ref->setTransform (getCircleDrawMatrix (cmp.scale));
 			ref->setPosition (m_drawedVerts[0]);
-			ref->setColor (MainColor());
+			ref->setColor (MainColor);
 			objs << ref;
 		}
 	}
@@ -145,7 +145,7 @@
 			v3.setCoordinate (localy, v3[localy] + c1[i].y1());
 
 			LDQuad* quad (LDSpawn<LDQuad> (v0, v1, v2, v3));
-			quad->setColor (MainColor());
+			quad->setColor (MainColor);
 
 			// Ensure the quads always are BFC-front towards the camera
 			if (renderer()->camera() % 3 <= 0)
@@ -161,7 +161,7 @@
 		ref->setFileInfo (refFile);
 		ref->setTransform (transform);
 		ref->setPosition (m_drawedVerts[0]);
-		ref->setColor (MainColor());
+		ref->setColor (MainColor);
 		objs << ref;
 	}
 
--- a/src/editmodes/drawMode.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/editmodes/drawMode.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -95,7 +95,7 @@
 			// 1 vertex - add a vertex object
 			LDVertex* obj = LDSpawn<LDVertex>();
 			obj->pos = verts[0];
-			obj->setColor (MainColor());
+			obj->setColor (MainColor);
 			objs << obj;
 			break;
 		}
@@ -104,7 +104,7 @@
 		{
 			// 2 verts - make a line
 			LDLine* obj = LDSpawn<LDLine> (verts[0], verts[1]);
-			obj->setColor (EdgeColor());
+			obj->setColor (EdgeColor);
 			objs << obj;
 			break;
 		}
@@ -116,7 +116,7 @@
 				static_cast<LDObject*> (LDSpawn<LDTriangle>()) :
 				static_cast<LDObject*> (LDSpawn<LDQuad>());
 
-			obj->setColor (MainColor());
+			obj->setColor (MainColor);
 
 			for (int i = 0; i < verts.size(); ++i)
 				obj->setVertex (i, verts[i]);
--- a/src/editmodes/rectangleMode.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/editmodes/rectangleMode.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -52,7 +52,7 @@
 			for (int i = 0; i < quad->numVertices(); ++i)
 				quad->setVertex (i, m_rectangleVerts[i]);
 
-			quad->setColor (MainColor());
+			quad->setColor (MainColor);
 			finishDraw (LDObjectList ({quad}));
 			return true;
 		}
--- a/src/extPrograms.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/extPrograms.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -476,8 +476,8 @@
 		if (not dlg->exec())
 			return;
 
-		inCol = LDColor::fromIndex (ui.cmb_incol->itemData (ui.cmb_incol->currentIndex()).toInt());
-		cutCol = LDColor::fromIndex (ui.cmb_cutcol->itemData (ui.cmb_cutcol->currentIndex()).toInt());
+		inCol = ui.cmb_incol->itemData (ui.cmb_incol->currentIndex()).toInt();
+		cutCol = ui.cmb_cutcol->itemData (ui.cmb_cutcol->currentIndex()).toInt();
 
 		if (inCol == cutCol)
 		{
@@ -570,8 +570,8 @@
 		if (not dlg->exec())
 			return;
 
-		in1Col = LDColor::fromIndex (ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt());
-		in2Col = LDColor::fromIndex (ui.cmb_col2->itemData (ui.cmb_col2->currentIndex()).toInt());
+		in1Col = ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt();
+		in2Col = ui.cmb_col2->itemData (ui.cmb_col2->currentIndex()).toInt();
 
 		if (in1Col == in2Col)
 		{
@@ -636,8 +636,8 @@
 		if (not dlg->exec())
 			return;
 
-		in1Col = LDColor::fromIndex (ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt());
-		in2Col = LDColor::fromIndex (ui.cmb_col2->itemData (ui.cmb_col2->currentIndex()).toInt());
+		in1Col = ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt();
+		in2Col = ui.cmb_col2->itemData (ui.cmb_col2->currentIndex()).toInt();
 
 		if (in1Col == in2Col)
 		{
--- a/src/format.h	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/format.h	Sat Aug 22 18:10:28 2015 +0300
@@ -46,18 +46,6 @@
 	}
 
 	template<typename T>
-	StringFormatArg (QSharedPointer<T> const& a)
-	{
-		m_text.sprintf ("%p", a.data());
-	}
-
-	template<typename T>
-	StringFormatArg (QPointer<T> const& a)
-	{
-		m_text.sprintf ("%p", a.data());
-	}
-
-	template<typename T>
 	StringFormatArg (const QList<T>& a)
 	{
 		m_text = "{";
--- a/src/glCompiler.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/glCompiler.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -159,22 +159,22 @@
 			break;
 
 		case VBOCM_NormalColors:
-			if (poly.color == MainColorIndex)
+			if (poly.color == MainColor)
 			{
-				if (topobj->color() == MainColor())
+				if (topobj->color() == MainColor)
 					qcol = GLRenderer::getMainColor();
 				else
 					qcol = topobj->color().faceColor();
 			}
-			elif (poly.color == EdgeColorIndex)
+			else if (poly.color == EdgeColor)
 			{
 				qcol = Luma (QColor (cfg::BackgroundColor)) > 40 ? Qt::black : Qt::white;
 			}
 			else
 			{
-				LDColor col = LDColor::fromIndex (poly.color);
+				LDColor col = poly.color;
 
-				if (col)
+				if (col.isValid())
 					qcol = col.faceColor();
 			}
 			break;
@@ -203,7 +203,7 @@
 
 	if (topobj->isSelected())
 		blendAlpha = 1.0;
-	elif (topobj == m_renderer->objectAtCursor())
+	else if (topobj == m_renderer->objectAtCursor())
 		blendAlpha = 0.5;
 
 	if (blendAlpha != 0.0)
@@ -249,11 +249,11 @@
 //
 void GLCompiler::compileDocument (LDDocument* doc)
 {
-	if (doc == null)
-		return;
-
-	for (LDObject* obj : doc->objects())
-		compileObject (obj);
+	if (doc != null)
+	{
+		for (LDObject* obj : doc->objects())
+			compileObject (obj);
+	}
 }
 
 // =============================================================================
--- a/src/glRenderer.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/glRenderer.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -950,7 +950,7 @@
 	// Read pixels from the color buffer.
 	glReadPixels (x0, m_height - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixeldata);
 
-	LDObject* removedObj;
+	LDObject* removedObj = nullptr;
 	QList<qint32> indices;
 
 	// Go through each pixel read and add them to the selection.
@@ -1531,7 +1531,7 @@
 	if (not cfg::HighlightObjectBelowCursor and objectAtCursor() == null)
 		return;
 
-	LDObject* newObject;
+	LDObject* newObject = nullptr;
 	LDObject* oldObject = objectAtCursor();
 	qint32 newIndex;
 
@@ -1579,7 +1579,7 @@
 	{
 		QString primName = static_cast<SubfileListItem*> (g_win->getPrimitivesTree()->currentItem())->primitive()->name;
 		LDSubfile* ref = LDSpawn<LDSubfile>();
-		ref->setColor (MainColor());
+		ref->setColor (MainColor);
 		ref->setFileInfo (GetDocument (primName));
 		ref->setPosition (Origin);
 		ref->setTransform (IdentityMatrix);
--- a/src/ldConfig.cc	Sat Aug 22 15:58:50 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*
- *  LDForge: LDraw parts authoring CAD
- *  Copyright (C) 2013, 2014 Teemu Piippo
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <QFile>
-#include "ldDocument.h"
-#include "ldConfig.h"
-#include "mainWindow.h"
-#include "miscallenous.h"
-#include "colors.h"
-
-// =============================================================================
-//
-// Helper function for parseLDConfig
-//
-static bool ParseLDConfigTag (LDConfigParser& pars, char const* tag, QString& val)
-{
-	int pos;
-
-	// Try find the token and get its position
-	if (not pars.findToken (pos, tag, 1))
-		return false;
-
-	// Get the token after it and store it into val
-	return pars.getToken (val, pos + 1);
-}
-
-// =============================================================================
-//
-void LDConfigParser::parseLDConfig()
-{
-	QFile* fp = OpenLDrawFile ("LDConfig.ldr", false);
-
-	if (fp == null)
-	{
-		Critical (QObject::tr ("Unable to open LDConfig.ldr for parsing."));
-		return;
-	}
-
-	// Read in the lines
-	while (not fp->atEnd())
-	{
-		QString line = QString::fromUtf8 (fp->readLine());
-
-		if (line.isEmpty() or line[0] != '0')
-			continue; // empty or illogical
-
-		line.remove ('\r');
-		line.remove ('\n');
-
-		// Parse the line
-		LDConfigParser pars (line, ' ');
-
-		int code = 0, alpha = 255;
-		QString name, facename, edgename, valuestr;
-
-		// Check 0 !COLOUR, parse the name
-		if (not pars.tokenCompare (0, "0") or
-			not pars.tokenCompare (1, "!COLOUR") or
-			not pars.getToken (name, 2))
-		{
-			continue;
-		}
-
-		// Replace underscores in the name with spaces for readability
-		name.replace ("_", " ");
-
-		// Get the CODE tag
-		if (not ParseLDConfigTag (pars, "CODE", valuestr))
-			continue;
-
-		// Ensure that the code is within [0 - 511]
-		bool ok;
-		code = valuestr.toShort (&ok);
-
-		if (not ok or code < 0 or code >= 512)
-			continue;
-
-		// VALUE and EDGE tags
-		if (not ParseLDConfigTag (pars, "VALUE", facename) or not ParseLDConfigTag (pars, "EDGE", edgename))
-			continue;
-
-		// Ensure that our colors are correct
-		QColor faceColor (facename),
-			edgeColor (edgename);
-
-		if (not faceColor.isValid() or not edgeColor.isValid())
-			continue;
-
-		// Parse alpha if given.
-		if (ParseLDConfigTag (pars, "ALPHA", valuestr))
-			alpha = Clamp (valuestr.toInt(), 0, 255);
-
-		LDColorData* col = new LDColorData;
-		col->m_name = name;
-		col->m_faceColor = faceColor;
-		col->m_edgeColor = edgeColor;
-		col->m_hexcode = facename;
-		col->m_faceColor.setAlpha (alpha);
-		col->m_index = code;
-		LDColor::addLDConfigColor (code, LDColor (col));
-	}
-
-	fp->close();
-	fp->deleteLater();
-}
-
-// =============================================================================
-//
-LDConfigParser::LDConfigParser (QString inText, char sep)
-{
-	m_tokens = inText.split (sep, QString::SkipEmptyParts);
-	m_pos = -1;
-}
-
-// =============================================================================
-//
-bool LDConfigParser::isAtBeginning()
-{
-	return m_pos == -1;
-}
-
-// =============================================================================
-//
-bool LDConfigParser::isAtEnd()
-{
-	return m_pos == m_tokens.size() - 1;
-}
-
-// =============================================================================
-//
-bool LDConfigParser::getToken (QString& val, const int pos)
-{
-	if (pos >= m_tokens.size())
-		return false;
-
-	val = m_tokens[pos];
-	return true;
-}
-
-// =============================================================================
-//
-bool LDConfigParser::getNextToken (QString& val)
-{
-	return getToken (val, ++m_pos);
-}
-
-// =============================================================================
-//
-bool LDConfigParser::peekNextToken (QString& val)
-{
-	return getToken (val, m_pos + 1);
-}
-
-// =============================================================================
-//
-bool LDConfigParser::findToken (int& result, char const* needle, int args)
-{
-	for (int i = 0; i < (m_tokens.size() - args); ++i)
-	{
-		if (m_tokens[i] == needle)
-		{
-			result = i;
-			return true;
-		}
-	}
-
-	return false;
-}
-
-// =============================================================================
-//
-void LDConfigParser::rewind()
-{
-	m_pos = -1;
-}
-
-// =============================================================================
-//
-void LDConfigParser::seek (int amount, bool rel)
-{
-	m_pos = (rel ? m_pos : 0) + amount;
-}
-
-// =============================================================================
-//
-int LDConfigParser::getSize()
-{
-	return m_tokens.size();
-}
-
-// =============================================================================
-//
-bool LDConfigParser::tokenCompare (int inPos, const char* sOther)
-{
-	QString tok;
-
-	if (not getToken (tok, inPos))
-		return false;
-
-	return (tok == sOther);
-}
--- a/src/ldConfig.h	Sat Aug 22 15:58:50 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- *  LDForge: LDraw parts authoring CAD
- *  Copyright (C) 2013, 2014 Teemu Piippo
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-#include "basics.h"
-#include <QStringList>
-
-// ============================================================================
-//
-// String parsing utility for parsing ldconfig.ldr
-//
-class LDConfigParser
-{
-public:
-	LDConfigParser (QString inText, char sep);
-
-	bool isAtEnd();
-	bool isAtBeginning();
-	bool getNextToken (QString& val);
-	bool peekNextToken (QString& val);
-	bool getToken (QString& val, const int pos);
-	bool findToken (int& result, char const* needle, int args);
-	int getSize();
-	void rewind();
-	void seek (int amount, bool rel);
-	bool tokenCompare (int inPos, const char* sOther);
-
-	inline QString operator[] (const int idx)
-	{
-		return m_tokens[idx];
-	}
-
-	static void parseLDConfig();
-
-private:
-	QStringList m_tokens;
-	int m_pos;
-};
--- a/src/ldDocument.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/ldDocument.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -126,30 +126,26 @@
 
 // =============================================================================
 //
-LDDocument::LDDocument (LDDocument** selfptr) :
+LDDocument::LDDocument() :
 	m_isImplicit (true),
 	m_flags (0),
 	m_verticesOutdated (true),
 	m_needVertexMerge (true),
 	m_gldata (new LDGLData)
 {
-	*selfptr = LDDocument* (this);
-	setSelf (*selfptr);
 	setSavePosition (-1);
 	setTabIndex (-1);
 	setHistory (new History);
-	history()->setDocument (*selfptr);
+	history()->setDocument (this);
 	m_needsReCache = true;
-	g_allDocuments << *selfptr;
+	g_allDocuments << this;
 }
 
 // =============================================================================
 //
 LDDocument* LDDocument::createNew()
 {
-	LDDocument* ptr;
-	new LDDocument (&ptr);
-	return ptr;
+	return new LDDocument();
 }
 
 // =============================================================================
@@ -221,8 +217,6 @@
 		if (file == null)
 			continue;
 
-		LDDocument* file (file);
-
 		if (Eq (name, file->name(), file->defaultName()))
 			return file;
 	}
@@ -685,8 +679,8 @@
 void OpenMainModel (QString path)
 {
 	// If there's already a file with the same name, this file must replace it.
-	LDDocument* documentToReplace;
-	LDDocument* file;
+	LDDocument* documentToReplace = nullptr;
+	LDDocument* file = nullptr;
 	QString shortName = LDDocument::shortenName (path);
 
 	for (LDDocument* doc : g_allDocuments)
@@ -748,7 +742,7 @@
 
 	for (LDObject* obj : file->objects())
 	{
-		if (obj->type() != OBJ_Error or static_cast<LDError*> (obj)->fileReferenced().isEmpty(j)
+		if (obj->type() != OBJ_Error or static_cast<LDError*> (obj)->fileReferenced().isEmpty())
 			continue;
 
 		unknowns << static_cast<LDError*> (obj)->fileReferenced();
@@ -965,7 +959,7 @@
 						CheckTokenNumbers (tokens, 3, 6);
 
 						LDVertex* obj = LDSpawn<LDVertex>();
-						obj->setColor (LDColor::fromIndex (StringToNumber (tokens[3])));
+						obj->setColor (StringToNumber (tokens[3]));
 						obj->pos.apply ([&](Axis ax, double& value)
 							{ value = tokens[4 + ax].toDouble(); });
 						return obj;
@@ -1015,7 +1009,7 @@
 				}
 
 				LDSubfile* obj = LDSpawn<LDSubfile>();
-				obj->setColor (LDColor::fromIndex (StringToNumber (tokens[1])));
+				obj->setColor (StringToNumber (tokens[1]));
 				obj->setPosition (ParseVertex (tokens, 2));  // 2 - 4
 
 				Matrix transform;
@@ -1035,7 +1029,7 @@
 
 				// Line
 				LDLine* obj (LDSpawn<LDLine>());
-				obj->setColor (LDColor::fromIndex (StringToNumber (tokens[1])));
+				obj->setColor (StringToNumber (tokens[1]));
 
 				for (int i = 0; i < 2; ++i)
 					obj->setVertex (i, ParseVertex (tokens, 2 + (i * 3)));   // 2 - 7
@@ -1050,7 +1044,7 @@
 
 				// Triangle
 				LDTriangle* obj (LDSpawn<LDTriangle>());
-				obj->setColor (LDColor::fromIndex (StringToNumber (tokens[1])));
+				obj->setColor (StringToNumber (tokens[1]));
 
 				for (int i = 0; i < 3; ++i)
 					obj->setVertex (i, ParseVertex (tokens, 2 + (i * 3)));   // 2 - 10
@@ -1072,7 +1066,7 @@
 				else
 					obj = LDSpawn<LDCondLine>();
 
-				obj->setColor (LDColor::fromIndex (StringToNumber (tokens[1])));
+				obj->setColor (StringToNumber (tokens[1]));
 
 				for (int i = 0; i < 4; ++i)
 					obj->setVertex (i, ParseVertex (tokens, 2 + (i * 3)));   // 2 - 13
--- a/src/ldDocument.h	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/ldDocument.h	Sat Aug 22 18:10:28 2015 +0300
@@ -74,7 +74,6 @@
 	PROPERTY (public,	int,				tabIndex,		setTabIndex,		STOCK_WRITE)
 	PROPERTY (public,	QList<LDPolygon>,	polygonData,	setPolygonData,		STOCK_WRITE)
 	PROPERTY (private,	LDDocumentFlags,	flags,			setFlags,			STOCK_WRITE)
-	PROPERTY (private,	LDDocument*,	self,			setSelf,			STOCK_WRITE)
 
 	QMap<LDObject*, QVector<Vertex>> m_objectVertices;
 	QVector<Vertex> m_vertices;
@@ -82,7 +81,7 @@
 	bool m_needVertexMerge;
 
 public:
-	LDDocument(LDDocument** selfptr);
+	LDDocument();
 	~LDDocument();
 
 	int addObject (LDObject* obj); // Adds an object to this file at the end of the file.
--- a/src/ldObject.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/ldObject.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -47,7 +47,6 @@
 LDObject::LDObject (LDDocument* document) :
 	m_isHidden (false),
 	m_isSelected (false),
-	m_isDestructed (false),
 	qObjListEntry (null)
 {
 	if (document)
@@ -87,11 +86,11 @@
 
 		// If this object was associated to a file, remove it off it now
 		if (document() != null)
-			document()->forgetObject (self());
+			document()->forgetObject (this);
 
 		// Delete the GL lists
 		if (g_win != null)
-			g_win->R()->forgetObject (self());
+			g_win->R()->forgetObject (this);
 
 		// Remove this object from the list of LDObjects
 		g_allObjects.erase (g_allObjects.find (id()));
@@ -268,7 +267,7 @@
 void LDObject::swap (LDObject* other)
 {
 	assert (document() == other->document());
-	document()->swapObjects (self(), other);
+	document()->swapObjects (this, other);
 }
 
 // =============================================================================
@@ -314,10 +313,6 @@
 
 // =============================================================================
 //
-LDObject::~LDObject() {}
-
-// =============================================================================
-//
 void LDObject::destroy()
 {
 	delete this;
@@ -325,7 +320,7 @@
 
 // =============================================================================
 //
-void LDObject::setDocument (LDDocument* a)
+void LDObject::setDocument (LDDocument* const& a)
 {
 	m_document = a;
 
@@ -366,7 +361,7 @@
 		break;
 	}
 
-	if (obj->color() == MainColor())
+	if (obj->color() == MainColor)
 		obj->setColor (parentcolor);
 }
 
@@ -381,7 +376,7 @@
 	{
 		// assert (obj->type() != OBJ_Subfile);
 		// Set the parent now so we know what inlined the object.
-		obj->setParent (self());
+		obj->setParent (this);
 		TransformObject (obj, transform(), position(), color());
 	}
 
@@ -537,7 +532,7 @@
 {
 	LDObject* it;
 	
-	for (it = self(); it->parent(); it = it->parent())
+	for (it = this; it->parent(); it = it->parent())
 		;
 
 	return it;
@@ -596,7 +591,7 @@
 	else if (type() == OBJ_Vertex)
 	{
 		// ugh
-		static_cast<LDVertex*> (self)->pos += vect;
+		static_cast<LDVertex*> (this)->pos += vect;
 	}
 	else
 	{
@@ -726,7 +721,7 @@
 	}
 
 	// Not inverted, thus prefix it with a new invertnext.
-	document->insertObj (idx, new LDBFC (BFCStatement::InvertNext));
+	document()->insertObj (idx, new LDBFC (BFCStatement::InvertNext));
 }
 
 // =============================================================================
@@ -824,7 +819,7 @@
 //
 void LDObject::setColor (LDColor const& val)
 {
-	changeProperty (self(), &m_color, val);
+	changeProperty (this, &m_color, val);
 }
 
 // =============================================================================
@@ -838,21 +833,21 @@
 //
 void LDObject::setVertex (int i, const Vertex& vert)
 {
-	changeProperty (self(), &m_coords[i], vert);
+	changeProperty (this, &m_coords[i], vert);
 }
 
 // =============================================================================
 //
 void LDMatrixObject::setPosition (const Vertex& a)
 {
-	changeProperty (self(), &m_position, a);
+	changeProperty (this, &m_position, a);
 }
 
 // =============================================================================
 //
 void LDMatrixObject::setTransform (const Matrix& val)
 {
-	changeProperty (self(), &m_transform, val);
+	changeProperty (this, &m_transform, val);
 }
 
 // =============================================================================
@@ -860,7 +855,7 @@
 void LDObject::select()
 {
 	if (document() != null)
-		document()->addToSelection (self());
+		document()->addToSelection (this);
 }
 
 // =============================================================================
@@ -869,7 +864,7 @@
 {
 	if (document() != null)
 	{
-		document()->removeFromSelection (self());
+		document()->removeFromSelection (this);
 
 		// If this object is inverted with INVERTNEXT, deselect the INVERTNEXT as well.
 		LDBFC* invertnext;
@@ -896,9 +891,9 @@
 
 // =============================================================================
 //
-void LDSubfile::setFileInfo (const LDDocument*& a)
+void LDSubfile::setFileInfo (LDDocument* const& a)
 {
-	changeProperty (self(), &m_fileInfo, a);
+	changeProperty (this, &m_fileInfo, a);
 
 	// If it's an immediate subfile reference (i.e. this subfile belongs in an
 	// explicit file), we need to pre-compile the GL polygons for the document
--- a/src/ldObject.h	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/ldObject.h	Sat Aug 22 18:10:28 2015 +0300
@@ -26,7 +26,7 @@
 #define LDOBJ(T)												\
 public:															\
 	static constexpr LDObjectType SubclassType = OBJ_##T;		\
-	LD##T (LDObject** selfptr);								\
+	LD##T (LDDocument* document = nullptr);						\
 																\
 	virtual LDObjectType type() const override					\
 	{															\
@@ -40,7 +40,7 @@
 #define LDOBJ_VERTICES(V)      public: virtual int numVertices() const override { return V; }
 #define LDOBJ_SETCOLORED(V)    public: virtual bool isColored() const override { return V; }
 #define LDOBJ_COLORED          LDOBJ_SETCOLORED (true)
-#define LDOBJ_UNCOLORED        LDOBJ_SETCOLORED (false) LDOBJ_DEFAULTCOLOR (MainColor())
+#define LDOBJ_UNCOLORED        LDOBJ_SETCOLORED (false) LDOBJ_DEFAULTCOLOR (MainColor)
 #define LDOBJ_DEFAULTCOLOR(V)  public: virtual LDColor defaultColor() const override { return (V); }
 
 #define LDOBJ_CUSTOM_SCEMANTIC public: virtual bool isScemantic() const override
@@ -97,7 +97,6 @@
 	PROPERTY (private,		int32,				id,				setID,			STOCK_WRITE)
 	PROPERTY (public,		LDColor,			color,			setColor,		CUSTOM_WRITE)
 	PROPERTY (private,		QColor,				randomColor,	setRandomColor,	STOCK_WRITE)
-	PROPERTY (private,		LDObject*,	self,			setSelf,		STOCK_WRITE)
 
 public:
 	LDObject (LDDocument* document = nullptr);
@@ -214,22 +213,12 @@
 	// Set default color. Relying on virtual functions, this cannot be done in the c-tor.
 	// TODO: store -1 as the default color
 	if (result->isColored())
-		result->setColor (ptr->defaultColor());
+		result->setColor (result->defaultColor());
 
 	return result;
 }
 
 //
-// Apparently QPointer doesn't implement operator<. This is a problem when
-// some of the code needs to sort and remove duplicates from LDObject lists.
-// Adding a specialized version here:
-//
-inline bool operator< (LDObject* a, LDObject* b)
-{
-	return a.data() < b.data();
-}
-
-//
 //
 // Common code for objects with matrices. This class is multiple-derived in
 // and thus not used directly other than as a common storage point for matrices
@@ -387,7 +376,7 @@
 	LDOBJ_NAME (subfile)
 	LDOBJ_VERTICES (0)
 	LDOBJ_COLORED
-	LDOBJ_DEFAULTCOLOR (MainColor())
+	LDOBJ_DEFAULTCOLOR (MainColor)
 	LDOBJ_SCEMANTIC
 	LDOBJ_HAS_MATRIX
 	PROPERTY (public, LDDocument*, fileInfo, setFileInfo, CUSTOM_WRITE)
@@ -422,7 +411,7 @@
 	LDOBJ_NAME (line)
 	LDOBJ_VERTICES (2)
 	LDOBJ_COLORED
-	LDOBJ_DEFAULTCOLOR (EdgeColor())
+	LDOBJ_DEFAULTCOLOR (EdgeColor)
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 
@@ -441,7 +430,7 @@
 	LDOBJ_NAME (condline)
 	LDOBJ_VERTICES (4)
 	LDOBJ_COLORED
-	LDOBJ_DEFAULTCOLOR (EdgeColor())
+	LDOBJ_DEFAULTCOLOR (EdgeColor)
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 
@@ -463,7 +452,7 @@
 	LDOBJ_NAME (triangle)
 	LDOBJ_VERTICES (3)
 	LDOBJ_COLORED
-	LDOBJ_DEFAULTCOLOR (MainColor())
+	LDOBJ_DEFAULTCOLOR (MainColor)
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 
@@ -483,7 +472,7 @@
 	LDOBJ_NAME (quad)
 	LDOBJ_VERTICES (4)
 	LDOBJ_COLORED
-	LDOBJ_DEFAULTCOLOR (MainColor())
+	LDOBJ_DEFAULTCOLOR (MainColor)
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 
@@ -508,7 +497,7 @@
 	LDOBJ_NAME (vertex)
 	LDOBJ_VERTICES (0) // TODO: move pos to m_vertices[0]
 	LDOBJ_COLORED
-	LDOBJ_DEFAULTCOLOR (MainColor())
+	LDOBJ_DEFAULTCOLOR (MainColor)
 	LDOBJ_NON_SCEMANTIC
 	LDOBJ_NO_MATRIX
 
--- a/src/mainWindow.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/mainWindow.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -209,10 +209,10 @@
 			colors << LDQuickColor::getSeparator();
 		else
 		{
-			LDColor col = LDColor::fromIndex (colorname.toLong());
+			LDColor color = colorname.toInt();
 
-			if (col != null)
-				colors << LDQuickColor (col, null);
+			if (color.isValid())
+				colors << LDQuickColor (color, null);
 		}
 	}
 
@@ -431,11 +431,10 @@
 			item->setBackground (QColor ("#AA0000"));
 			item->setForeground (QColor ("#FFAA00"));
 		}
-		elif (cfg::ColorizeObjectsList and obj->isColored() and
-			obj->color() != null and obj->color() != MainColor() and obj->color() != EdgeColor())
+		else if (cfg::ColorizeObjectsList and obj->isColored() and
+			obj->color().isValid() and obj->color() != MainColor and obj->color() != EdgeColor)
 		{
-			// If the object isn't in the main or edge color, draw this
-			// list entry in said color.
+			// If the object isn't in the main or edge color, draw this list entry in that color.
 			item->setForeground (obj->color().faceColor());
 		}
 
@@ -511,18 +510,18 @@
 void MainWindow::slot_quickColor()
 {
 	QToolButton* button = static_cast<QToolButton*> (sender());
-	LDColor col = null;
+	LDColor color = LDColor::nullColor();
 
 	for (const LDQuickColor& entry : m_quickColors)
 	{
 		if (entry.toolButton() == button)
 		{
-			col = entry.color();
+			color = entry.color();
 			break;
 		}
 	}
 
-	if (col == null)
+	if (not color.isValid())
 		return;
 
 	for (LDObject* obj : Selection())
@@ -530,7 +529,7 @@
 		if (not obj->isColored())
 			continue; // uncolored object
 
-		obj->setColor (col);
+		obj->setColor (color);
 		R()->compileObject (obj);
 	}
 
@@ -618,12 +617,12 @@
 	for (LDObject* obj : Selection())
 	{
 		if (not obj->isColored())
-			continue; // doesn't use color
+			continue; // This one doesn't use color so it doesn't have a say
 
-		if (result != null and obj->color() != result)
-			return null; // No consensus in object color
+		if (result.isValid() and obj->color() != result)
+			return LDColor::nullColor(); // No consensus in object color
 
-		if (result == null)
+		if (not result.isValid())
 			result = obj->color();
 	}
 
@@ -873,7 +872,7 @@
 	QPainter paint (&img);
 	QColor col = colinfo.faceColor();
 
-	if (colinfo == MainColor())
+	if (colinfo == MainColor)
 	{
 		// Use the user preferences for main color here
 		col = cfg::MainColor;
@@ -899,7 +898,7 @@
 
 	for (LDObject* obj : CurrentDocument()->objects())
 	{
-		if (not obj->isColored() or obj->color() == null)
+		if (not obj->isColored() or not obj->color().isValid())
 			continue;
 
 		if (counts.find (obj->color()) == counts.end())
@@ -980,7 +979,7 @@
 	if (m_updatingTabs)
 		return;
 
-	LDDocument* f;
+	LDDocument* file = nullptr;
 	int tabIndex = m_tabs->currentIndex();
 
 	// Find the file pointer of the item that was selected.
@@ -988,17 +987,17 @@
 	{
 		if (it->tabIndex() == tabIndex)
 		{
-			f = it;
+			file = it;
 			break;
 		}
 	}
 
 	// If we picked the same file we're currently on, we don't need to do
 	// anything.
-	if (f == null or f == CurrentDocument())
+	if (file == null or file == CurrentDocument())
 		return;
 
-	LDDocument::setCurrent (f);
+	LDDocument::setCurrent (file);
 }
 
 // =============================================================================
@@ -1160,14 +1159,14 @@
 //
 LDQuickColor LDQuickColor::getSeparator()
 {
-	return LDQuickColor (null, null);
+	return LDQuickColor (LDColor::nullColor(), null);
 }
 
 // =============================================================================
 //
 bool LDQuickColor::isSeparator() const
 {
-	return color() == null;
+	return color() == LDColor::nullColor();
 }
 
 void PopulatePrimitives (QTreeWidget* tw, QString const& selectByDefault)
--- a/src/mainWindow.h	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/mainWindow.h	Sat Aug 22 18:10:28 2015 +0300
@@ -29,7 +29,6 @@
 
 class MessageManager;
 class MainWindow;
-class LDColorData;
 class QToolButton;
 class QDialogButtonBox;
 class GLRenderer;
--- a/src/primitives.cc	Sat Aug 22 15:58:50 2015 +0300
+++ b/src/primitives.cc	Sat Aug 22 18:10:28 2015 +0300
@@ -420,7 +420,7 @@
 				LDLine* line (LDSpawn<LDLine>());
 				line->setVertex (0, v0);
 				line->setVertex (1, v1);
-				line->setColor (EdgeColor());
+				line->setColor (EdgeColor);
 				objs << line;
 			} break;
 
@@ -468,7 +468,7 @@
 					   v3 (x3, y3, z3);
 
 				LDQuad* quad (LDSpawn<LDQuad> (v0, v1, v2, v3));
-				quad->setColor (MainColor());
+				quad->setColor (MainColor);
 
 				if (type == Cylinder)
 					quad->invert();
@@ -499,7 +499,7 @@
 				// Disc negatives need to go the other way around, otherwise
 				// they'll end up upside-down.
 				LDTriangle* seg (LDSpawn<LDTriangle>());
-				seg->setColor (MainColor());
+				seg->setColor (MainColor);
 				seg->setVertex (type == Disc ? 0 : 2, v0);
 				seg->setVertex (1, v1);
 				seg->setVertex (type == Disc ? 2 : 0, v2);
@@ -533,7 +533,7 @@
 		}
 
 		LDCondLine* line = (LDSpawn<LDCondLine>());
-		line->setColor (EdgeColor());
+		line->setColor (EdgeColor);
 		line->setVertex (0, v0);
 		line->setVertex (1, v1);
 		line->setVertex (2, v2);

mercurial