- upgraded the PROPERTY macro, resulting in a major code refactor

Thu, 05 Dec 2013 23:20:50 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Thu, 05 Dec 2013 23:20:50 +0200
changeset 539
72ad83a67165
parent 538
2f85d4d286e5
child 540
0334789cb4d7

- upgraded the PROPERTY macro, resulting in a major code refactor

ldforge.pro file | annotate | diff | comparison | revisions
src/addObjectDialog.cpp file | annotate | diff | comparison | revisions
src/colorSelectDialog.cpp file | annotate | diff | comparison | revisions
src/colorSelectDialog.h file | annotate | diff | comparison | revisions
src/common.h file | annotate | diff | comparison | revisions
src/config.cpp file | annotate | diff | comparison | revisions
src/config.h file | annotate | diff | comparison | revisions
src/configDialog.cpp file | annotate | diff | comparison | revisions
src/configDialog.h file | annotate | diff | comparison | revisions
src/dialogs.cpp file | annotate | diff | comparison | revisions
src/dialogs.h file | annotate | diff | comparison | revisions
src/download.cpp file | annotate | diff | comparison | revisions
src/download.h file | annotate | diff | comparison | revisions
src/extprogs.cpp file | annotate | diff | comparison | revisions
src/file.cpp file | annotate | diff | comparison | revisions
src/file.h file | annotate | diff | comparison | revisions
src/gldraw.cpp file | annotate | diff | comparison | revisions
src/gldraw.h file | annotate | diff | comparison | revisions
src/gui.cpp file | annotate | diff | comparison | revisions
src/gui.h file | annotate | diff | comparison | revisions
src/gui_actions.cpp file | annotate | diff | comparison | revisions
src/gui_editactions.cpp file | annotate | diff | comparison | revisions
src/history.cpp file | annotate | diff | comparison | revisions
src/history.h file | annotate | diff | comparison | revisions
src/ldtypes.cpp file | annotate | diff | comparison | revisions
src/ldtypes.h file | annotate | diff | comparison | revisions
src/messagelog.cpp file | annotate | diff | comparison | revisions
src/messagelog.h file | annotate | diff | comparison | revisions
src/misc.h file | annotate | diff | comparison | revisions
src/primitives.cpp file | annotate | diff | comparison | revisions
src/primitives.h file | annotate | diff | comparison | revisions
src/types.cpp file | annotate | diff | comparison | revisions
src/types.h file | annotate | diff | comparison | revisions
--- a/ldforge.pro	Thu Dec 05 13:51:52 2013 +0200
+++ b/ldforge.pro	Thu Dec 05 23:20:50 2013 +0200
@@ -8,13 +8,13 @@
 
 TARGET          = ldforge
 DEPENDPATH     += .
-INCLUDEPATH    += . ./build/
+INCLUDEPATH    += . ./build_shared/
 RC_FILE         = ldforge.rc
 RESOURCES       = ldforge.qrc
-RCC_DIR         = ./build/
-MOC_DIR         = ./build/
-RCC_DIR         = ./build/
-UI_DIR          = ./build/
+RCC_DIR         = ./build_shared/
+MOC_DIR         = ./build_shared/
+RCC_DIR         = ./build_shared/
+UI_DIR          = ./build_shared/
 SOURCES         = src/*.cpp
 HEADERS         = src/*.h
 FORMS           = ui/*.ui
--- a/src/addObjectDialog.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/addObjectDialog.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -39,18 +39,22 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 class SubfileListItem : public QTreeWidgetItem
-{	PROPERTY (Primitive*, primInfo, setPrimInfo)
+{	PROPERTY (public,	Primitive*,	PrimitiveInfo, NO_OPS,	NO_CB)
 
 	public:
 		SubfileListItem (QTreeWidgetItem* parent, Primitive* info) :
-			QTreeWidgetItem (parent), m_primInfo (info) {}
+			QTreeWidgetItem (parent),
+			m_PrimitiveInfo (info) {}
+
 		SubfileListItem (QTreeWidget* parent, Primitive* info) :
-			QTreeWidgetItem (parent), m_primInfo (info) {}
+			QTreeWidgetItem (parent),
+			m_PrimitiveInfo (info) {}
 };
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-AddObjectDialog::AddObjectDialog (const LDObject::Type type, LDObject* obj, QWidget* parent) : QDialog (parent)
+AddObjectDialog::AddObjectDialog (const LDObject::Type type, LDObject* obj, QWidget* parent) :
+	QDialog (parent)
 {	setlocale (LC_ALL, "C");
 
 	int coordCount = 0;
@@ -112,7 +116,7 @@
 
 		for (PrimitiveCategory & cat : g_PrimitiveCategories)
 			{	SubfileListItem* parentItem = new SubfileListItem (tw_subfileList, null);
-				parentItem->setText (0, cat.name());
+				parentItem->setText (0, cat.getName());
 				QList<QTreeWidgetItem*> subfileItems;
 
 			for (Primitive & prim : cat.prims)
@@ -122,7 +126,7 @@
 
 					// If this primitive is the one the current object points to,
 					// select it by default
-					if (obj && static_cast<LDSubfile*> (obj)->fileInfo()->name() == prim.name)
+					if (obj && static_cast<LDSubfile*> (obj)->getFileInfo()->getName() == prim.name)
 						tw_subfileList->setCurrentItem (item);
 				}
 
@@ -136,7 +140,7 @@
 
 			if (obj)
 			{	LDSubfile* ref = static_cast<LDSubfile*> (obj);
-				le_subfileName->setText (ref->fileInfo()->name());
+				le_subfileName->setText (ref->getFileInfo()->getName());
 			}
 
 			break;
@@ -155,7 +159,7 @@
 	// Show a color edit dialog for the types that actually use the color
 	if (defaults->isColored())
 	{	if (obj != null)
-			colnum = obj->color();
+			colnum = obj->getColor();
 		else
 			colnum = (type == LDObject::CndLine || type == LDObject::Line) ? edgecolor : maincolor;
 
@@ -219,7 +223,7 @@
 		{	for (const Axis ax : g_Axes)
 				dsb_coords[ax]->setValue (mo->position() [ax]);
 
-			defaultMatrix = mo->transform();
+			defaultMatrix = mo->getTransform();
 		}
 
 		le_matrix->setText (defaultMatrix.stringRep());
@@ -267,10 +271,10 @@
 str AddObjectDialog::currentSubfileName()
 {	SubfileListItem* item = static_cast<SubfileListItem*> (tw_subfileList->currentItem());
 
-	if (item->primInfo() == null)
+	if (item->getPrimitiveInfo() == null)
 		return ""; // selected a heading
 
-	return item->primInfo()->name;
+	return item->getPrimitiveInfo()->name;
 }
 
 // =============================================================================
--- a/src/colorSelectDialog.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/colorSelectDialog.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -111,7 +111,7 @@
 		numtext->setDefaultTextColor ( (luma (col) < 80) ? Qt::white : Qt::black);
 		numtext->setPos (x, y);
 
-		if (sel() && i == sel()->index)
+		if (getSelection() && i == getSelection()->index)
 		{	auto curspic = m_scene->addPixmap (getIcon ("colorcursor"));
 			curspic->setPos (x, y);
 		}
@@ -133,12 +133,12 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void ColorSelector::drawColorInfo()
-{	if (!sel())
+{	if (!getSelection())
 	{	ui->colorLabel->setText ("---");
 		return;
 	}
 
-	ui->colorLabel->setText (fmt ("%1 - %2", sel()->index, sel()->name));
+	ui->colorLabel->setText (fmt ("%1 - %2", getSelection()->index, getSelection()->name));
 }
 
 // =============================================================================
@@ -150,8 +150,8 @@
 	if (m_firstResize)
 	{	int visibleColors = (ui->viewport->height() / g_squareSize) * g_numColumns;
 
-		if (sel() && sel()->index >= visibleColors)
-		{	int y = (sel()->index / g_numColumns) * g_squareSize;
+		if (getSelection() && getSelection()->index >= visibleColors)
+		{	int y = (getSelection()->index / g_numColumns) * g_squareSize;
 			ui->viewport->verticalScrollBar()->setValue (y);
 		}
 
@@ -186,8 +186,8 @@
 bool ColorSelector::selectColor (int& val, int defval, QWidget* parent)
 {	ColorSelector dlg (defval, parent);
 
-	if (dlg.exec() && dlg.sel() != null)
-	{	val = dlg.sel()->index;
+	if (dlg.exec() && dlg.getSelection() != null)
+	{	val = dlg.getSelection()->index;
 		return true;
 	}
 
--- a/src/colorSelectDialog.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/colorSelectDialog.h	Thu Dec 05 23:20:50 2013 +0200
@@ -28,7 +28,7 @@
 
 class ColorSelector : public QDialog
 {	Q_OBJECT
-	READ_PROPERTY (LDColor*, sel, setSelection)
+	PROPERTY (private,	LDColor*,	Selection,	NO_OPS,	NO_CB)
 
 	public:
 		explicit ColorSelector (int defval = -1, QWidget* parent = null);
--- a/src/common.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/common.h	Thu Dec 05 23:20:50 2013 +0200
@@ -23,6 +23,23 @@
 #ifndef LDFORGE_COMMON_H
 #define LDFORGE_COMMON_H
 
+// Hack to make KDevelop parse QString properly. Q_REQUIRED_RESULT expands into
+// an __attribute__((warn_unused_result)) KDevelop's lexer doesn't seem to
+// understand, yielding an error and leaving some methods unlexed.
+//
+// The following first includes <QChar> to get Q_REQUIRED_RESULT defined first,
+// then re-defining it as nothing. This causes Q_REQUIRED_RESULT to essentially
+// "vanish" from QString's methods when KDevelop lexes them.
+//
+// Similar reasoning for Q_DECL_HIDDEN, except with Q_OBJECT this time.
+#ifdef IN_IDE_PARSER
+# include <QChar>
+# undef Q_REQUIRED_RESULT
+# undef Q_DECL_HIDDEN
+# define Q_REQUIRED_RESULT
+# define Q_DECL_HIDDEN
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -71,58 +88,76 @@
 # define DIRSLASH_CHAR '/'
 #endif // WIN32
 
-#define PROP_NAME(GET) m_##GET
-
-#define READ_ACCESSOR(T, GET) \
-	T const& GET() const
-
-#define SET_ACCESSOR(T, SET) \
-	void SET (T val)
+#define PROPERTY( ACCESS, TYPE, NAME, OPS, CALLBACK )			\
+	private:																	\
+		TYPE m_##NAME;														\
+		DEFINE_##CALLBACK( NAME )										\
+																				\
+	public:																	\
+		inline TYPE const& GET_READ_METHOD( NAME, OPS ) const	\
+		{	return m_##NAME; 												\
+		}																		\
+																				\
+	ACCESS:																	\
+		inline void set##NAME( TYPE const& NAME##_ )				\
+		{	m_##NAME = NAME##_;											\
+			TRIGGER_CALLBACK( NAME, CALLBACK )						\
+		}																		\
+																				\
+		DEFINE_PROPERTY_##OPS( TYPE, NAME, CALLBACK )
 
-// Read-only, private property with a get accessor
-#define DECLARE_READ_PROPERTY(T, GET, SET) \
-private: \
-	T PROP_NAME (GET); \
-	SET_ACCESSOR (T, SET); \
-public: \
-	READ_ACCESSOR (T, GET);
+#define GET_READ_METHOD( NAME, OPS ) \
+	GET_READ_METHOD_##OPS( NAME )
 
-// Read/write private property with get and set accessors
-#define DECLARE_PROPERTY(T, GET, SET) \
-private: \
-	T PROP_NAME (GET); \
-public: \
-	READ_ACCESSOR (T, GET); \
-	SET_ACCESSOR (T, SET);
+#define GET_READ_METHOD_BOOL_OPS( NAME ) is##NAME()
+#define GET_READ_METHOD_NO_OPS( NAME ) get##NAME()
+#define GET_READ_METHOD_STR_OPS( NAME ) get##NAME()
+#define GET_READ_METHOD_NUM_OPS( NAME ) get##NAME()
+
+#define DEFINE_WITH_CB( NAME ) void NAME##Changed();
+#define DEFINE_NO_CB( NAME )
+
+#define DEFINE_PROPERTY_NO_OPS( TYPE, NAME, CALLBACK  )
 
-#define DEFINE_PROPERTY(T, CLASS, GET, SET) \
-	READ_ACCESSOR (T, CLASS::GET) { return PROP_NAME (GET); } \
-	SET_ACCESSOR (T, CLASS::SET) { PROP_NAME (GET) = val; }
-
-// Shortcuts
-#define PROPERTY(T, GET, SET) \
-private: \
-	T PROP_NAME (GET); \
-public: \
-	READ_ACCESSOR (T, GET) { return PROP_NAME (GET); } \
-	SET_ACCESSOR (T, SET) { PROP_NAME (GET) = val; }
+#define DEFINE_PROPERTY_STR_OPS( TYPE, NAME, CALLBACK )	\
+		void append##NAME( TYPE a )								\
+		{	m_##NAME.append( a );									\
+			TRIGGER_CALLBACK( NAME, CALLBACK )					\
+		}																	\
+																			\
+		void prepend##NAME( TYPE a )								\
+		{	m_##NAME.prepend( a );									\
+			TRIGGER_CALLBACK( NAME, CALLBACK )					\
+		}																	\
+																			\
+		void replaceIn##NAME( TYPE a, TYPE b )					\
+		{	m_##NAME.replace( a, b );								\
+			TRIGGER_CALLBACK( NAME, CALLBACK )					\
+		}
 
-#define READ_PROPERTY(T, GET, SET) \
-private: \
-	T PROP_NAME (GET); \
-	SET_ACCESSOR (T, SET) { PROP_NAME (GET) = val; } \
-public: \
-	READ_ACCESSOR (T, GET) { return PROP_NAME (GET); }
+#define DEFINE_PROPERTY_NUM_OPS( TYPE, NAME, CALLBACK )	\
+		inline void increase##NAME( TYPE a = 1 )				\
+		{	m_##NAME += a;												\
+			TRIGGER_CALLBACK( NAME, CALLBACK )					\
+		}																	\
+																			\
+		inline void decrease##NAME( TYPE a = 1 )				\
+		{	m_##NAME -= a;												\
+			TRIGGER_CALLBACK( NAME, CALLBACK )					\
+		}
 
-// Property whose set accessor is a public slot
-// TODO: make this replace PROPERTY
-#define SLOT_PROPERTY (T, GET, SET) \
-private: \
-	T PROP_NAME (GET); \
-public: \
-	READ_ACCESSOR (T, GET) { return PROP_NAME (GET); } \
-public slots: \
-	SET_ACCESSOR (T, SET) { PROP_NAME (GET) = val; }
+#define DEFINE_PROPERTY_BOOL_OPS( TYPE, NAME, CALLBACK )	\
+		inline void toggle##NAME()									\
+		{	m_##NAME = !m_##NAME;									\
+			TRIGGER_CALLBACK( NAME, CALLBACK )					\
+		}
+
+#define TRIGGER_CALLBACK( NAME, CALLBACK ) \
+	TRIGGER_CALLBACK_##CALLBACK( NAME );
+
+#define TRIGGER_CALLBACK_NO_CB( NAME )
+#define TRIGGER_CALLBACK_WITH_CB( NAME ) \
+	NAME##Changed();
 
 #ifdef null
 #undef null
--- a/src/config.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/config.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -17,7 +17,7 @@
  *  =====================================================================
  *
  *  config.cpp: Configuration management. I don't like how unsafe QSettings
- *  is so this implements a type-safer and idenitifer-safer wrapping system of
+ *  is so this implements a type-safer and identifer-safer wrapping system of
  *  configuration variables. QSettings is used underlyingly, this is a matter
  *  of interface.
  */
@@ -32,6 +32,12 @@
 #include "gui.h"
 #include "file.h"
 
+#ifdef _WIN32
+# define EXTENSION ".ini"
+#else
+# define EXTENSION ".cfg"
+#endif // _WIN32
+
 Config* g_configPointers[MAX_CONFIG];
 static int g_cfgPointerCursor = 0;
 
@@ -42,11 +48,6 @@
 static QSettings* getSettingsObject()
 {
 #ifdef PORTABLE
-# ifdef _WIN32
-#  define EXTENSION ".ini"
-# else
-#  define EXTENSION ".cfg"
-# endif // _WIN32
 	return new QSettings (str (APPNAME).toLower() + EXTENSION, QSettings::IniFormat);
 #else
 	return new QSettings;
--- a/src/config.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/config.h	Thu Dec 05 23:20:50 2013 +0200
@@ -19,8 +19,6 @@
 #ifndef LDFORGE_CONFIG_H
 #define LDFORGE_CONFIG_H
 
-#include "common.h"
-
 // =============================================================================
 #include <QString>
 #include <QVariant>
--- a/src/configDialog.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/configDialog.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -376,7 +376,7 @@
 			item->setIcon (getIcon ("empty"));
 		}
 		else
-		{	LDColor* col = entry.color();
+		{	LDColor* col = entry.getColor();
 
 			if (col == null)
 			{	item->setText ("[[unknown color]]");
@@ -419,7 +419,7 @@
 			return; // don't color separators
 	}
 
-	int defval = entry ? entry->color()->index : -1;
+	int defval = entry ? entry->getColor()->index : -1;
 	int val;
 
 	if (ColorSelector::selectColor (val, defval, this) == false)
@@ -576,7 +576,7 @@
 
 	ShortcutListItem* item = sel[0];
 
-	if (KeySequenceDialog::staticDialog (item->keyConfig(), this))
+	if (KeySequenceDialog::staticDialog (item->getKeyConfig(), this))
 		setShortcutText (item);
 }
 
@@ -587,7 +587,7 @@
 {	QList<ShortcutListItem*> sel = getShortcutSelection();
 
 	for (ShortcutListItem* item : sel)
-	{	item->keyConfig()->reset();
+	{	item->getKeyConfig()->reset();
 		setShortcutText (item);
 	}
 }
@@ -599,7 +599,7 @@
 {	QList<ShortcutListItem*> sel = getShortcutSelection();
 
 	for (ShortcutListItem* item : sel)
-	{	item->keyConfig()->value = QKeySequence();
+	{	item->getKeyConfig()->value = QKeySequence();
 		setShortcutText (item);
 	}
 }
@@ -638,9 +638,9 @@
 // Updates the text string for a given shortcut list item
 // -----------------------------------------------------------------------------
 void ConfigDialog::setShortcutText (ShortcutListItem* item)
-{	QAction* act = item->action();
+{	QAction* act = item->getAction();
 	str label = act->iconText();
-	str keybind = item->keyConfig()->value.toString();
+	str keybind = item->getKeyConfig()->value.toString();
 	item->setText (fmt ("%1 (%2)", label, keybind));
 }
 
@@ -657,7 +657,7 @@
 		if (entry.isSeparator())
 			val += '|';
 		else
-			val += fmt ("%1", entry.color()->index);
+			val += fmt ("%1", entry.getColor()->index);
 	}
 
 	return val;
--- a/src/configDialog.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/configDialog.h	Thu Dec 05 23:20:50 2013 +0200
@@ -28,8 +28,8 @@
 
 // =============================================================================
 class ShortcutListItem : public QListWidgetItem
-{	PROPERTY (KeySequenceConfig*, keyConfig, setKeyConfig)
-	PROPERTY (QAction*, action, setAction)
+{	PROPERTY (public,	KeySequenceConfig*,	KeyConfig,	NO_OPS,	NO_CB)
+	PROPERTY (public,	QAction*,				Action,		NO_OPS,	NO_CB)
 
 	public:
 		explicit ShortcutListItem (QListWidget* view = null, int type = Type) :
--- a/src/dialogs.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/dialogs.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -239,7 +239,7 @@
 	ui->setupUi (this);
 	ui->progressText->setText ("Parsing...");
 	setNumLines (0);
-	m_progress = 0;
+	m_Progress = 0;
 }
 
 // =============================================================================
@@ -250,29 +250,22 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-READ_ACCESSOR (int, OpenProgressDialog::numLines)
-{	return m_numLines;
-}
-
-// =============================================================================
-// -----------------------------------------------------------------------------
-SET_ACCESSOR (int, OpenProgressDialog::setNumLines)
-{	m_numLines = val;
-	ui->progressBar->setRange (0, numLines());
+void OpenProgressDialog::NumLinesChanged()
+{	ui->progressBar->setRange (0, getNumLines());
 	updateValues();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void OpenProgressDialog::updateValues()
-{	ui->progressText->setText (fmt ("Parsing... %1 / %2", progress(), numLines()));
-	ui->progressBar->setValue (progress());
+{	ui->progressText->setText (fmt ("Parsing... %1 / %2", getProgress(), getNumLines()));
+	ui->progressBar->setValue (getProgress());
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void OpenProgressDialog::updateProgress (int progress)
-{	m_progress = progress;
+{	setProgress (progress);
 	updateValues();
 }
 
--- a/src/dialogs.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/dialogs.h	Thu Dec 05 23:20:50 2013 +0200
@@ -92,8 +92,8 @@
 // =============================================================================
 class OpenProgressDialog : public QDialog
 {	Q_OBJECT
-	READ_PROPERTY (int, progress, setProgress)
-	DECLARE_PROPERTY (int, numLines, setNumLines)
+	PROPERTY (public,	int, Progress,	NUM_OPS,	NO_CB)
+	PROPERTY (public,	int, NumLines,	NUM_OPS,	WITH_CB)
 
 	public:
 		explicit OpenProgressDialog (QWidget* parent = null, Qt::WindowFlags f = 0);
--- a/src/download.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/download.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -135,7 +135,6 @@
 	{	dest.remove (0, 2);
 		dest.prepend ("parts/s/");
 	} elif (dest.left (3) == "48\\" || dest.left (3) == "48/")
-
 	{	dest.remove (0, 3);
 		dest.prepend ("p/48/");
 	}
@@ -187,14 +186,12 @@
 void PartDownloader::buttonClicked (QAbstractButton* btn)
 {	if (btn == getButton (Close))
 	{	reject();
-	}
-	elif (btn == getButton (Abort))
+	} elif (btn == getButton (Abort))
 	{	setAborted (true);
 
 		for (PartDownloadRequest* req : m_requests)
 			req->abort();
-	}
-	elif (btn == getButton (Download))
+	} elif (btn == getButton (Download))
 	{	str dest = ui->fname->text();
 		setPrimaryFile (null);
 		setAborted (false);
@@ -244,7 +241,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloader::checkIfFinished()
-{	bool failed = aborted();
+{	bool failed = isAborted();
 
 	// If there is some download still working, we're not finished.
 	for (PartDownloadRequest* req : m_requests)
@@ -261,8 +258,8 @@
 	m_requests.clear();
 
 	// Update everything now
-	if (primaryFile())
-	{	LDFile::setCurrent (primaryFile());
+	if (getPrimaryFile())
+	{	LDFile::setCurrent (getPrimaryFile());
 		reloadAllSubfiles();
 		g_win->doFullRefresh();
 		g_win->R()->resetAngles();
@@ -349,11 +346,11 @@
 	switch (m_state)
 	{	case Requesting:
 		case Downloading:
-		{	prog = qobject_cast<QProgressBar*> (table->cellWidget (tableRow(), progcol));
+		{	prog = qobject_cast<QProgressBar*> (table->cellWidget (getTableRow(), progcol));
 
 			if (!prog)
 			{	prog = new QProgressBar;
-				table->setCellWidget (tableRow(), progcol, prog);
+				table->setCellWidget (getTableRow(), progcol, prog);
 			}
 
 			prog->setRange (0, m_bytesTotal);
@@ -365,15 +362,15 @@
 		{	QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" :
 									  "<b><span style=\"color: #800\">FAILED</span></b>");
 			lb->setAlignment (Qt::AlignCenter);
-			table->setCellWidget (tableRow(), progcol, lb);
+			table->setCellWidget (getTableRow(), progcol, lb);
 		} break;
 	}
 
-	QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (tableRow(), labelcol));
+	QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (getTableRow(), labelcol));
 
 	if (m_firstUpdate)
 	{	lb = new QLabel (fmt ("<b>%1</b>", m_dest), table);
-		table->setCellWidget (tableRow(), labelcol, lb);
+		table->setCellWidget (getTableRow(), labelcol, lb);
 	}
 
 	// Make sure that the cell is big enough to contain the label
@@ -387,7 +384,7 @@
 // -----------------------------------------------------------------------------
 void PartDownloadRequest::downloadFinished()
 {	if (m_reply->error() != QNetworkReply::NoError)
-	{	if (m_primary && !m_prompt->aborted())
+	{	if (m_primary && !m_prompt->isAborted())
 			critical (m_reply->errorString());
 
 		m_state = Failed;
@@ -423,13 +420,13 @@
 	// from unknown file references, try resolve that by downloading the reference.
 	// This is why downloading a part may end up downloading multiple files, as
 	// it resolves dependencies.
-	for (LDObject* obj : f->objects())
+	for (LDObject* obj : f->getObjects())
 	{	LDError* err = dynamic_cast<LDError*> (obj);
 
-		if (!err || err->fileRef().isEmpty())
+		if (!err || err->getFileReferenced().isEmpty())
 			continue;
 
-		str dest = err->fileRef();
+		str dest = err->getFileReferenced();
 		m_prompt->modifyDestination (dest);
 		m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false);
 	}
--- a/src/download.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/download.h	Thu Dec 05 23:20:50 2013 +0200
@@ -36,8 +36,8 @@
 // -----------------------------------------------------------------------------
 class PartDownloader : public QDialog
 {	Q_OBJECT
-	PROPERTY (LDFile*, primaryFile, setPrimaryFile)
-	PROPERTY (bool, aborted, setAborted)
+	PROPERTY (public,	LDFile*, PrimaryFile,	NO_OPS,		NO_CB)
+	PROPERTY (public,	bool,		Aborted,			BOOL_OPS,	NO_CB)
 
 	public:
 		constexpr static const char* k_UnofficialURL = "http://ldraw.org/library/unofficial/";
@@ -87,7 +87,7 @@
 // -----------------------------------------------------------------------------
 class PartDownloadRequest : public QObject
 {	Q_OBJECT
-	PROPERTY (int, tableRow, setTableRow)
+	PROPERTY (public,	int, TableRow,	NUM_OPS,	NO_CB)
 
 	public:
 		enum State
--- a/src/extprogs.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/extprogs.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -190,8 +190,8 @@
 void writeColorGroup (const int colnum, str fname)
 {	QList<LDObject*> objects;
 
-	for (LDObject* obj : LDFile::current()->objects())
-	{	if (obj->isColored() == false || obj->color() != colnum)
+	for (LDObject* obj : LDFile::current()->getObjects())
+	{	if (obj->isColored() == false || obj->getColor() != colnum)
 			continue;
 
 		objects << obj;
@@ -404,8 +404,8 @@
 	Ui::IntersectorUI ui;
 	ui.setupUi (dlg);
 
-	makeColorSelector (ui.cmb_incol);
-	makeColorSelector (ui.cmb_cutcol);
+	makeColorComboBox (ui.cmb_incol);
+	makeColorComboBox (ui.cmb_cutcol);
 	ui.cb_repeat->setWhatsThis ("If this is set, " APPNAME " runs Intersector a second time with inverse files to cut the "
 								" cutter group with the input group. Both groups are cut by the intersection.");
 	ui.cb_edges->setWhatsThis ("Makes " APPNAME " try run Isecalc to create edgelines for the intersection.");
@@ -494,8 +494,8 @@
 	QDialog* dlg = new QDialog;
 	Ui::CovererUI ui;
 	ui.setupUi (dlg);
-	makeColorSelector (ui.cmb_col1);
-	makeColorSelector (ui.cmb_col2);
+	makeColorComboBox (ui.cmb_col1);
+	makeColorComboBox (ui.cmb_col2);
 
 	int in1Col, in2Col;
 
@@ -551,8 +551,8 @@
 	QDialog* dlg = new QDialog;
 	ui.setupUi (dlg);
 
-	makeColorSelector (ui.cmb_col1);
-	makeColorSelector (ui.cmb_col2);
+	makeColorComboBox (ui.cmb_col1);
+	makeColorComboBox (ui.cmb_col2);
 
 	int in1Col, in2Col;
 
--- a/src/file.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/file.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -48,8 +48,6 @@
 
 LDFile* LDFile::m_curfile = null;
 
-DEFINE_PROPERTY (QListWidgetItem*, LDFile, listItem, setListItem)
-
 // =============================================================================
 // -----------------------------------------------------------------------------
 namespace LDPaths
@@ -116,22 +114,25 @@
 // -----------------------------------------------------------------------------
 LDFile::LDFile()
 {	setImplicit (true);
-	setSavePos (-1);
+	setSavePosition (-1);
 	setListItem (null);
-	m_history.setFile (this);
+	setHistory (new History);
+	m_History->setFile (this);
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 LDFile::~LDFile()
 {	// Clear everything from the model
-	for (LDObject* obj : objects())
+	for (LDObject* obj : getObjects())
 		delete obj;
 
 	// Clear the cache as well
-	for (LDObject* obj : cache())
+	for (LDObject* obj : getCache())
 		delete obj;
 
+	delete m_History;
+
 	// Remove this file from the list of files
 	g_loadedFiles.removeOne (this);
 
@@ -143,7 +144,7 @@
 		// Try find an explicitly loaded file - if we can't find one,
 		// we need to create a new file to switch to.
 		for (LDFile* file : g_loadedFiles)
-		{	if (!file->implicit())
+		{	if (!file->isImplicit())
 			{	LDFile::setCurrent (file);
 				found = true;
 				break;
@@ -161,7 +162,7 @@
 // -----------------------------------------------------------------------------
 LDFile* findLoadedFile (str name)
 {	for (LDFile * file : g_loadedFiles)
-		if (!file->name().isEmpty() && file->getShortName() == name)
+		if (!file->getName().isEmpty() && file->getShortName() == name)
 			return file;
 
 	return null;
@@ -212,7 +213,7 @@
 	if (LDFile::current())
 	{	// First, try find the file in the current model's file path. We want a file
 		// in the immediate vicinity of the current model to override stock LDraw stuff.
-		str partpath = fmt ("%1" DIRSLASH "%2", dirname (LDFile::current()->name()), relpath);
+		str partpath = fmt ("%1" DIRSLASH "%2", dirname (LDFile::current()->getName()), relpath);
 
 		if (f->open (partpath, File::Read))
 			return f;
@@ -253,7 +254,7 @@
 	setProgress (0);
 	setAborted (false);
 
-	if (concurrent())
+	if (isOnForeground())
 	{	g_aborted = false;
 
 		// Show a progress dialog if we're loading the main file here so we can
@@ -261,7 +262,7 @@
 		// Of course we cannot exec() the dialog because then the dialog would
 		// block.
 		dlg = new OpenProgressDialog (g_win);
-		dlg->setNumLines (lines().size());
+		dlg->setNumLines (getLines().size());
 		dlg->setModal (true);
 		dlg->show();
 
@@ -280,11 +281,11 @@
 // -----------------------------------------------------------------------------
 void FileLoader::work (int i)
 {	// User wishes to abort, so stop here now.
-	if (aborted())
-	{	for (LDObject* obj : m_objs)
+	if (isAborted())
+	{	for (LDObject* obj : m_Objects)
 			delete obj;
 
-		m_objs.clear();
+		m_Objects.clear();
 		setDone (true);
 		return;
 	}
@@ -292,8 +293,8 @@
 	// Parse up to 300 lines per iteration
 	int max = i + 300;
 
-	for (; i < max && i < (int) lines().size(); ++i)
-	{	str line = lines() [i];
+	for (; i < max && i < (int) getLines().size(); ++i)
+	{	str line = getLines()[i];
 
 		// Trim the trailing newline
 		QChar c;
@@ -305,29 +306,29 @@
 
 		// Check for parse errors and warn about tthem
 		if (obj->getType() == LDObject::Error)
-		{	log ("Couldn't parse line #%1: %2", m_progress + 1, static_cast<LDError*> (obj)->reason);
+		{	log ("Couldn't parse line #%1: %2", getProgress() + 1, static_cast<LDError*> (obj)->reason);
 
-			if (m_warningsPointer)
-				(*m_warningsPointer)++;
+			if (getWarnings() != null)
+				(*getWarnings())++;
 		}
 
-		m_objs << obj;
+		m_Objects << obj;
 		setProgress (i);
 
 		// If we have a dialog pointer, update the progress now
-		if (concurrent())
+		if (isOnForeground())
 			dlg->updateProgress (i);
 	}
 
 	// If we're done now, tell the environment we're done and stop.
-	if (i >= ((int) lines().size()) - 1)
+	if (i >= ((int) getLines().size()) - 1)
 	{	emit workDone();
 		setDone (true);
 		return;
 	}
 
 	// Otherwise, continue, by recursing back.
-	if (!done())
+	if (!isDone())
 	{	// If we have a dialog to show progress output to, we cannot just call
 		// work() again immediately as the dialog needs some processor cycles as
 		// well. Thus, take a detour through the event loop by using the
@@ -338,7 +339,7 @@
 		// until we're ready (see loadFileContents), thus the event loop will
 		// eventually catch the invokation we throw here and send us back. Though
 		// it's not technically recursion anymore, more like a for loop. :P
-		if (concurrent())
+		if (isOnForeground())
 			QMetaObject::invokeMethod (this, "work", Qt::QueuedConnection, Q_ARG (int, i));
 		else
 			work (i + 1);
@@ -350,7 +351,7 @@
 void FileLoader::abort()
 {	setAborted (true);
 
-	if (concurrent())
+	if (isOnForeground())
 		g_aborted = true;
 }
 
@@ -370,23 +371,23 @@
 	f->rewind();
 
 	FileLoader* loader = new FileLoader;
-	loader->setWarningsPointer (numWarnings);
+	loader->setWarnings (numWarnings);
 	loader->setLines (lines);
-	loader->setConcurrent (g_loadingMainFile);
+	loader->setOnForeground (g_loadingMainFile);
 	loader->start();
 
 	// After start() returns, if the loader isn't done yet, it's delaying
 	// its next iteration through the event loop. We need to catch this here
 	// by telling the event loop to tick, which will tick the file loader again.
 	// We keep doing this until the file loader is ready.
-	while (loader->done() == false)
+	while (loader->isDone() == false)
 		qApp->processEvents();
 
 	// If we wanted the success value, supply that now
 	if (ok)
-		*ok = !loader->aborted();
+		*ok = !loader->isAborted();
 
-	objs = loader->objs();
+	objs = loader->getObjects();
 	return objs;
 }
 
@@ -446,7 +447,7 @@
 	// If we have unsaved changes, warn and give the option of saving.
 	if (hasUnsavedChanges())
 	{	str message = fmt ("There are unsaved changes to %1. Should it be saved?",
-						   (name().length() > 0) ? name() : "<anonymous>");
+						   (getName().length() > 0) ? getName() : "<anonymous>");
 
 		int button = msgbox::question (g_win, "Unsaved Changes", message,
 									   (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel);
@@ -455,9 +456,9 @@
 		{	case msgbox::Yes:
 
 				// If we don't have a file path yet, we have to ask the user for one.
-				if (name().length() == 0)
+				if (getName().length() == 0)
 				{	str newpath = QFileDialog::getSaveFileName (g_win, "Save As",
-								  LDFile::current()->name(), "LDraw files (*.dat *.ldr)");
+								  LDFile::current()->getName(), "LDraw files (*.dat *.ldr)");
 
 					if (newpath.length() == 0)
 						return false;
@@ -467,7 +468,7 @@
 
 				if (!save())
 				{	message = fmt (QObject::tr ("Failed to save %1: %2\nDo you still want to close?"),
-								   name(), strerror (errno));
+								   getName(), strerror (errno));
 
 					if (msgbox::critical (g_win, "Save Failure", message,
 										  (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No)
@@ -513,7 +514,7 @@
 	g_win->R()->setFile (f);
 	g_win->doFullRefresh();
 	g_win->updateTitle();
-	f->history().updateActions();
+	f->getHistory()->updateActions();
 }
 
 // =============================================================================
@@ -583,7 +584,7 @@
 // -----------------------------------------------------------------------------
 bool LDFile::save (str savepath)
 {	if (!savepath.length())
-		savepath = name();
+		savepath = getName();
 
 	File f (savepath, File::Write);
 
@@ -596,7 +597,7 @@
 	LDComment* fpathComment = null;
 	LDObject* first = getObject (1);
 
-	if (!implicit() && first != null && first->getType() == LDObject::Comment)
+	if (!isImplicit() && first != null && first->getType() == LDObject::Comment)
 	{	fpathComment = static_cast<LDComment*> (first);
 
 		if (fpathComment->text.left (6) == "Name: ")
@@ -614,14 +615,14 @@
 
 	// File is open, now save the model to it. Note that LDraw requires files to
 	// have DOS line endings, so we terminate the lines with \r\n.
-	for (LDObject* obj : objects())
+	for (LDObject* obj : getObjects())
 		f.write (obj->raw() + "\r\n");
 
 	// File is saved, now clean up.
 	f.close();
 
 	// We have successfully saved, update the save position now.
-	setSavePos (history().pos());
+	setSavePosition (getHistory()->getPosition());
 	setName (savepath);
 
 	g_win->updateFileListItem (this);
@@ -721,7 +722,7 @@
 					CHECK_TOKEN_NUMBERS (5, 8)
 
 					LDOverlay* obj = new LDOverlay;
-					obj->setFilename (tokens[3]);
+					obj->setFileName (tokens[3]);
 					obj->setCamera (tokens[4].toLong());
 					obj->setX (tokens[5].toLong());
 					obj->setY (tokens[6].toLong());
@@ -752,7 +753,7 @@
 			// If we cannot open the file, mark it an error
 			if (!load)
 			{	LDError* obj = new LDError (line, fmt ("Could not open %1", tokens[14]));
-				obj->setFileRef (tokens[14]);
+				obj->setFileReferenced (tokens[14]);
 				return obj;
 			}
 
@@ -847,10 +848,10 @@
 	g_loadedFiles << LDFile::current();
 
 	// Go through all objects in the current file and reload the subfiles
-for (LDObject * obj : LDFile::current()->objects())
+	for (LDObject* obj : LDFile::current()->getObjects())
 	{	if (obj->getType() == LDObject::Subfile)
 		{	LDSubfile* ref = static_cast<LDSubfile*> (obj);
-			LDFile* fileInfo = getFile (ref->fileInfo()->name());
+			LDFile* fileInfo = getFile (ref->getFileInfo()->getName());
 
 			if (fileInfo)
 				ref->setFileInfo (fileInfo);
@@ -871,11 +872,11 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 int LDFile::addObject (LDObject* obj)
-{	m_history.add (new AddHistory (objects().size(), obj));
-	m_objects << obj;
+{	getHistory()->add (new AddHistory (getObjects().size(), obj));
+	m_Objects << obj;
 
 	if (obj->getType() == LDObject::Vertex)
-		m_vertices << obj;
+		m_Vertices << obj;
 
 	obj->setFile (this);
 	return getObjectCount() - 1;
@@ -892,8 +893,8 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void LDFile::insertObj (int pos, LDObject* obj)
-{	m_history.add (new AddHistory (pos, obj));
-	m_objects.insert (pos, obj);
+{	getHistory()->add (new AddHistory (pos, obj));
+	m_Objects.insert (pos, obj);
 	obj->setFile (this);
 }
 
@@ -901,8 +902,8 @@
 // -----------------------------------------------------------------------------
 void LDFile::forgetObject (LDObject* obj)
 {	int idx = obj->getIndex();
-	m_history.add (new DelHistory (idx, obj));
-	m_objects.removeAt (idx);
+	getHistory()->add (new DelHistory (idx, obj));
+	m_Objects.removeAt (idx);
 	obj->setFile (null);
 }
 
@@ -919,15 +920,15 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void LDFile::setObject (int idx, LDObject* obj)
-{	assert (idx < m_objects.size());
+{	assert (idx < m_Objects.size());
 
 	// Mark this change to history
 	str oldcode = getObject (idx)->raw();
 	str newcode = obj->raw();
-	m_history << new EditHistory (idx, oldcode, newcode);
+	*m_History << new EditHistory (idx, oldcode, newcode);
 
 	obj->setFile (this);
-	m_objects[idx] = obj;
+	m_Objects[idx] = obj;
 }
 
 // =============================================================================
@@ -935,13 +936,13 @@
 static QList<LDFile*> getFilesUsed (LDFile* node)
 {	QList<LDFile*> filesUsed;
 
-	for (LDObject* obj : node->objects())
+	for (LDObject* obj : node->getObjects())
 	{	if (obj->getType() != LDObject::Subfile)
 			continue;
 
 		LDSubfile* ref = static_cast<LDSubfile*> (obj);
-		filesUsed << ref->fileInfo();
-		filesUsed << getFilesUsed (ref->fileInfo());
+		filesUsed << ref->getFileInfo();
+		filesUsed << getFilesUsed (ref->getFileInfo());
 	}
 
 	return filesUsed;
@@ -955,7 +956,7 @@
 
 	// Anything that's explicitly opened must not be closed
 	for (LDFile* file : g_loadedFiles)
-		if (!file->implicit())
+		if (!file->isImplicit())
 			filesUsed << file;
 
 	// Remove duplicated entries
@@ -983,32 +984,32 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 LDObject* LDFile::getObject (int pos) const
-{	if (m_objects.size() <= pos)
+{	if (m_Objects.size() <= pos)
 		return null;
 
-	return m_objects[pos];
+	return m_Objects[pos];
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 int LDFile::getObjectCount() const
-{	return objects().size();
+{	return getObjects().size();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 bool LDFile::hasUnsavedChanges() const
-{	return !implicit() && history().pos() != savePos();
+{	return !isImplicit() && getHistory()->getPosition() != getSavePosition();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 str LDFile::getShortName()
-{	if (!name().isEmpty())
-		return basename (name());
+{	if (!getName().isEmpty())
+		return basename (getName());
 
-	if (!defaultName().isEmpty())
-		return defaultName();
+	if (!getDefaultName().isEmpty())
+		return getDefaultName();
 
 	return tr ("<anonymous>");
 }
@@ -1020,10 +1021,10 @@
 	// stud.dat -> stud-logo.dat
 	// stud2.dat -> stud-logo2.dat
 	if (gl_logostuds && (flags & LDSubfile::RendererInline))
-	{	if (name() == "stud.dat" && g_logoedStud)
+	{	if (getName() == "stud.dat" && g_logoedStud)
 			return g_logoedStud->inlineContents (flags);
 
-		elif (name() == "stud2.dat" && g_logoedStud2)
+		elif (getName() == "stud2.dat" && g_logoedStud2)
 		return g_logoedStud2->inlineContents (flags);
 	}
 
@@ -1033,15 +1034,15 @@
 		 doCache = flags & LDSubfile::CacheInline;
 
 	// If we have this cached, just clone that
-	if (deep && cache().size())
-{	for (LDObject * obj : cache())
+	if (deep && getCache().size())
+	{	for (LDObject* obj : getCache())
 			objs << obj->clone();
 	}
 	else
 	{	if (!deep)
 			doCache = false;
 
-	for (LDObject * obj : objects())
+		for (LDObject* obj : getObjects())
 		{	// Skip those without scemantic meaning
 			if (!obj->isScemantic())
 				continue;
@@ -1094,7 +1095,7 @@
 void LDFile::setCurrent (LDFile* f)
 {	// Implicit files were loaded for caching purposes and must never be set
 	// current.
-	if (f && f->implicit())
+	if (f && f->isImplicit())
 		return;
 
 	m_curfile = f;
@@ -1118,7 +1119,7 @@
 {	int count = 0;
 
 	for (LDFile* f : g_loadedFiles)
-		if (f->implicit() == false)
+		if (f->isImplicit() == false)
 			count++;
 
 	return count;
@@ -1131,7 +1132,7 @@
 void LDFile::closeInitialFile()
 {	if (
 		countExplicitFiles() == 2 &&
-		g_loadedFiles[0]->name() == "" &&
+		g_loadedFiles[0]->getName() == "" &&
 		!g_loadedFiles[0]->hasUnsavedChanges()
 	)
 		delete g_loadedFiles[0];
@@ -1152,10 +1153,10 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void LDFile::addToSelection (LDObject* obj) // [protected]
-{	if (obj->selected())
+{	if (obj->isSelected())
 		return;
 
-	assert (obj->file() == this);
+	assert (obj->getFile() == this);
 	m_sel << obj;
 	obj->setSelected (true);
 }
@@ -1163,10 +1164,10 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void LDFile::removeFromSelection (LDObject* obj) // [protected]
-{	if (!obj->selected())
+{	if (!obj->isSelected())
 		return;
 
-	assert (obj->file() == this);
+	assert (obj->getFile() == this);
 	m_sel.removeOne (obj);
 	obj->setSelected (false);
 }
--- a/src/file.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/file.h	Thu Dec 05 23:20:50 2013 +0200
@@ -53,15 +53,15 @@
 // =============================================================================
 class LDFile : public QObject
 {	Q_OBJECT
-		READ_PROPERTY (QList<LDObject*>, objects, setObjects)
-		READ_PROPERTY (History, history, setHistory)
-		READ_PROPERTY (QList<LDObject*>, vertices, setVertices)
-		PROPERTY (str, name, setName)
-		PROPERTY (str, defaultName, setDefaultName)
-		PROPERTY (bool, implicit, setImplicit)
-		PROPERTY (QList<LDObject*>, cache, setCache)
-		PROPERTY (long, savePos, setSavePos)
-		DECLARE_PROPERTY (QListWidgetItem*, listItem, setListItem)
+	PROPERTY (private,	QList<LDObject*>,	Objects, 		NO_OPS,		NO_CB)
+	PROPERTY (private,	History*,			History,			NO_OPS,		NO_CB)
+	PROPERTY (private,	QList<LDObject*>,	Vertices,		NO_OPS,		NO_CB)
+	PROPERTY (public,		str,					Name,				STR_OPS,		NO_CB)
+	PROPERTY (public,		str,					DefaultName,	STR_OPS,		NO_CB)
+	PROPERTY (public,		bool,					Implicit,		BOOL_OPS,	NO_CB)
+	PROPERTY (public,		QList<LDObject*>,	Cache,			NO_OPS,		NO_CB)
+	PROPERTY (public,		long,					SavePosition,	NUM_OPS,		NO_CB)
+	PROPERTY (public,		QListWidgetItem*, ListItem,		NO_OPS,		NO_CB)
 
 	public:
 		LDFile();
@@ -87,28 +87,24 @@
 			return *this;
 		}
 
-		inline void openHistory()
-		{	m_history.open();
-		}
-
-		inline void closeHistory()
-		{	m_history.close();
+		inline void addHistoryStep()
+		{	m_History->addStep();
 		}
 
 		inline void undo()
-		{	m_history.undo();
+		{	m_History->undo();
 		}
 
 		inline void redo()
-		{	m_history.redo();
+		{	m_History->redo();
 		}
 
 		inline void clearHistory()
-		{	m_history.clear();
+		{	m_History->clear();
 		}
 
 		inline void addToHistory (AbstractHistoryEntry* entry)
-		{	m_history << entry;
+		{	*m_History << entry;
 		}
 
 		static void closeUnused();
@@ -184,14 +180,14 @@
 // event loop, allowing the program to maintain responsivity during loading.
 // =============================================================================
 class FileLoader : public QObject
-{		Q_OBJECT
-		READ_PROPERTY (QList<LDObject*>, objs, setObjects)
-		READ_PROPERTY (bool, done, setDone)
-		READ_PROPERTY (int, progress, setProgress)
-		READ_PROPERTY (bool, aborted, setAborted)
-		PROPERTY (QList<str>, lines, setLines)
-		PROPERTY (int*, warningsPointer, setWarningsPointer)
-		PROPERTY (bool, concurrent, setConcurrent)
+{	Q_OBJECT
+	PROPERTY (private,	QList<LDObject*>,	Objects,			NO_OPS,		NO_CB)
+	PROPERTY (private,	bool,					Done,				BOOL_OPS,	NO_CB)
+	PROPERTY (private,	int,					Progress,		NUM_OPS,		NO_CB)
+	PROPERTY (private,	bool,					Aborted,			BOOL_OPS,	NO_CB)
+	PROPERTY (public,		QStringList,		Lines,			NO_OPS,		NO_CB)
+	PROPERTY (public,		int*,					Warnings,		NO_OPS,		NO_CB)
+	PROPERTY (public,		bool,					OnForeground,	BOOL_OPS,	NO_CB)
 
 	public slots:
 		void start();
--- a/src/gldraw.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/gldraw.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -102,10 +102,10 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent)
-{	m_picking = m_rangepick = false;
+{	m_Picking = m_rangepick = false;
 	m_camera = (GL::Camera) gl_camera.value;
 	m_drawToolTip = false;
-	m_editMode = Select;
+	m_EditMode = Select;
 	m_rectdraw = false;
 	m_panning = false;
 	setFile (null);
@@ -272,7 +272,7 @@
 		// ID again from the color we get from the picking results. Be sure to use
 		// the top level parent's index since we want a subfile's children point
 		// to the subfile itself.
-		long i = obj->topLevelParent()->id();
+		long i = obj->topLevelParent()->getID();
 
 		// Calculate a color based from this index. This method caters for
 		// 16777216 objects. I don't think that'll be exceeded anytime soon. :)
@@ -285,47 +285,45 @@
 		return;
 	}
 
-	if ( (list == BFCFrontList || list == BFCBackList) &&
-			obj->getType() != LDObject::Line &&
-			obj->getType() != LDObject::CndLine)
-	{
-
-		if (list == GL::BFCFrontList)
+	if ((list == BFCFrontList || list == BFCBackList) &&
+		obj->getType() != LDObject::Line &&
+		obj->getType() != LDObject::CndLine)
+	{	if (list == GL::BFCFrontList)
 			qcol = QColor (40, 192, 0);
 		else
 			qcol = QColor (224, 0, 0);
 	}
 	else
-	{	if (obj->color() == maincolor)
+	{	if (obj->getColor() == maincolor)
 			qcol = getMainColor();
 		else
-		{	LDColor* col = getColor (obj->color());
+		{	LDColor* col = getColor (obj->getColor());
 
 			if (col)
 				qcol = col->faceColor;
 		}
 
-		if (obj->color() == edgecolor)
+		if (obj->getColor() == edgecolor)
 		{	qcol = luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black;
 			LDColor* col;
 
-			if (!gl_blackedges && obj->parent() && (col = getColor (obj->parent()->color())))
+			if (!gl_blackedges && obj->getParent() && (col = getColor (obj->getParent()->getColor())))
 				qcol = col->edgeColor;
 		}
 
 		if (qcol.isValid() == false)
 		{	// The color was unknown. Use main color to make the object at least
 			// not appear pitch-black.
-			if (obj->color() != edgecolor)
+			if (obj->getColor() != edgecolor)
 				qcol = getMainColor();
 
 			// Warn about the unknown colors, but only once.
 			for (int i : g_warnedColors)
-				if (obj->color() == i)
+				if (obj->getColor() == i)
 					return;
 
-			log ("%1: Unknown color %2!\n", __func__, obj->color());
-			g_warnedColors << obj->color();
+			log ("%1: Unknown color %2!\n", __func__, obj->getColor());
+			g_warnedColors << obj->getColor();
 			return;
 		}
 	}
@@ -335,7 +333,7 @@
 		 b = qcol.blue(),
 		 a = qcol.alpha();
 
-	if (obj->topLevelParent()->selected())
+	if (obj->topLevelParent()->isSelected())
 	{	// Brighten it up for the select list.
 		const uchar add = 51;
 
@@ -385,10 +383,10 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void GLRenderer::drawGLScene()
-{	if (file() == null)
+{	if (getFile() == null)
 		return;
 
-	if (gl_wireframe && !picking())
+	if (gl_wireframe && !isPicking())
 		glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
 
 	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -426,13 +424,13 @@
 		glRotatef (rot (Z), 0.0f, 0.0f, 1.0f);
 	}
 
-	const GL::ListType list = (!drawOnly() && m_picking) ? PickList : NormalList;
+	const GL::ListType list = (!isDrawOnly() && isPicking()) ? PickList : NormalList;
 
-	if (gl_colorbfc && !m_picking && !drawOnly())
+	if (gl_colorbfc && !isPicking() && !isDrawOnly())
 	{	glEnable (GL_CULL_FACE);
 
-		for (LDObject* obj : file()->objects())
-		{	if (obj->hidden())
+		for (LDObject* obj : getFile()->getObjects())
+		{	if (obj->isHidden())
 				continue;
 
 			glCullFace (GL_BACK);
@@ -445,15 +443,15 @@
 		glDisable (GL_CULL_FACE);
 	}
 	else
-	{	for (LDObject* obj : file()->objects())
-		{	if (obj->hidden())
+	{	for (LDObject* obj : getFile()->getObjects())
+		{	if (obj->isHidden())
 				continue;
 
 			glCallList (obj->glLists[list]);
 		}
 	}
 
-	if (gl_axes && !m_picking && !drawOnly())
+	if (gl_axes && !isPicking() && !isDrawOnly())
 		glCallList (m_axeslist);
 
 	glPopMatrix();
@@ -545,10 +543,10 @@
 	paint.setRenderHint (QPainter::HighQualityAntialiasing);
 
 	// If we wish to only draw the brick, stop here
-	if (drawOnly())
+	if (isDrawOnly())
 		return;
 
-	if (m_camera != Free && !picking())
+	if (m_camera != Free && !isPicking())
 	{	// Paint the overlay image if we have one
 		const LDGLOverlay& overlay = m_overlays[m_camera];
 
@@ -576,7 +574,7 @@
 		linepen.setColor (luma (m_bgcolor) < 40 ? Qt::white : Qt::black);
 
 		// If we're drawing, draw the vertices onto the screen.
-		if (editMode() == Draw)
+		if (getEditMode() == Draw)
 		{	int numverts = 4;
 
 			if (!m_rectdraw)
@@ -633,7 +631,7 @@
 				}
 			}
 		}
-		elif (editMode() == CircleMode)
+		elif (getEditMode() == CircleMode)
 		{	// If we have not specified the center point of the circle yet, preview it on the screen.
 			if (m_drawedVerts.isEmpty())
 				drawBlip (paint, coordconv3_2 (m_hoverpos));
@@ -719,7 +717,7 @@
 	}
 
 	// Camera icons
-	if (!m_picking)
+	if (!isPicking())
 	{	// Draw a background for the selected camera
 		paint.setPen (m_thinBorderPen);
 		paint.setBrush (QBrush (QColor (0, 128, 160, 128)));
@@ -728,7 +726,7 @@
 		// Draw the actual icons
 		for (CameraIcon& info : m_cameraIcons)
 		{	// Don't draw the free camera icon when in draw mode
-			if (&info == &m_cameraIcons[GL::Free] && editMode() != Select)
+			if (&info == &m_cameraIcons[GL::Free] && getEditMode() != Select)
 				continue;
 
 			paint.drawPixmap (info.destRect, *info.img, info.srcRect);
@@ -757,12 +755,12 @@
 	}
 
 	// Message log
-	if (msglog())
+	if (getMessageLog())
 	{	int y = 0;
 		const int margin = 2;
 		QColor penColor = getTextPen();
 
-		for (const MessageManager::Line& line : msglog()->getLines())
+		for (const MessageManager::Line& line : getMessageLog()->getLines())
 		{	penColor.setAlphaF (line.alpha);
 			paint.setPen (penColor);
 			paint.drawText (QPoint (margin, y + margin + metrics.ascent()), line.text);
@@ -771,7 +769,7 @@
 	}
 
 	// If we're range-picking, draw a rectangle encompassing the selection area.
-	if (m_rangepick && !m_picking && m_totalmove >= 10)
+	if (m_rangepick && !isPicking() && m_totalmove >= 10)
 	{	int x0 = m_rangeStart.x(),
 			y0 = m_rangeStart.y(),
 			x1 = m_pos.x(),
@@ -807,7 +805,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void GLRenderer::compileAllObjects()
-{	if (!file())
+{	if (!getFile())
 		return;
 
 	// Compiling all is a big job, use a busy cursor
@@ -815,7 +813,7 @@
 
 	m_knownVerts.clear();
 
-	for (LDObject* obj : file()->objects())
+	for (LDObject* obj : getFile()->getObjects())
 		compileObject (obj);
 
 	// Compile axes
@@ -895,7 +893,7 @@
 					   LDSubfile::RendererInline);
 			bool oldinvert = g_glInvert;
 
-			if (ref->transform().getDeterminant() < 0)
+			if (ref->getTransform().getDeterminant() < 0)
 				g_glInvert = !g_glInvert;
 
 			LDObject* prev = ref->prev();
@@ -937,7 +935,7 @@
 // -----------------------------------------------------------------------------
 void GLRenderer::addDrawnVertex (vertex pos)
 {	// If we picked an already-existing vertex, stop drawing
-	if (editMode() != CircleMode)
+	if (getEditMode() != CircleMode)
 	{	for (vertex& vert : m_drawedVerts)
 		{	if (vert == pos)
 			{	endDraw (true);
@@ -970,16 +968,14 @@
 			}
 		}
 
-		switch (editMode())
-		{
-			case Draw:
+		switch (getEditMode())
+		{	case Draw:
 			{	if (m_rectdraw)
 				{	if (m_drawedVerts.size() == 2)
 					{	endDraw (true);
 						return;
 					}
-				}
-				else
+				} else
 				{	// If we have 4 verts, stop drawing.
 					if (m_drawedVerts.size() >= 4)
 					{	endDraw (true);
@@ -1005,7 +1001,7 @@
 			} break;
 
 			case Select:
-			{	if (!drawOnly())
+			{	if (!isDrawOnly())
 				{	if (m_totalmove < 10)
 						m_rangepick = false;
 
@@ -1021,7 +1017,7 @@
 		m_rangepick = false;
 	}
 
-	if (wasMid && editMode() != Select && m_drawedVerts.size() < 4 && m_totalmove < 10)
+	if (wasMid && getEditMode() != Select && m_drawedVerts.size() < 4 && m_totalmove < 10)
 	{	// Find the closest vertex to our cursor
 		double mindist = 1024.0f;
 		vertex closest;
@@ -1190,7 +1186,7 @@
 			compileObject (obj);
 	}
 
-	m_picking = true;
+	setPicking (true);
 
 	// Paint the picking scene
 	glDisable (GL_DITHER);
@@ -1259,7 +1255,7 @@
 		// If this is an additive single pick and the object is currently selected,
 		// we remove it from selection instead.
 		if (!m_rangepick && m_addpick)
-		{	if (obj->selected())
+		{	if (obj->isSelected())
 			{	obj->unselect();
 				removedObj = obj;
 				break;
@@ -1284,7 +1280,7 @@
 	// Restore line thickness
 	glLineWidth (gl_linethickness);
 
-	m_picking = false;
+	setPicking (false);
 	m_rangepick = false;
 	glEnable (GL_DITHER);
 
@@ -1294,16 +1290,8 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-READ_ACCESSOR (EditMode, GLRenderer::editMode)
-{	return m_editMode;
-}
-
-// =============================================================================
-// -----------------------------------------------------------------------------
-SET_ACCESSOR (EditMode, GLRenderer::setEditMode)
-{	m_editMode = val;
-
-	switch (editMode())
+void GLRenderer::EditModeChanged()
+{	switch (getEditMode())
 	{	case Select:
 		{	unsetCursor();
 			setContextMenuPolicy (Qt::DefaultContextMenu);
@@ -1338,18 +1326,8 @@
 	update();
 }
 
-// =============================================================================
-// -----------------------------------------------------------------------------
-READ_ACCESSOR (LDFile*, GLRenderer::file)
-{	return m_file;
-}
-
-// =============================================================================
-// -----------------------------------------------------------------------------
-SET_ACCESSOR (LDFile*, GLRenderer::setFile)
-{	m_file = val;
-
-	if (val != null)
+void GLRenderer::FileChanged()
+{	if (getFile() != null)
 		initOverlaysFromObjects();
 }
 
@@ -1377,7 +1355,7 @@
 	QList<vertex>& verts = m_drawedVerts;
 	QList<LDObject*> objs;
 
-	switch (editMode())
+	switch (getEditMode())
 	{	case Draw:
 		{	if (m_rectdraw)
 			{	LDQuad* quad = new LDQuad;
@@ -1438,20 +1416,20 @@
 
 			if (dist0 == dist1)
 			{	// If the radii are the same, there's no ring space to fill. Use a circle.
-				refFile = getFile ("4-4edge.dat");
+				refFile = ::getFile ("4-4edge.dat");
 				transform = getCircleDrawMatrix (dist0);
 				circleOrDisc = true;
 			}
 			elif (dist0 == 0 || dist1 == 0)
 			{	// If either radii is 0, use a disc.
-				refFile = getFile ("4-4disc.dat");
+				refFile = ::getFile ("4-4disc.dat");
 				transform = getCircleDrawMatrix ((dist0 != 0) ? dist0 : dist1);
 				circleOrDisc = true;
 			}
 			elif (g_RingFinder (dist0, dist1))
 			{	// The ring finder found a solution, use that. Add the component rings to the file.
 				for (const RingFinder::Component& cmp : g_RingFinder.bestSolution()->getComponents())
-				{	if ((refFile = getFile (radialFileName (::Ring, lores, lores, cmp.num))) == null)
+				{	if ((refFile = ::getFile (radialFileName (::Ring, lores, lores, cmp.num))) == null)
 					{	refFile = generatePrimitive (::Ring, lores, lores, cmp.num);
 						refFile->setImplicit (false);
 					}
@@ -1525,7 +1503,7 @@
 	{	g_win->beginAction (null);
 
 		for (LDObject* obj : objs)
-		{	file()->addObject (obj);
+		{	getFile()->addObject (obj);
 			compileObject (obj);
 		}
 
@@ -1584,8 +1562,8 @@
 void GLRenderer::compileObject (LDObject* obj)
 {	deleteLists (obj);
 
-for (const GL::ListType listType : g_glListTypes)
-	{	if (drawOnly() && listType != GL::NormalList)
+	for (const GL::ListType listType : g_glListTypes)
+	{	if (isDrawOnly() && listType != GL::NormalList)
 			continue;
 
 		GLuint list = glGenLists (1);
@@ -1760,7 +1738,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void GLRenderer::zoomToFit()
-{	if (file() == null || m_width == -1 || m_height == -1)
+{	if (getFile() == null || m_width == -1 || m_height == -1)
 	{	zoom() = 30.0f;
 		return;
 	}
@@ -1776,7 +1754,7 @@
 
 	// Use the pick list while drawing the scene, this way we can tell whether borders
 	// are background or not.
-	m_picking = true;
+	setPicking (true);
 
 	for (;;)
 	{	if (zoom() > 10000.0 || zoom() < 0.0)
@@ -1833,7 +1811,7 @@
 	}
 
 	setBackground();
-	m_picking = false;
+	setPicking (false);
 }
 
 // =============================================================================
@@ -1885,7 +1863,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void GLRenderer::mouseDoubleClickEvent (QMouseEvent* ev)
-{	if (! (ev->buttons() & Qt::LeftButton) || editMode() != Select)
+{	if (!(ev->buttons() & Qt::LeftButton) || getEditMode() != Select)
 		return;
 
 	pick (ev->x(), ev->y());
@@ -1905,8 +1883,8 @@
 LDOverlay* GLRenderer::findOverlayObject (GLRenderer::Camera cam)
 {	LDOverlay* ovlobj = null;
 
-	for (LDObject * obj : file()->objects())
-	{	if (obj->getType() == LDObject::Overlay && static_cast<LDOverlay*> (obj)->camera() == cam)
+	for (LDObject * obj : getFile()->getObjects())
+	{	if (obj->getType() == LDObject::Overlay && static_cast<LDOverlay*> (obj)->getCamera() == cam)
 		{	ovlobj = static_cast<LDOverlay*> (obj);
 			break;
 		}
@@ -1930,8 +1908,9 @@
 		if (!ovlobj && meta.img)
 		{	delete meta.img;
 			meta.img = null;
-		} elif (ovlobj && (!meta.img || meta.fname != ovlobj->filename()))
-			setupOverlay (cam, ovlobj->filename(), ovlobj->x(), ovlobj->y(), ovlobj->width(), ovlobj->height());
+		} elif (ovlobj && (!meta.img || meta.fname != ovlobj->getFileName()))
+			setupOverlay (cam, ovlobj->getFileName(), ovlobj->getX(),
+				ovlobj->getY(), ovlobj->getWidth(), ovlobj->getHeight());
 	}
 }
 
@@ -1950,13 +1929,13 @@
 			LDObject* nextobj = ovlobj->next();
 
 			if (nextobj && nextobj->getType() == LDObject::Empty)
-			{	m_file->forgetObject (nextobj);
+			{	getFile()->forgetObject (nextobj);
 				delete nextobj;
 			}
 
 			// If the overlay object was there and the overlay itself is
 			// not, remove the object.
-			m_file->forgetObject (ovlobj);
+			getFile()->forgetObject (ovlobj);
 			delete ovlobj;
 		} elif (meta.img && !ovlobj)
 		{	// Inverse case: image is there but the overlay object is
@@ -1972,8 +1951,8 @@
 			int i, lastOverlay = -1;
 			bool found = false;
 
-			for (i = 0; i < file()->getObjectCount(); ++i)
-			{	LDObject* obj = file()->getObject (i);
+			for (i = 0; i < getFile()->getObjectCount(); ++i)
+			{	LDObject* obj = getFile()->getObject (i);
 
 				if (obj->isScemantic())
 				{	found = true;
@@ -1985,18 +1964,18 @@
 			}
 
 			if (lastOverlay != -1)
-				file()->insertObj (lastOverlay + 1, ovlobj);
+				getFile()->insertObj (lastOverlay + 1, ovlobj);
 			else
-			{	file()->insertObj (i, ovlobj);
+			{	getFile()->insertObj (i, ovlobj);
 
 				if (found)
-					file()->insertObj (i + 1, new LDEmpty);
+					getFile()->insertObj (i + 1, new LDEmpty);
 			}
 		}
 
 		if (meta.img && ovlobj)
 		{	ovlobj->setCamera (cam);
-			ovlobj->setFilename (meta.fname);
+			ovlobj->setFileName (meta.fname);
 			ovlobj->setX (meta.ox);
 			ovlobj->setY (meta.oy);
 			ovlobj->setWidth (meta.lw);
--- a/src/gldraw.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/gldraw.h	Thu Dec 05 23:20:50 2013 +0200
@@ -63,11 +63,11 @@
 class GLRenderer : public QGLWidget
 {	Q_OBJECT
 
-	PROPERTY (bool, drawOnly, setDrawOnly)
-	PROPERTY (MessageManager*, msglog, setMessageLog)
-	READ_PROPERTY (bool, picking, setPicking)
-	DECLARE_PROPERTY (LDFile*, file, setFile)
-	DECLARE_PROPERTY (EditMode, editMode, setEditMode)
+	PROPERTY (public,		bool,					DrawOnly,	BOOL_OPS,	NO_CB)
+	PROPERTY (public,		MessageManager*,	MessageLog, NO_OPS,		NO_CB)
+	PROPERTY (private,	bool,					Picking,		BOOL_OPS,	NO_CB)
+	PROPERTY (public,		LDFile*,				File,			NO_OPS,		WITH_CB)
+	PROPERTY (public,		EditMode,			EditMode,	NO_OPS,		WITH_CB)
 
 	public:
 		enum Camera { Top, Front, Left, Bottom, Back, Right, Free };
@@ -176,28 +176,28 @@
 		void           getRelativeAxes (Axis& relX, Axis& relY) const;
 		matrix         getCircleDrawMatrix (double scale);
 		void           drawBlip (QPainter& paint, QPoint pos) const;
-		
+
 		// Compute geometry for camera icons
 		void           calcCameraIcons();
-		
+
 		// How large is the circle we're drawing right now?
 		double         getCircleDrawDist (int pos) const;
-		
+
 		// Clamps an angle to [0, 360]
 		void           clampAngle (double& angle) const;
-		
+
 		// Compile one of the lists of an object
 		void           compileList (LDObject* obj, const ListType list);
-		
+
 		// Sub-routine for object compiling
 		void           compileSubObject (LDObject* obj, const GLenum gltype);
-		
+
 		// Compile a single vertex to a list
 		void           compileVertex (const vertex& vrt);
-		
+
 		// Convert a 2D point to a 3D point
 		vertex         coordconv2_3 (const QPoint& pos2d, bool snap) const;
-		
+
 		// Convert a 3D point to a 2D point
 		QPoint         coordconv3_2 (const vertex& pos3d) const;
 
--- a/src/gui.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/gui.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -195,9 +195,9 @@
 			ui->colorToolbar->addSeparator();
 		else
 		{	QToolButton* colorButton = new QToolButton;
-			colorButton->setIcon (makeColorIcon (entry.color(), 22));
+			colorButton->setIcon (makeColorIcon (entry.getColor(), 22));
 			colorButton->setIconSize (QSize (22, 22));
-			colorButton->setToolTip (entry.color()->name);
+			colorButton->setToolTip (entry.getColor()->name);
 
 			connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor()));
 			ui->colorToolbar->addWidget (colorButton);
@@ -226,8 +226,8 @@
 
 	// Append our current file if we have one
 	if (LDFile::current())
-	{	if (LDFile::current()->name().length() > 0)
-			title += fmt (": %1", basename (LDFile::current()->name()));
+	{	if (LDFile::current()->getName().length() > 0)
+			title += fmt (": %1", basename (LDFile::current()->getName()));
 		else
 			title += fmt (": <anonymous>");
 
@@ -238,7 +238,7 @@
 			title += fmt (": %1", comm->text);
 		}
 
-		if (LDFile::current()->history().pos() != LDFile::current()->savePos())
+		if (LDFile::current()->getHistory()->getPosition() != LDFile::current()->getSavePosition())
 			title += '*';
 	}
 
@@ -283,7 +283,7 @@
 
 	ui->objectList->clear();
 
-	for (LDObject* obj : LDFile::current()->objects())
+	for (LDObject* obj : LDFile::current()->getObjects())
 	{	str descr;
 
 		switch (obj->getType())
@@ -321,10 +321,10 @@
 			case LDObject::Subfile:
 			{	LDSubfile* ref = static_cast<LDSubfile*> (obj);
 
-				descr = fmt ("%1 %2, (", ref->fileInfo()->name(), ref->position().stringRep (true));
+				descr = fmt ("%1 %2, (", ref->getFileInfo()->getName(), ref->position().stringRep (true));
 
 				for (int i = 0; i < 9; ++i)
-					descr += fmt ("%1%2", ref->transform()[i], (i != 8) ? " " : "");
+					descr += fmt ("%1%2", ref->getTransform()[i], (i != 8) ? " " : "");
 
 				descr += ')';
 			} break;
@@ -335,8 +335,9 @@
 
 			case LDObject::Overlay:
 			{	LDOverlay* ovl = static_cast<LDOverlay*> (obj);
-				descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()],
-							 basename (ovl->filename()), ovl->x(), ovl->y(), ovl->width(), ovl->height());
+				descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->getCamera()],
+					basename (ovl->getFileName()), ovl->getX(), ovl->getY(),
+					ovl->getWidth(), ovl->getHeight());
 			}
 			break;
 
@@ -349,7 +350,7 @@
 		item->setIcon (getIcon (obj->getTypeName()));
 		
 		// Use italic font if hidden
-		if (obj->hidden())
+		if (obj->isHidden())
 		{	QFont font = item->font();
 			font.setItalic (true);
 			item->setFont (font);
@@ -360,10 +361,10 @@
 		{	item->setBackground (QColor ("#AA0000"));
 			item->setForeground (QColor ("#FFAA00"));
 		}
-		elif (lv_colorize && obj->isColored() && obj->color() != maincolor && obj->color() != edgecolor)
+		elif (lv_colorize && obj->isColored() && obj->getColor() != maincolor && obj->getColor() != edgecolor)
 		{	// If the object isn't in the main or edge color, draw this
 			// list entry in said color.
-			LDColor* col = getColor (obj->color());
+			LDColor* col = getColor (obj->getColor());
 
 			if (col)
 				item->setForeground (col->faceColor);
@@ -397,7 +398,7 @@
 	// Update the shared selection array, though don't do this if this was
 	// called during GL picking, in which case the GL renderer takes care
 	// of the selection.
-	if (m_renderer->picking())
+	if (m_renderer->isPicking())
 		return;
 
 	QList<LDObject*> priorSelection = selection();
@@ -406,7 +407,7 @@
 	LDFile::current()->clearSelection();
 	const QList<QListWidgetItem*> items = ui->objectList->selectedItems();
 
-	for (LDObject* obj : LDFile::current()->objects())
+	for (LDObject* obj : LDFile::current()->getObjects())
 	{	for (QListWidgetItem* item : items)
 		{	if (item == obj->qObjListEntry)
 			{	obj->select();
@@ -440,8 +441,8 @@
 	LDColor* col = null;
 
 	for (const LDQuickColor & entry : m_quickColors)
-	{	if (entry.toolButton() == button)
-		{	col = entry.color();
+	{	if (entry.getToolButton() == button)
+		{	col = entry.getColor();
 			break;
 		}
 	}
@@ -493,7 +494,7 @@
 void ForgeWindow::updateSelection()
 {	g_isSelectionLocked = true;
 
-	for (LDObject* obj : LDFile::current()->objects())
+	for (LDObject* obj : LDFile::current()->getObjects())
 		obj->setSelected (false);
 
 	ui->objectList->clearSelection();
@@ -519,11 +520,11 @@
 	{	if (obj->isColored() == false)
 			continue; // doesn't use color
 
-		if (result != -1 && obj->color() != result)
+		if (result != -1 && obj->getColor() != result)
 			return -1; // No consensus in object color
 
 		if (result == -1)
-			result = obj->color();
+			result = obj->getColor();
 	}
 
 	return result;
@@ -535,7 +536,7 @@
 {	LDObject::Type result = LDObject::Unidentified;
 
 	for (LDObject * obj : selection())
-	{	if (result != LDObject::Unidentified && obj->color() != result)
+	{	if (result != LDObject::Unidentified && obj->getColor() != result)
 			return LDObject::Unidentified;
 
 		if (result == LDObject::Unidentified)
@@ -613,8 +614,8 @@
 void ForgeWindow::deleteByColor (const int colnum)
 {	QList<LDObject*> objs;
 
-for (LDObject * obj : LDFile::current()->objects())
-	{	if (!obj->isColored() || obj->color() != colnum)
+	for (LDObject* obj : LDFile::current()->getObjects())
+	{	if (!obj->isColored() || obj->getColor() != colnum)
 			continue;
 
 		objs << obj;
@@ -626,7 +627,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void ForgeWindow::updateEditModeActions()
-{	const EditMode mode = R()->editMode();
+{	const EditMode mode = R()->getEditMode();
 	ACTION (ModeSelect)->setChecked (mode == Select);
 	ACTION (ModeDraw)->setChecked (mode == Draw);
 	ACTION (ModeCircle)->setChecked (mode == CircleMode);
@@ -637,7 +638,7 @@
 void ForgeWindow::slot_editObject (QListWidgetItem* listitem)
 {	LDObject* obj = null;
 
-	for (LDObject* it : LDFile::current()->objects())
+	for (LDObject* it : LDFile::current()->getObjects())
 	{	if (it->qObjListEntry == listitem)
 		{	obj = it;
 			break;
@@ -676,11 +677,12 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void ForgeWindow::save (LDFile* f, bool saveAs)
-{	str path = f->name();
+{	str path = f->getName();
 
 	if (saveAs || path.isEmpty())
 	{	path = QFileDialog::getSaveFileName (g_win, tr ("Save As"),
-			(f->name().isEmpty()) ? f->name() : f->defaultName(), tr ("LDraw files (*.dat *.ldr)"));
+			(f->getName().isEmpty()) ? f->getName() : f->getDefaultName(),
+			tr ("LDraw files (*.dat *.ldr)"));
 
 		if (path.isEmpty())
 		{	// User didn't give a file name, abort.
@@ -770,17 +772,17 @@
 }
 
 // =============================================================================
-void makeColorSelector (QComboBox* box)
+void makeColorComboBox (QComboBox* box)
 {	std::map<int, int> counts;
 
-	for (LDObject * obj : LDFile::current()->objects())
+	for (LDObject * obj : LDFile::current()->getObjects())
 	{	if (!obj->isColored())
 			continue;
 
-		if (counts.find (obj->color()) == counts.end())
-			counts[obj->color()] = 1;
+		if (counts.find (obj->getColor()) == counts.end())
+			counts[obj->getColor()] = 1;
 		else
-			counts[obj->color()]++;
+			counts[obj->getColor()]++;
 	}
 
 	box->clear();
@@ -792,7 +794,7 @@
 
 		QIcon ico = makeColorIcon (col, 16);
 		box->addItem (ico, fmt ("[%1] %2 (%3 object%4)",
-								pair.first, col->name, pair.second, plural (pair.second)));
+			pair.first, col->name, pair.second, plural (pair.second)));
 		box->setItemData (row, pair.first);
 
 		++row;
@@ -815,7 +817,7 @@
 
 	for (LDFile* f : g_loadedFiles)
 	{	// Don't list implicit files unless explicitly desired.
-		if (f->implicit() && !gui_implicitfiles)
+		if (f->isImplicit() && !gui_implicitfiles)
 			continue;
 
 		// Add an item to the list for this file and store a pointer to it in
@@ -829,7 +831,7 @@
 }
 
 void ForgeWindow::updateFileListItem (LDFile* f)
-{	if (f->listItem() == null)
+{	if (f->getListItem() == null)
 	{	// We don't have a list item for this file, so the list either doesn't
 		// exist yet or is out of date. Build the list now.
 		updateFileList();
@@ -839,28 +841,28 @@
 	// If this is the current file, it also needs to be the selected item on
 	// the list.
 	if (f == LDFile::current())
-		ui->fileList->setCurrentItem (f->listItem());
+		ui->fileList->setCurrentItem (f->getListItem());
 
 	// If we list implicit files, draw them with a shade of gray to make them
 	// distinct.
-	if (f->implicit())
-		f->listItem()->setForeground (QColor (96, 96, 96));
+	if (f->isImplicit())
+		f->getListItem()->setForeground (QColor (96, 96, 96));
 
-	f->listItem()->setText (f->getShortName());
+	f->getListItem()->setText (f->getShortName());
 
 	// If the file has unsaved changes, draw a little icon next to it to mark that.
-	f->listItem()->setIcon (f->hasUnsavedChanges() ? getIcon ("file-save") : QIcon());
+	f->getListItem()->setIcon (f->hasUnsavedChanges() ? getIcon ("file-save") : QIcon());
 }
 
 void ForgeWindow::beginAction (QAction* act)
 {	// Open the history so we can record the edits done during this action.
-	if (act != ACTION (Undo) && act != ACTION (Redo) && act != ACTION (Open))
-		LDFile::current()->openHistory();
+	if (act == ACTION (Undo) || act == ACTION (Redo) || act == ACTION (Open))
+		LDFile::current()->getHistory()->setIgnoring (true);
 }
 
 void ForgeWindow::endAction()
 {	// Close the history now.
-	LDFile::current()->closeHistory();
+	LDFile::current()->addHistoryStep();
 
 	// Update the list item of the current file - we may need to draw an icon
 	// now that marks it as having unsaved changes.
@@ -875,8 +877,8 @@
 	QListWidgetItem* item = ui->fileList->currentItem();
 
 	// Find the file pointer of the item that was selected.
-for (LDFile * it : g_loadedFiles)
-	{	if (it->listItem() == item)
+	for (LDFile* it : g_loadedFiles)
+	{	if (it->getListItem() == item)
 		{	f = it;
 			break;
 		}
@@ -912,13 +914,13 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 LDQuickColor::LDQuickColor (LDColor* color, QToolButton* toolButton) :
-	m_color (color),
-	m_toolButton (toolButton) {}
+	m_Color (color),
+	m_ToolButton (toolButton) {}
 
 LDQuickColor LDQuickColor::getSeparator()
 {	return LDQuickColor (null, null);
 }
 
 bool LDQuickColor::isSeparator() const
-{	return color() == null;
+{	return getColor() == null;
 }
--- a/src/gui.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/gui.h	Thu Dec 05 23:20:50 2013 +0200
@@ -59,8 +59,8 @@
 
 // =============================================================================
 class LDQuickColor
-{	PROPERTY (LDColor*, color, setColor)
-	PROPERTY (QToolButton*, toolButton, setToolButton)
+{	PROPERTY (public,	LDColor*,		Color,		NO_OPS,	NO_CB)
+	PROPERTY (public,	QToolButton*,	ToolButton,	NO_OPS,	NO_CB)
 
 	public:
 		LDQuickColor (LDColor* color, QToolButton* toolButton);
@@ -180,7 +180,7 @@
 bool confirm (str msg); // Generic confirm prompt
 void critical (str msg); // Generic error prompt
 QIcon makeColorIcon (LDColor* colinfo, const int size); // Makes an icon for the given color
-void makeColorSelector (QComboBox* box); // Fills the given combo-box with color information
+void makeColorComboBox (QComboBox* box); // Fills the given combo-box with color information
 QImage imageFromScreencap (uchar* data, int w, int h);
 
 // =============================================================================
@@ -188,7 +188,8 @@
 // Takes in pairs of radio buttons and respective values and returns the value of
 // the first found radio button that was checked.
 // =============================================================================
-template<class T> T radioSwitch (const T& defval, QList<pair<QRadioButton*, T>> haystack)
+template<class T>
+T radioSwitch (const T& defval, QList<pair<QRadioButton*, T>> haystack)
 {	for (pair<QRadioButton*, const T&> i : haystack)
 		if (i.first->isChecked())
 			return i.second;
@@ -201,7 +202,8 @@
 // Takes in pairs of radio buttons and respective values and checks the first
 // found radio button to have the given value.
 // =============================================================================
-template<class T> void radioDefault (const T& expr, QList<pair<QRadioButton*, T>> haystack)
+template<class T>
+void radioDefault (const T& expr, QList<pair<QRadioButton*, T>> haystack)
 {	for (pair<QRadioButton*, const T&> i : haystack)
 	{	if (i.second == expr)
 		{	i.first->setChecked (true);
--- a/src/gui_actions.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/gui_actions.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -137,7 +137,7 @@
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (SaveAll, CTRL (L))
 {	for (LDFile* file : g_loadedFiles)
-	{	if (file->implicit())
+	{	if (file->isImplicit())
 			continue;
 
 		g_win->save (file, false);
@@ -259,7 +259,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (SelectAll, CTRL (A))
-{	for (LDObject* obj : LDFile::current()->objects())
+{	for (LDObject* obj : LDFile::current()->getObjects())
 		obj->select();
 
 	g_win->updateSelection();
@@ -275,8 +275,8 @@
 
 	LDFile::current()->clearSelection();
 
-	for (LDObject* obj : LDFile::current()->objects())
-		if (obj->color() == colnum)
+	for (LDObject* obj : LDFile::current()->getObjects())
+		if (obj->getColor() == colnum)
 			obj->select();
 
 	g_win->updateSelection();
@@ -298,20 +298,20 @@
 	str refName;
 
 	if (type == LDObject::Subfile)
-	{	refName = static_cast<LDSubfile*> (selection()[0])->fileInfo()->name();
+	{	refName = static_cast<LDSubfile*> (selection()[0])->getFileInfo()->getName();
 
 		for (LDObject* obj : selection())
-			if (static_cast<LDSubfile*> (obj)->fileInfo()->name() != refName)
+			if (static_cast<LDSubfile*> (obj)->getFileInfo()->getName() != refName)
 				return;
 	}
 
 	LDFile::current()->clearSelection();
 
-	for (LDObject* obj : LDFile::current()->objects())
+	for (LDObject* obj : LDFile::current()->getObjects())
 	{	if (obj->getType() != type)
 			continue;
 
-		if (type == LDObject::Subfile && static_cast<LDSubfile*> (obj)->fileInfo()->name() != refName)
+		if (type == LDObject::Subfile && static_cast<LDSubfile*> (obj)->getFileInfo()->getName() != refName)
 			continue;
 
 		obj->select();
@@ -446,7 +446,7 @@
 	uchar* imgdata = g_win->R()->getScreencap (w, h);
 	QImage img = imageFromScreencap (imgdata, w, h);
 
-	str root = basename (LDFile::current()->name());
+	str root = basename (LDFile::current()->getName());
 
 	if (root.right (4) == ".dat")
 		root.chop (4);
@@ -474,7 +474,7 @@
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (VisibilityToggle, 0)
 {	for (LDObject* obj : selection())
-		obj->setHidden (!obj->hidden());
+		obj->toggleHidden();
 
 	g_win->refresh();
 }
--- a/src/gui_editactions.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/gui_editactions.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -316,7 +316,7 @@
 		for (int i = 0; i < obj->vertices(); ++i)
 		{	LDVertex* vert = new LDVertex;
 			vert->pos = obj->getVertex (i);
-			vert->setColor (obj->color());
+			vert->setColor (obj->getColor());
 
 			LDFile::current()->insertObj (++idx, vert);
 			g_win->R()->compileObject (vert);
@@ -462,7 +462,7 @@
 			mo->setPosition (v);
 
 			// Transform the matrix
-			mo->setTransform (mo->transform() * transform);
+			mo->setTransform (mo->getTransform() * transform);
 		} elif (obj->getType() == LDObject::Vertex)
 		{	LDVertex* vert = static_cast<LDVertex*> (obj);
 			vertex v = vert->pos;
@@ -651,8 +651,8 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 static bool isColorUsed (int colnum)
-{	for (LDObject* obj : LDFile::current()->objects())
-		if (obj->isColored() && obj->color() == colnum)
+{	for (LDObject* obj : LDFile::current()->getObjects())
+		if (obj->isColored() && obj->getColor() == colnum)
 			return true;
 
 	return false;
--- a/src/history.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/history.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -28,23 +28,22 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 History::History() :
-	m_pos (-1),
-	m_opened (false) {}
+	m_Position (-1) {}
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void History::undo()
-{	if (m_changesets.isEmpty() || pos() == -1)
+{	if (m_changesets.isEmpty() || getPosition() == -1)
 		return;
 
-	const Changeset& set = getChangeset (pos());
+	const Changeset& set = getChangeset (getPosition());
 	g_fullRefresh = false;
 
 	// Iterate the list in reverse and undo all actions
 	for (auto it = set.end() - 1; it != set.begin(); --it)
 		(*it)->undo();
 
-	setPos (pos() - 1);
+	decreasePosition();
 
 	if (!g_fullRefresh)
 		g_win->refresh();
@@ -57,17 +56,17 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void History::redo()
-{	if (pos() == (long) m_changesets.size())
+{	if (getPosition() == (long) m_changesets.size())
 		return;
 
-	const Changeset& set = getChangeset (pos() + 1);
+	const Changeset& set = getChangeset (getPosition() + 1);
 	g_fullRefresh = false;
 
 	// Redo things - in the order as they were done in the first place
 	for (const AbstractHistoryEntry* change : set)
 		change->redo();
 
-	setPos (pos() + 1);
+	setPosition (getPosition() + 1);
 
 	if (!g_fullRefresh)
 		g_win->refresh();
@@ -81,7 +80,7 @@
 // -----------------------------------------------------------------------------
 void History::clear()
 {	for (Changeset set : m_changesets)
-		for (auto change : set)
+		for (AbstractHistoryEntry* change : set)
 			delete change;
 
 	m_changesets.clear();
@@ -90,56 +89,42 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void History::updateActions() const
-{	ACTION (Undo)->setEnabled (pos() != -1);
-	ACTION (Redo)->setEnabled (pos() < (long) m_changesets.size() - 1);
-}
-
-// =============================================================================
-// -----------------------------------------------------------------------------
-void History::open()
-{	if (opened())
-		return;
-
-	setOpened (true);
+{	ACTION (Undo)->setEnabled (getPosition() != -1);
+	ACTION (Redo)->setEnabled (getPosition() < (long) m_changesets.size() - 1);
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-void History::close()
-{	if (!opened())
+void History::addStep()
+{	if (m_currentChangeset.isEmpty())
 		return;
 
-	setOpened (false);
-
-	if (m_currentArchive.isEmpty())
-		return;
-
-	while (pos() < getSize() - 1)
+	while (getPosition() < getSize() - 1)
 		m_changesets.removeLast();
 
-	m_changesets << m_currentArchive;
-	m_currentArchive.clear();
-	setPos (pos() + 1);
+	m_changesets << m_currentChangeset;
+	m_currentChangeset.clear();
+	setPosition (getPosition() + 1);
 	updateActions();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void History::add (AbstractHistoryEntry* entry)
-{	if (!opened())
+{	if (isIgnoring())
 	{	delete entry;
 		return;
 	}
 
 	entry->setParent (this);
-	m_currentArchive << entry;
+	m_currentChangeset << entry;
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void AddHistory::undo() const
-{	LDFile* f = parent()->file();
-	LDObject* obj = f->getObject (index());
+{	LDFile* f = getParent()->getFile();
+	LDObject* obj = f->getObject (getIndex());
 	f->forgetObject (obj);
 	delete obj;
 
@@ -149,42 +134,38 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void AddHistory::redo() const
-{	LDFile* f = parent()->file();
-	LDObject* obj = parseLine (code());
-	f->insertObj (index(), obj);
+{	LDFile* f = getParent()->getFile();
+	LDObject* obj = parseLine (getCode());
+	f->insertObj (getIndex(), obj);
 	g_win->R()->compileObject (obj);
 }
 
-AddHistory::~AddHistory() {}
-
 // =============================================================================
 // heh
 // -----------------------------------------------------------------------------
 void DelHistory::undo() const
-{	LDFile* f = parent()->file();
-	LDObject* obj = parseLine (code());
-	f->insertObj (index(), obj);
+{	LDFile* f = getParent()->getFile();
+	LDObject* obj = parseLine (getCode());
+	f->insertObj (getIndex(), obj);
 	g_win->R()->compileObject (obj);
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void DelHistory::redo() const
-{	LDFile* f = parent()->file();
-	LDObject* obj = f->getObject (index());
+{	LDFile* f = getParent()->getFile();
+	LDObject* obj = f->getObject (getIndex());
 	f->forgetObject (obj);
 	delete obj;
 
 	g_fullRefresh = true;
 }
 
-DelHistory::~DelHistory() {}
-
 // =============================================================================
 // -----------------------------------------------------------------------------
 void EditHistory::undo() const
-{	LDObject* obj = LDFile::current()->getObject (index());
-	LDObject* newobj = parseLine (oldCode());
+{	LDObject* obj = LDFile::current()->getObject (getIndex());
+	LDObject* newobj = parseLine (getOldCode());
 	obj->replace (newobj);
 	g_win->R()->compileObject (newobj);
 }
@@ -192,14 +173,12 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void EditHistory::redo() const
-{	LDObject* obj = LDFile::current()->getObject (index());
-	LDObject* newobj = parseLine (newCode());
+{	LDObject* obj = LDFile::current()->getObject (getIndex());
+	LDObject* newobj = parseLine (getNewCode());
 	obj->replace (newobj);
 	g_win->R()->compileObject (newobj);
 }
 
-EditHistory::~EditHistory() {}
-
 // =============================================================================
 // -----------------------------------------------------------------------------
 void SwapHistory::undo() const
@@ -208,6 +187,4 @@
 
 void SwapHistory::redo() const
 {	undo(); // :v
-}
-
-SwapHistory::~SwapHistory() {}
+}
\ No newline at end of file
--- a/src/history.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/history.h	Thu Dec 05 23:20:50 2013 +0200
@@ -23,7 +23,7 @@
 #include "ldtypes.h"
 
 #define IMPLEMENT_HISTORY_TYPE(N) \
-	virtual ~N##History(); \
+	virtual ~N##History(){} \
 	virtual void undo() const override; \
 	virtual void redo() const override; \
 	virtual History::Type getType() const override { return History::N; }
@@ -32,9 +32,9 @@
 
 // =============================================================================
 class History
-{	PROPERTY (long, pos, setPos)
-	PROPERTY (LDFile*, file, setFile)
-	READ_PROPERTY (bool, opened, setOpened)
+{	PROPERTY (private,	long,		Position,	NUM_OPS,		NO_CB)
+	PROPERTY (public,		LDFile*,	File,			NO_OPS,		NO_CB)
+	PROPERTY (public,		bool,		Ignoring,	BOOL_OPS,	NO_CB)
 
 	public:
 		typedef QList<AbstractHistoryEntry*> Changeset;
@@ -53,8 +53,7 @@
 		void clear();
 		void updateActions() const;
 
-		void open();
-		void close();
+		void addStep();
 		void add (AbstractHistoryEntry* entry);
 
 		inline long getSize() const
@@ -71,7 +70,7 @@
 		}
 
 	private:
-		Changeset m_currentArchive;
+		Changeset m_currentChangeset;
 		QList<Changeset> m_changesets;
 };
 
@@ -79,12 +78,12 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 class AbstractHistoryEntry
-{		PROPERTY (History*, parent, setParent)
+{	PROPERTY (public,	History*,	Parent,	NO_OPS,	NO_CB)
 
 	public:
+		virtual ~AbstractHistoryEntry() {}
 		virtual void undo() const {}
 		virtual void redo() const {}
-		virtual ~AbstractHistoryEntry() {}
 		virtual History::Type getType() const
 		{	return (History::Type) 0;
 		}
@@ -94,63 +93,47 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 class DelHistory : public AbstractHistoryEntry
-{	public:
-		enum Type
-		{	Cut,	// was deleted with a cut operation
-			Other,	// was deleted witout specific reason
-		};
-
-		PROPERTY (int, index, setIndex)
-		PROPERTY (str, code, setCode)
-		PROPERTY (DelHistory::Type, type, setType)
+{	PROPERTY (private,	int,	Index,	NO_OPS,	NO_CB)
+	PROPERTY (private,	str,	Code,		NO_OPS,	NO_CB)
 
 	public:
 		IMPLEMENT_HISTORY_TYPE (Del)
 
-		DelHistory (int idx, LDObject* obj, Type type = Other) :
-				m_index (idx),
-				m_code (obj->raw()),
-				m_type (type) {}
+		DelHistory (int idx, LDObject* obj) :
+				m_Index (idx),
+				m_Code (obj->raw()) {}
 };
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 class EditHistory : public AbstractHistoryEntry
-{	PROPERTY (int, index, setIndex)
-	PROPERTY (str, oldCode, setOldCode)
-	PROPERTY (str, newCode, setNewCode)
+{	PROPERTY (private,	int, Index,		NO_OPS,	NO_CB)
+	PROPERTY (private,	str, OldCode,	NO_OPS,	NO_CB)
+	PROPERTY (private,	str, NewCode,	NO_OPS,	NO_CB)
 
 	public:
 		IMPLEMENT_HISTORY_TYPE (Edit)
 
 		EditHistory (int idx, str oldCode, str newCode) :
-				m_index (idx),
-				m_oldCode (oldCode),
-				m_newCode (newCode) {}
+				m_Index (idx),
+				m_OldCode (oldCode),
+				m_NewCode (newCode) {}
 };
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 class AddHistory : public AbstractHistoryEntry
-{	public:
-		enum Type
-		{	Other,	// was "just added"
-			Paste,	// was added through a paste operation
-		};
-
-		PROPERTY (int, index, setIndex)
-		PROPERTY (str, code, setCode)
-		PROPERTY (AddHistory::Type, type, setType)
+{	PROPERTY (private,	int,	Index,	NO_OPS,	NO_CB)
+	PROPERTY (private,	str,	Code,		NO_OPS,	NO_CB)
 
 	public:
 		IMPLEMENT_HISTORY_TYPE (Add)
 
-		AddHistory (int idx, LDObject* obj, Type type = Other) :
-				m_index (idx),
-				m_code (obj->raw()),
-				m_type (type) {}
+		AddHistory (int idx, LDObject* obj) :
+				m_Index (idx),
+				m_Code (obj->raw()) {}
 };
 
 // =============================================================================
@@ -174,11 +157,13 @@
 class SwapHistory : public AbstractHistoryEntry
 {	public:
 		IMPLEMENT_HISTORY_TYPE (Swap)
-		int a, b;
 
 		SwapHistory (int a, int b) :
 				a (a),
 				b (b) {}
+
+	private:
+		int a, b;
 };
 
 #endif // LDFORGE_HISTORY_H
--- a/src/ldtypes.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/ldtypes.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -36,10 +36,10 @@
 // LDObject constructors
 // -----------------------------------------------------------------------------
 LDObject::LDObject() :
-	m_hidden (false),
-	m_selected (false),
-	m_parent (null),
-	m_file (null),
+	m_Hidden (false),
+	m_Selected (false),
+	m_Parent (null),
+	m_File (null),
 	qObjListEntry (null),
 	m_glinit (false)
 {
@@ -49,8 +49,8 @@
 	int32 id = 1; // 0 is invalid
 
 	for (LDObject* obj : g_LDObjects)
-		if (obj->id() >= id)
-			id = obj->id() + 1;
+		if (obj->getID() >= id)
+			id = obj->getID() + 1;
 
 	setID (id);
 	g_LDObjects << this;
@@ -104,17 +104,17 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 str LDSubfile::raw()
-{	str val = fmt ("1 %1 %2 ", color(), position());
-	val += transform().stringRep();
+{	str val = fmt ("1 %1 %2 ", getColor(), position());
+	val += getTransform().stringRep();
 	val += ' ';
-	val += fileInfo()->name();
+	val += getFileInfo()->getName();
 	return val;
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 str LDLine::raw()
-{	str val = fmt ("2 %1", color());
+{	str val = fmt ("2 %1", getColor());
 
 	for (int i = 0; i < 2; ++i)
 		val += fmt (" %1", getVertex (i));
@@ -125,7 +125,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 str LDTriangle::raw()
-{	str val = fmt ("3 %1", color());
+{	str val = fmt ("3 %1", getColor());
 
 	for (int i = 0; i < 3; ++i)
 		val += fmt (" %1", getVertex (i));
@@ -136,7 +136,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 str LDQuad::raw()
-{	str val = fmt ("4 %1", color());
+{	str val = fmt ("4 %1", getColor());
 
 	for (int i = 0; i < 4; ++i)
 		val += fmt (" %1", getVertex (i));
@@ -147,7 +147,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 str LDCndLine::raw()
-{	str val = fmt ("5 %1", color());
+{	str val = fmt ("5 %1", getColor());
 
 	// Add the coordinates
 	for (int i = 0; i < 4; ++i)
@@ -165,7 +165,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 str LDVertex::raw()
-{	return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos);
+{	return fmt ("0 !LDFORGE VERTEX %1 %2", getColor(), pos);
 }
 
 // =============================================================================
@@ -206,8 +206,8 @@
 	LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3));
 
 	// The triangles also inherit the quad's color
-	tri1->setColor (color());
-	tri2->setColor (color());
+	tri1->setColor (getColor());
+	tri2->setColor (getColor());
 
 	QList<LDTriangle*> triangles;
 	triangles << tri1;
@@ -222,7 +222,7 @@
 	assert (idx != -1);
 
 	// Replace the instance of the old object with the new object
-	file()->setObject (idx, other);
+	getFile()->setObject (idx, other);
 
 	// Remove the old object
 	delete this;
@@ -233,16 +233,16 @@
 void LDObject::swap (LDObject* other)
 {	int i = 0;
 
-	for (LDObject* obj : file()->objects())
+	for (LDObject* obj : getFile()->getObjects())
 	{	if (obj == this)
-			file()->setObject (i, other);
+			getFile()->setObject (i, other);
 		elif (obj == other)
-			file()->setObject (i, this);
+			getFile()->setObject (i, this);
 
 		++i;
 	}
 
-	file()->addToHistory (new SwapHistory (id(), other->id()));
+	getFile()->addToHistory (new SwapHistory (getID(), other->getID()));
 }
 
 // =============================================================================
@@ -265,12 +265,12 @@
 // -----------------------------------------------------------------------------
 LDObject::~LDObject()
 {	// If this object was selected, unselect it now
-	if (selected())
+	if (isSelected())
 		unselect();
 
 	// If this object was associated to a file, remove it off it now
-	if (file())
-		file()->forgetObject (this);
+	if (getFile())
+		getFile()->forgetObject (this);
 
 	// Delete the GL lists
 	GL::deleteLists (this);
@@ -298,7 +298,7 @@
 
 		case LDObject::Subfile:
 		{	LDSubfile* ref = static_cast<LDSubfile*> (obj);
-			matrix newMatrix = transform * ref->transform();
+			matrix newMatrix = transform * ref->getTransform();
 			vertex newpos = ref->position();
 
 			newpos.transform (transform, pos);
@@ -311,20 +311,20 @@
 			break;
 	}
 
-	if (obj->color() == maincolor)
+	if (obj->getColor() == maincolor)
 		obj->setColor (parentcolor);
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 QList<LDObject*> LDSubfile::inlineContents (InlineFlags flags)
-{	QList<LDObject*> objs = fileInfo()->inlineContents (flags);
+{	QList<LDObject*> objs = getFileInfo()->inlineContents (flags);
 
 	// Transform the objects
 for (LDObject * obj : objs)
 	{	// Set the parent now so we know what inlined this.
 		obj->setParent (this);
-		transformObject (obj, transform(), position(), color());
+		transformObject (obj, getTransform(), position(), getColor());
 	}
 
 	return objs;
@@ -335,11 +335,11 @@
 long LDObject::getIndex() const
 {
 #ifndef RELEASE
-	assert (file() != null);
+	assert (getFile() != null);
 #endif
 
-	for (int i = 0; i < file()->getObjectCount(); ++i)
-		if (file()->getObject (i) == this)
+	for (int i = 0; i < getFile()->getObjectCount(); ++i)
+		if (getFile()->getObject (i) == this)
 			return i;
 
 	return -1;
@@ -356,7 +356,7 @@
 	const long end = up ? objs.size() : -1;
 	const long incr = up ? 1 : -1;
 	QList<LDObject*> objsToCompile;
-	LDFile* file = objs[0]->file();
+	LDFile* file = objs[0]->getFile();
 
 	for (long i = start; i != end; i += incr)
 	{	LDObject* obj = objs[i];
@@ -364,7 +364,7 @@
 		const long idx = obj->getIndex(),
 				   target = idx + (up ? -1 : 1);
 
-		if ( (up && idx == 0) || (!up && idx == (long) (file->objects().size() - 1)))
+		if ( (up && idx == 0) || (!up && idx == (long) (file->getObjects().size() - 1)))
 		{	// One of the objects hit the extrema. If this happens, this should be the first
 			// object to be iterated on. Thus, nothing has changed yet and it's safe to just
 			// abort the entire operation.
@@ -435,13 +435,13 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 LDObject* LDObject::topLevelParent()
-{	if (!parent())
+{	if (!getParent())
 		return this;
 
 	LDObject* it = this;
 
-	while (it->parent())
-		it = it->parent();
+	while (it->getParent())
+		it = it->getParent();
 
 	return it;
 }
@@ -452,10 +452,10 @@
 {	long idx = getIndex();
 	assert (idx != -1);
 
-	if (idx == (long) file()->getObjectCount() - 1)
+	if (idx == (long) getFile()->getObjectCount() - 1)
 		return null;
 
-	return file()->getObject (idx + 1);
+	return getFile()->getObject (idx + 1);
 }
 
 // =============================================================================
@@ -467,7 +467,7 @@
 	if (idx == 0)
 		return null;
 
-	return file()->getObject (idx - 1);
+	return getFile()->getObject (idx - 1);
 }
 
 // =============================================================================
@@ -597,7 +597,7 @@
 
 		if (bfc && bfc->type == LDBFC::InvertNext)
 		{	// This is prefixed with an invertnext, thus remove it.
-			file()->forgetObject (bfc);
+			getFile()->forgetObject (bfc);
 			delete bfc;
 			return;
 		}
@@ -605,7 +605,7 @@
 
 	// Not inverted, thus prefix it with a new invertnext.
 	LDBFC* bfc = new LDBFC (LDBFC::InvertNext);
-	file()->insertObj (idx, bfc);
+	getFile()->insertObj (idx, bfc);
 }
 
 // =============================================================================
@@ -636,7 +636,7 @@
 	for (int i = 0; i < repl->vertices(); ++i)
 		repl->setVertex (i, getVertex (i));
 
-	repl->setColor (color());
+	repl->setColor (getColor());
 
 	replace (repl);
 	return repl;
@@ -646,7 +646,7 @@
 // -----------------------------------------------------------------------------
 LDObject* LDObject::fromID (int id)
 {	for (LDObject * obj : g_LDObjects)
-		if (obj->id() == id)
+		if (obj->getID() == id)
 			return obj;
 
 	return null;
@@ -656,7 +656,7 @@
 // -----------------------------------------------------------------------------
 str LDOverlay::raw()
 {	return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6",
-				filename(), camera(), x(), y(), width(), height());
+		getFileName(), getCamera(), getX(), getY(), getWidth(), getHeight());
 }
 
 void LDOverlay::move (vertex vect)
@@ -669,6 +669,8 @@
 // Hook the set accessors of certain properties to this changeProperty function.
 // It takes care of history management so we can capture low-level changes, this
 // makes history stuff work out of the box.
+//
+// TODO: use new PROPERTY-callbacks
 // -----------------------------------------------------------------------------
 template<class T> static void changeProperty (LDObject* obj, T* ptr, const T& val)
 {	long idx;
@@ -676,12 +678,12 @@
 	if (*ptr == val)
 		return;
 
-	if (obj->file() && (idx = obj->getIndex()) != -1)
+	if (obj->getFile() && (idx = obj->getIndex()) != -1)
 	{	str before = obj->raw();
 		*ptr = val;
 		str after = obj->raw();
 
-		obj->file()->addToHistory (new EditHistory (idx, before, after));
+		obj->getFile()->addToHistory (new EditHistory (idx, before, after));
 	}
 	else
 		*ptr = val;
@@ -689,12 +691,12 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-READ_ACCESSOR (int, LDObject::color)
-{	return m_color;
+const int& LDObject::getColor() const
+{	return m_Color;
 }
 
-SET_ACCESSOR (int, LDObject::setColor)
-{	changeProperty (this, &m_color, val);
+void LDObject::setColor (int val)
+{	changeProperty (this, &m_Color, val);
 }
 
 // =============================================================================
@@ -710,17 +712,13 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void LDMatrixObject::setPosition (const vertex& a)
-{	changeProperty (linkPointer(), &m_position, LDSharedVertex::getSharedVertex (a));
+{	changeProperty (getLinkPointer(), &m_position, LDSharedVertex::getSharedVertex (a));
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-READ_ACCESSOR (matrix, LDMatrixObject::transform)
-{	return m_transform;
-}
-
-SET_ACCESSOR (matrix, LDMatrixObject::setTransform)
-{	changeProperty (linkPointer(), &m_transform, val);
+void LDMatrixObject::setTransform (const matrix& val)
+{	changeProperty (getLinkPointer(), &m_Transform, val);
 }
 
 // =============================================================================
@@ -759,19 +757,19 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void LDObject::select()
-{	if (!file())
-	{	log ("Warning: Object #%1 cannot be selected as it is not assigned a file!\n", id());
+{	if (!getFile())
+	{	log ("Warning: Object #%1 cannot be selected as it is not assigned a file!\n", getID());
 		return;
 	}
 
-	file()->addToSelection (this);
+	getFile()->addToSelection (this);
 }
 
 void LDObject::unselect()
-{	if (!file())
-	{	log ("Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", id());
+{	if (!getFile())
+	{	log ("Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", getID());
 		return;
 	}
 
-	file()->removeFromSelection (this);
+	getFile()->removeFromSelection (this);
 }
\ No newline at end of file
--- a/src/ldtypes.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/ldtypes.h	Thu Dec 05 23:20:50 2013 +0200
@@ -63,12 +63,11 @@
 // sub-classes based on this enumerator.
 // =============================================================================
 class LDObject
-{	PROPERTY (bool, hidden, setHidden)
-	PROPERTY (bool, selected, setSelected)
-	PROPERTY (LDObject*, parent, setParent)
-	PROPERTY (LDFile*, file, setFile)
-	READ_PROPERTY (int32, id, setID)
-	DECLARE_PROPERTY (int, color, setColor)
+{	PROPERTY (public,		bool,			Hidden,		BOOL_OPS,	NO_CB)
+	PROPERTY (public,		bool,			Selected,	BOOL_OPS,	NO_CB)
+	PROPERTY (public,		LDObject*,	Parent,		NO_OPS,		NO_CB)
+	PROPERTY (public,		LDFile*,		File,			NO_OPS,		NO_CB)
+	PROPERTY	(private,	int32,		ID,			NUM_OPS,		NO_CB)
 
 	public:
 		// Object type codes. Codes are sorted in order of significance.
@@ -95,6 +94,7 @@
 		{	return 0;   // Creates a new LDObject identical to this one.
 		}
 		long getIndex() const;                      // Index (i.e. line number) of this object
+		const int& getColor() const;						// Color of this object
 		virtual LDObject::Type getType() const;     // Type enumerator of this object
 		const vertex& getVertex (int i) const;      // Get a vertex by index
 		virtual str getTypeName() const;            // Type name of this object
@@ -108,6 +108,7 @@
 		virtual str raw() {	return ""; }            // This object as LDraw code
 		void replace (LDObject* other);             // Replace this LDObject with another LDObject. Object is deleted in the process.
 		void select();
+		void setColor (int val);
 		void setVertex (int i, const vertex& vert); // Set a vertex to the given value
 		void setVertexCoord (int i, Axis ax, double value); // Set a single coordinate of a vertex
 		void swap (LDObject* other);                // Swap this object with another.
@@ -133,7 +134,8 @@
 		friend class GLRenderer;
 
 	private:
-		LDSharedVertex* m_coords[4];
+		LDSharedVertex*	m_coords[4];
+		int					m_Color;
 };
 
 // =============================================================================
@@ -180,19 +182,20 @@
 // this class distinct in case I get new extension ideas. :)
 // =============================================================================
 class LDMatrixObject
-{	DECLARE_PROPERTY (matrix, transform, setTransform)
-	PROPERTY (LDObject*, linkPointer, setLinkPointer)
+{	PROPERTY (public,	LDObject*,	LinkPointer,	NO_OPS,	NO_CB)
 
 	public:
 		LDMatrixObject() {}
 		LDMatrixObject (const matrix& transform, const vertex& pos) :
-			m_transform (transform), m_position (LDSharedVertex::getSharedVertex (pos)) {}
+			m_Transform (transform),
+			m_position (LDSharedVertex::getSharedVertex (pos)) {}
 
 		const vertex& position() const
 		{	return m_position->data();
 		}
 
 		void setPosition (const vertex& a);
+		void setTransform (const matrix& val);
 
 		const double& setCoordinate (const Axis ax, double value)
 		{	vertex v = position();
@@ -202,8 +205,13 @@
 			return position() [ax];
 		}
 
+		inline const matrix& getTransform() const
+		{	return m_Transform;
+		}
+
 	private:
-		LDSharedVertex* m_position;
+		matrix				m_Transform;
+		LDSharedVertex*	m_position;
 };
 
 // =============================================================================
@@ -221,7 +229,7 @@
 	LDOBJ_UNCOLORED
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
-	PROPERTY (str, fileRef, setFileRef)
+	PROPERTY (public,	str, FileReferenced, STR_OPS,	NO_CB)
 
 	public:
 		LDError();
@@ -319,7 +327,7 @@
 	LDOBJ_COLORED
 	LDOBJ_SCEMANTIC
 	LDOBJ_HAS_MATRIX
-	PROPERTY (LDFile*, fileInfo, setFileInfo)
+	PROPERTY (public,	LDFile*, FileInfo, NO_OPS,	NO_CB)
 
 	public:
 		enum InlineFlag
@@ -463,12 +471,12 @@
 	LDOBJ_UNCOLORED
 	LDOBJ_NON_SCEMANTIC
 	LDOBJ_NO_MATRIX
-	PROPERTY (int, camera, setCamera)
-	PROPERTY (int, x, setX)
-	PROPERTY (int, y, setY)
-	PROPERTY (int, width, setWidth)
-	PROPERTY (int, height, setHeight)
-	PROPERTY (str, filename, setFilename)
+	PROPERTY (public,	int, Camera,	NUM_OPS,	NO_CB)
+	PROPERTY (public,	int, X,			NUM_OPS,	NO_CB)
+	PROPERTY (public,	int, Y,			NUM_OPS,	NO_CB)
+	PROPERTY (public,	int, Width,		NUM_OPS,	NO_CB)
+	PROPERTY (public,	int, Height,	NUM_OPS,	NO_CB)
+	PROPERTY (public,	str, FileName,	STR_OPS,	NO_CB)
 };
 
 // Other common LDraw stuff
--- a/src/messagelog.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/messagelog.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -79,8 +79,8 @@
 	m_lines << Line (line);
 
 	// Update the renderer view
-	if (renderer())
-		renderer()->update();
+	if (getRenderer())
+		getRenderer()->update();
 }
 
 // =============================================================================
@@ -102,8 +102,8 @@
 		changed |= lineChanged;
 	}
 
-	if (changed && renderer())
-		renderer()->update();
+	if (changed && getRenderer())
+		getRenderer()->update();
 }
 
 // =============================================================================
--- a/src/messagelog.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/messagelog.h	Thu Dec 05 23:20:50 2013 +0200
@@ -38,8 +38,8 @@
  * repainting.
  */
 class MessageManager : public QObject
-{		Q_OBJECT
-		PROPERTY (GLRenderer*, renderer, setRenderer)
+{	Q_OBJECT
+	PROPERTY (public,	GLRenderer*,	Renderer,	NO_OPS,	NO_CB)
 
 	public:
 		// Single line of the message log.
--- a/src/misc.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/misc.h	Thu Dec 05 23:20:50 2013 +0200
@@ -182,8 +182,7 @@
 
 template<class T> void removeDuplicates (QList<T>& a)
 {	std::sort (a.begin(), a.end());
-	typename QList<T>::iterator pos = std::unique (a.begin(), a.end());
-	a.erase (pos, a.end());
+	a.erase (std::unique (a.begin(), a.end()), a.end());
 }
 
 #endif // LDFORGE_MISC_H
--- a/src/primitives.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/primitives.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -169,7 +169,7 @@
 // -----------------------------------------------------------------------------
 static PrimitiveCategory* findCategory (str name)
 {	for (PrimitiveCategory & cat : g_PrimitiveCategories)
-		if (cat.name() == name)
+		if (cat.getName() == name)
 			return &cat;
 
 	return null;
--- a/src/primitives.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/primitives.h	Thu Dec 05 23:20:50 2013 +0200
@@ -33,7 +33,7 @@
 };
 
 class PrimitiveCategory
-{	PROPERTY (str, name, setName)
+{	PROPERTY (public,	str,	Name,	STR_OPS,	NO_CB)
 
 	public:
 		enum Type
--- a/src/types.cpp	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/types.cpp	Thu Dec 05 23:20:50 2013 +0200
@@ -59,7 +59,7 @@
 vertex vertex::midpoint (const vertex& other)
 {	vertex mid;
 
-for (const Axis ax : g_Axes)
+	for (const Axis ax : g_Axes)
 		mid[ax] = (m_coords[ax] + other[ax]) / 2;
 
 	return mid;
@@ -513,7 +513,7 @@
 	if (!LDFile::current())
 		return;
 
-for (LDObject * obj : LDFile::current()->objects())
+	for (LDObject* obj : LDFile::current()->getObjects())
 		calcObject (obj);
 }
 
@@ -563,31 +563,31 @@
 // -----------------------------------------------------------------------------
 void LDBoundingBox::calcVertex (const vertex& v)
 {	for (const Axis ax : g_Axes)
-	{	if (v[ax] < m_v0[ax])
-			m_v0[ax] = v[ax];
+	{	if (v[ax] < m_Vertex0[ax])
+			m_Vertex0[ax] = v[ax];
 
-		if (v[ax] > m_v1[ax])
-			m_v1[ax] = v[ax];
+		if (v[ax] > m_Vertex1[ax])
+			m_Vertex1[ax] = v[ax];
 	}
 
-	m_empty = false;
+	setEmpty (false);
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void LDBoundingBox::reset()
-{	m_v0[X] = m_v0[Y] = m_v0[Z] = 0x7FFFFFFF;
-	m_v1[X] = m_v1[Y] = m_v1[Z] = 0xFFFFFFFF;
+{	m_Vertex0[X] = m_Vertex0[Y] = m_Vertex0[Z] = 0x7FFFFFFF;
+	m_Vertex1[X] = m_Vertex1[Y] = m_Vertex1[Z] = 0xFFFFFFFF;
 
-	m_empty = true;
+	setEmpty (true);
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 double LDBoundingBox::size() const
-{	double xscale = (m_v0[X] - m_v1[X]);
-	double yscale = (m_v0[Y] - m_v1[Y]);
-	double zscale = (m_v0[Z] - m_v1[Z]);
+{	double xscale = (m_Vertex0[X] - m_Vertex1[X]);
+	double yscale = (m_Vertex0[Y] - m_Vertex1[Y]);
+	double zscale = (m_Vertex0[Z] - m_Vertex1[Z]);
 	double size = zscale;
 
 	if (xscale > yscale)
@@ -607,7 +607,7 @@
 // -----------------------------------------------------------------------------
 vertex LDBoundingBox::center() const
 {	return vertex (
-		(m_v0[X] + m_v1[X]) / 2,
-		(m_v0[Y] + m_v1[Y]) / 2,
-		(m_v0[Z] + m_v1[Z]) / 2);
+		(m_Vertex0[X] + m_Vertex1[X]) / 2,
+		(m_Vertex0[Y] + m_Vertex1[Y]) / 2,
+		(m_Vertex0[Z] + m_Vertex1[Z]) / 2);
 }
--- a/src/types.h	Thu Dec 05 13:51:52 2013 +0200
+++ b/src/types.h	Thu Dec 05 23:20:50 2013 +0200
@@ -21,6 +21,7 @@
 
 #include <QString>
 #include <QObject>
+#include <QStringList>
 #include <deque>
 #include "common.h"
 
@@ -295,9 +296,9 @@
 // v0 is the minimum vertex, v1 is the maximum vertex.
 // =============================================================================
 class LDBoundingBox
-{	READ_PROPERTY (bool, empty, setEmpty)
-	READ_PROPERTY (vertex, v0, setV0)
-	READ_PROPERTY (vertex, v1, setV1)
+{	PROPERTY (private,	bool,		Empty,	BOOL_OPS,	NO_CB)
+	PROPERTY (private,	vertex,	Vertex0,	NO_OPS,		NO_CB)
+	PROPERTY (private,	vertex,	Vertex1,	NO_OPS,		NO_CB)
 
 	public:
 		LDBoundingBox();

mercurial