Cleaned up download.cpp/.h, used PROPERTY. Added LIST_OPS to PROPERTY

Sat, 07 Dec 2013 00:01:20 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sat, 07 Dec 2013 00:01:20 +0200
changeset 549
715d9a7f6598
parent 548
a99f41732cd2
child 550
d97594e3fc54

Cleaned up download.cpp/.h, used PROPERTY. Added LIST_OPS to PROPERTY

src/download.cpp file | annotate | diff | comparison | revisions
src/download.h file | annotate | diff | comparison | revisions
src/main.h file | annotate | diff | comparison | revisions
src/property.h file | annotate | diff | comparison | revisions
--- a/src/download.cpp	Fri Dec 06 21:30:58 2013 +0200
+++ b/src/download.cpp	Sat Dec 07 00:01:20 2013 +0200
@@ -31,15 +31,15 @@
 #include "configDialog.h"
 #include "moc_download.cpp"
 
-cfg (String, net_downloadpath, "");
-cfg (Bool, net_guesspaths, true);
-cfg (Bool, net_autoclose, false);
+cfg (String,	net_downloadpath,	"");
+cfg (Bool,		net_guesspaths,	true);
+cfg (Bool,		net_autoclose,		false);
 
-constexpr const char *PartDownloader::k_UnofficialURL;
+const str g_unofficialLibraryURL ("http://ldraw.org/library/unofficial/");
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-void PartDownloader::k_download()
+void PartDownloader::staticBegin()
 {	str path = getDownloadPath();
 
 	if (path == "" || QDir (path).exists() == false)
@@ -69,23 +69,25 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 PartDownloader::PartDownloader (QWidget* parent) : QDialog (parent)
-{	ui = new Ui_DownloadFrom;
-	ui->setupUi (this);
-	ui->fname->setFocus();
-	ui->progress->horizontalHeader()->setResizeMode (PartLabelColumn, QHeaderView::Stretch);
+{	setInterface (new Ui_DownloadFrom);
+	getInterface()->setupUi (this);
+	getInterface()->fname->setFocus();
+	getInterface()->progress->horizontalHeader()->setResizeMode (PartLabelColumn, QHeaderView::Stretch);
 
-	m_downloadButton = new QPushButton (tr ("Download"));
-	ui->buttonBox->addButton (m_downloadButton, QDialogButtonBox::ActionRole);
+	setDownloadButton (new QPushButton (tr ("Download")));
+	getInterface()->buttonBox->addButton (getDownloadButton(), QDialogButtonBox::ActionRole);
 	getButton (Abort)->setEnabled (false);
 
-	connect (ui->source, SIGNAL (currentIndexChanged (int)), this, SLOT (sourceChanged (int)));
-	connect (ui->buttonBox, SIGNAL (clicked (QAbstractButton*)), this, SLOT (buttonClicked (QAbstractButton*)));
+	connect (getInterface()->source, SIGNAL (currentIndexChanged (int)),
+		this, SLOT (sourceChanged (int)));
+	connect (getInterface()->buttonBox, SIGNAL (clicked (QAbstractButton*)),
+		this, SLOT (buttonClicked (QAbstractButton*)));
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 PartDownloader::~PartDownloader()
-{	delete ui;
+{	delete getInterface();
 }
 
 // =============================================================================
@@ -96,12 +98,12 @@
 
 	switch (src)
 	{	case PartsTracker:
-			dest = ui->fname->text();
+			dest = getInterface()->fname->text();
 			modifyDestination (dest);
-			return str (k_UnofficialURL) + dest;
+			return g_unofficialLibraryURL + dest;
 
 		case CustomURL:
-			return ui->fname->text();
+			return getInterface()->fname->text();
 	}
 
 	// Shouldn't happen
@@ -169,16 +171,16 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 PartDownloader::Source PartDownloader::getSource() const
-{	return (Source) ui->source->currentIndex();
+{	return (Source) getInterface()->source->currentIndex();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloader::sourceChanged (int i)
 {	if (i == CustomURL)
-		ui->fileNameLabel->setText (tr ("URL:"));
+		getInterface()->fileNameLabel->setText (tr ("URL:"));
 	else
-		ui->fileNameLabel->setText (tr ("File name:"));
+		getInterface()->fileNameLabel->setText (tr ("File name:"));
 }
 
 // =============================================================================
@@ -186,13 +188,15 @@
 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)
+		for (PartDownloadRequest* req : getRequests())
 			req->abort();
-	} elif (btn == getButton (Download))
-	{	str dest = ui->fname->text();
+	}
+	elif (btn == getButton (Download))
+	{	str dest = getInterface()->fname->text();
 		setPrimaryFile (null);
 		setAborted (false);
 
@@ -207,10 +211,10 @@
 				return;
 		}
 
-		m_downloadButton->setEnabled (false);
-		ui->progress->setEnabled (true);
-		ui->fname->setEnabled (false);
-		ui->source->setEnabled (false);
+		getDownloadButton()->setEnabled (false);
+		getInterface()->progress->setEnabled (true);
+		getInterface()->fname->setEnabled (false);
+		getInterface()->source->setEnabled (false);
 		downloadFile (dest, getURL(), true);
 		getButton (Close)->setEnabled (false);
 		getButton (Abort)->setEnabled (true);
@@ -221,19 +225,19 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloader::downloadFile (str dest, str url, bool primary)
-{	const int row = ui->progress->rowCount();
+{	const int row = getInterface()->progress->rowCount();
 
 	// Don't download files repeadetly.
-	if (m_filesToDownload.indexOf (dest) != -1)
+	if (getFilesToDownload().indexOf (dest) != -1)
 		return;
 
 	modifyDestination (dest);
 	log ("DOWNLOAD: %1 -> %2\n", url, PartDownloader::getDownloadPath() + DIRSLASH + dest);
 	PartDownloadRequest* req = new PartDownloadRequest (url, dest, primary, this);
 
-	m_filesToDownload << dest;
-	m_requests << req;
-	ui->progress->insertRow (row);
+	pushToFilesToDownload (dest);
+	pushToRequests (req);
+	getInterface()->progress->insertRow (row);
 	req->setTableRow (row);
 	req->updateToTable();
 }
@@ -244,18 +248,18 @@
 {	bool failed = isAborted();
 
 	// If there is some download still working, we're not finished.
-	for (PartDownloadRequest* req : m_requests)
+	for (PartDownloadRequest* req : getRequests())
 	{	if (!req->isFinished())
 			return;
 
-		if (req->state() == PartDownloadRequest::Failed)
+		if (req->getState() == PartDownloadRequest::EFailed)
 			failed = true;
 	}
 
-	for (PartDownloadRequest* req : m_requests)
+	for (PartDownloadRequest* req : getRequests())
 		delete req;
 
-	m_requests.clear();
+	clearRequests();
 
 	// Update everything now
 	if (getPrimaryFile())
@@ -281,13 +285,13 @@
 QPushButton* PartDownloader::getButton (PartDownloader::Button i)
 {	switch (i)
 	{	case Download:
-			return m_downloadButton;
+			return getDownloadButton();
 
 		case Abort:
-			return qobject_cast<QPushButton*> (ui->buttonBox->button (QDialogButtonBox::Abort));
+			return qobject_cast<QPushButton*> (getInterface()->buttonBox->button (QDialogButtonBox::Abort));
 
 		case Close:
-			return qobject_cast<QPushButton*> (ui->buttonBox->button (QDialogButtonBox::Close));
+			return qobject_cast<QPushButton*> (getInterface()->buttonBox->button (QDialogButtonBox::Close));
 	}
 
 	return null;
@@ -297,18 +301,18 @@
 // -----------------------------------------------------------------------------
 PartDownloadRequest::PartDownloadRequest (str url, str dest, bool primary, PartDownloader* parent) :
 	QObject (parent),
-	m_prompt (parent),
-	m_url (url),
-	m_dest (dest),
-	m_fpath (PartDownloader::getDownloadPath() + DIRSLASH + dest),
-	m_nam (new QNetworkAccessManager),
-	m_firstUpdate (true),
-	m_state (Requesting),
-	m_primary (primary),
-	m_fp (null)
+	m_State (ERequesting),
+	m_Prompt (parent),
+	m_URL (url),
+	m_Destinaton (dest),
+	m_FilePath (PartDownloader::getDownloadPath() + DIRSLASH + dest),
+	m_NAM (new QNetworkAccessManager),
+	m_FirstUpdate (true),
+	m_Primary (primary),
+	m_FilePointer (null)
 {
 	// Make sure that we have a valid destination.
-	str dirpath = dirname (m_fpath);
+	str dirpath = dirname (getFilePath());
 
 	QDir dir (dirpath);
 
@@ -319,10 +323,11 @@
 			critical (fmt (tr ("Couldn't create the directory %1!"), dirpath));
 	}
 
-	m_reply = m_nam->get (QNetworkRequest (QUrl (url)));
-	connect (m_reply, SIGNAL (finished()), this, SLOT (downloadFinished()));
-	connect (m_reply, SIGNAL (readyRead()), this, SLOT (readyRead()));
-	connect (m_reply, SIGNAL (downloadProgress (qint64, qint64)), this, SLOT (downloadProgress (qint64, qint64)));
+	setReply (getNAM()->get (QNetworkRequest (QUrl (url))));
+	connect (getReply(), SIGNAL (finished()), this, SLOT (downloadFinished()));
+	connect (getReply(), SIGNAL (readyRead()), this, SLOT (readyRead()));
+	connect (getReply(), SIGNAL (downloadProgress (qint64, qint64)),
+		this, SLOT (downloadProgress (qint64, qint64)));
 }
 
 // =============================================================================
@@ -332,14 +337,14 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloadRequest::updateToTable()
-{	const int labelcol = PartDownloader::PartLabelColumn,
-				  progcol = PartDownloader::ProgressColumn;
-	QTableWidget* table = m_prompt->ui->progress;
-	QProgressBar* prog;
+{	const int		labelcol = PartDownloader::PartLabelColumn,
+						progcol = PartDownloader::ProgressColumn;
+	QTableWidget*	table = getPrompt()->getInterface()->progress;
+	QProgressBar*	prog;
 
-	switch (m_state)
-	{	case Requesting:
-		case Downloading:
+	switch (getState())
+	{	case ERequesting:
+		case EDownloading:
 		{	prog = qobject_cast<QProgressBar*> (table->cellWidget (getTableRow(), progcol));
 
 			if (!prog)
@@ -347,14 +352,17 @@
 				table->setCellWidget (getTableRow(), progcol, prog);
 			}
 
-			prog->setRange (0, m_bytesTotal);
-			prog->setValue (m_bytesRead);
+			prog->setRange (0, getBytesTotal());
+			prog->setValue (getBytesRead());
 		} break;
 
-		case Finished:
-		case Failed:
-		{	QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" :
-									  "<b><span style=\"color: #800\">FAILED</span></b>");
+		case EFinished:
+		case EFailed:
+		{	const str text = (getState() == EFinished)
+				? "<b><span style=\"color: #080\">FINISHED</span></b>"
+				: "<b><span style=\"color: #800\">FAILED</span></b>";
+
+			QLabel* lb = new QLabel (text);
 			lb->setAlignment (Qt::AlignCenter);
 			table->setCellWidget (getTableRow(), progcol, lb);
 		} break;
@@ -362,8 +370,8 @@
 
 	QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (getTableRow(), labelcol));
 
-	if (m_firstUpdate)
-	{	lb = new QLabel (fmt ("<b>%1</b>", m_dest), table);
+	if (isFirstUpdate())
+	{	lb = new QLabel (fmt ("<b>%1</b>", getDestinaton()), table);
 		table->setCellWidget (getTableRow(), labelcol, lb);
 	}
 
@@ -371,44 +379,45 @@
 	if (table->columnWidth (labelcol) < lb->width())
 		table->setColumnWidth (labelcol, lb->width());
 
-	m_firstUpdate = false;
+	setFirstUpdate (true);
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloadRequest::downloadFinished()
-{	if (m_reply->error() != QNetworkReply::NoError)
-	{	if (m_primary && !m_prompt->isAborted())
-			critical (m_reply->errorString());
+{	if (getReply()->error() != QNetworkReply::NoError)
+	{	if (isPrimary() && !getPrompt()->isAborted())
+			critical (getReply()->errorString());
 
-		m_state = Failed;
-	} elif (state() != Failed)
-		m_state = Finished;
+		setState (EFailed);
+	}
+	elif (getState() != EFailed)
+		setState (EFinished);
 
-	m_bytesRead = m_bytesTotal;
+	setBytesRead (getBytesTotal());
 	updateToTable();
 
-	if (m_fp)
-	{	m_fp->close();
-		delete m_fp;
-		m_fp = null;
+	if (getFilePointer())
+	{	getFilePointer()->close();
+		delete getFilePointer();
+		setFilePointer (null);
 
-		if (m_state == Failed)
-			QFile::remove (m_fpath);
+		if (getState() == EFailed)
+			QFile::remove (getFilePath());
 	}
 
-	if (m_state != Finished)
-	{	m_prompt->checkIfFinished();
+	if (getState() != EFinished)
+	{	getPrompt()->checkIfFinished();
 		return;
 	}
 
 	// Try to load this file now.
-	LDFile* f = openDATFile (m_fpath, false);
+	LDFile* f = openDATFile (getFilePath(), false);
 
 	if (!f)
 		return;
 
-	f->setImplicit (!m_primary);
+	f->setImplicit (!isPrimary());
 
 	// Iterate through this file and check for errors. If there's any that stems
 	// from unknown file references, try resolve that by downloading the reference.
@@ -421,73 +430,67 @@
 			continue;
 
 		str dest = err->getFileReferenced();
-		m_prompt->modifyDestination (dest);
-		m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false);
+		getPrompt()->modifyDestination (dest);
+		getPrompt()->downloadFile (dest, g_unofficialLibraryURL + dest, false);
 	}
 
-	if (m_primary)
-	{	addRecentFile (m_fpath);
-		m_prompt->setPrimaryFile (f);
+	if (isPrimary())
+	{	addRecentFile (getFilePath());
+		getPrompt()->setPrimaryFile (f);
 	}
 
-	m_prompt->checkIfFinished();
+	getPrompt()->checkIfFinished();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloadRequest::downloadProgress (int64 recv, int64 total)
-{	m_bytesRead = recv;
-	m_bytesTotal = total;
-	m_state = Downloading;
+{	setBytesRead (recv);
+	setBytesTotal (total);
+	setState (EDownloading);
 	updateToTable();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloadRequest::readyRead()
-{	if (state() == Failed)
+{	if (getState() == EFailed)
 		return;
 
-	if (m_fp == null)
-	{	m_fpath.replace ("\\", "/");
+	if (getFilePointer() == null)
+	{	replaceInFilePath ("\\", "/");
 
 		// We have already asked the user whether we can overwrite so we're good
 		// to go here.
-		m_fp = new QFile (m_fpath.toLocal8Bit());
+		setFilePointer (new QFile (getFilePath().toLocal8Bit()));
 
-		if (!m_fp->open (QIODevice::WriteOnly))
-		{	critical (fmt (tr ("Couldn't open %1 for writing: %2"), m_fpath, strerror (errno)));
-			m_state = Failed;
-			m_reply->abort();
+		if (!getFilePointer()->open (QIODevice::WriteOnly))
+		{	critical (fmt (tr ("Couldn't open %1 for writing: %2"), getFilePath(), strerror (errno)));
+			setState (EFailed);
+			getReply()->abort();
 			updateToTable();
-			m_prompt->checkIfFinished();
+			getPrompt()->checkIfFinished();
 			return;
 		}
 	}
 
-	m_fp->write (m_reply->readAll());
+	getFilePointer()->write (getReply()->readAll());
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 bool PartDownloadRequest::isFinished() const
-{	return m_state == Finished || m_state == Failed;
-}
-
-// =============================================================================
-// -----------------------------------------------------------------------------
-const PartDownloadRequest::State& PartDownloadRequest::state() const
-{	return m_state;
+{	return getState() == EFinished || getState() == EFailed;
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 void PartDownloadRequest::abort()
-{	m_reply->abort();
+{	getReply()->abort();
 }
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (DownloadFrom, 0)
-{	PartDownloader::k_download();
+{	PartDownloader::staticBegin();
 }
--- a/src/download.h	Fri Dec 06 21:30:58 2013 +0200
+++ b/src/download.h	Sat Dec 07 00:01:20 2013 +0200
@@ -35,13 +35,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 class PartDownloader : public QDialog
-{	Q_OBJECT
-	PROPERTY (public,	LDFile*, PrimaryFile,	NO_OPS,		STOCK_WRITE)
-	PROPERTY (public,	bool,		Aborted,			BOOL_OPS,	STOCK_WRITE)
-
-	public:
-		constexpr static const char* k_UnofficialURL = "http://ldraw.org/library/unofficial/";
-
+{	typedefs:
 		enum Source
 		{	PartsTracker,
 			CustomURL,
@@ -58,51 +52,69 @@
 			ProgressColumn,
 		};
 
-		explicit PartDownloader (QWidget* parent = null);
-		virtual ~PartDownloader();
-		str getURL() const;
-		static str getDownloadPath();
-		Source getSource() const;
-		void downloadFile (str dest, str url, bool primary);
-		void modifyDestination (str& dest) const;
-		QPushButton* getButton (Button i);
-		static void k_download();
+		using RequestList = QList<PartDownloadRequest*>;
+
+	properties:
+		Q_OBJECT
+		PROPERTY (public,		LDFile*, 			PrimaryFile,		NO_OPS,		STOCK_WRITE)
+		PROPERTY (public,		bool,					Aborted,				BOOL_OPS,	STOCK_WRITE)
+		PROPERTY (private,	Ui_DownloadFrom*,	Interface,			NO_OPS,		STOCK_WRITE)
+		PROPERTY (private,	QStringList,		FilesToDownload,	LIST_OPS,	STOCK_WRITE)
+		PROPERTY (private,	RequestList,		Requests,			LIST_OPS,	STOCK_WRITE)
+		PROPERTY (private,	QPushButton*,		DownloadButton,	NO_OPS,		STOCK_WRITE)
+
+	public methods:
+		explicit			PartDownloader (QWidget* parent = null);
+		virtual			~PartDownloader();
+
+		void				downloadFile (str dest, str url, bool primary);
+		QPushButton*	getButton (Button i);
+		str				getURL() const;
+		Source			getSource() const;
+		void				modifyDestination (str& dest) const;
+
+		static str		getDownloadPath();
+		static void		staticBegin();
 
 	public slots:
-		void sourceChanged (int i);
-		void checkIfFinished();
-		void buttonClicked (QAbstractButton* btn);
-
-	protected:
-		Ui_DownloadFrom* ui;
-		friend class PartDownloadRequest;
-
-	private:
-		QStringList m_filesToDownload;
-		QList<PartDownloadRequest*> m_requests;
-		QPushButton* m_downloadButton;
+		void				buttonClicked (QAbstractButton* btn);
+		void				checkIfFinished();
+		void				sourceChanged (int i);
 };
 
 // =============================================================================
 // -----------------------------------------------------------------------------
 class PartDownloadRequest : public QObject
-{	Q_OBJECT
-	PROPERTY (public,	int, TableRow,	NUM_OPS,	STOCK_WRITE)
-
-	public:
-		enum State
-		{	Requesting,
-			Downloading,
-			Finished,
-			Failed,
+{	typedefs:
+		enum EState
+		{	ERequesting,
+			EDownloading,
+			EFinished,
+			EFailed,
 		};
 
+	properties:
+		Q_OBJECT
+		PROPERTY (public,		int,							TableRow,		NUM_OPS,		STOCK_WRITE)
+		PROPERTY (private,	EState,						State,			NO_OPS,		STOCK_WRITE)
+		PROPERTY (private,	PartDownloader*,			Prompt,			NO_OPS,		STOCK_WRITE)
+		PROPERTY (private,	str,							URL,				STR_OPS,		STOCK_WRITE)
+		PROPERTY (private,	str,							Destinaton,		STR_OPS,		STOCK_WRITE)
+		PROPERTY (private,	str,							FilePath,		STR_OPS,		STOCK_WRITE)
+		PROPERTY (private,	QNetworkAccessManager*,	NAM,				NO_OPS,		STOCK_WRITE)
+		PROPERTY (private,	QNetworkReply*,			Reply,			NO_OPS,		STOCK_WRITE)
+		PROPERTY (private,	bool,							FirstUpdate,	BOOL_OPS,	STOCK_WRITE)
+		PROPERTY (private,	int64,						BytesRead,		NUM_OPS,		STOCK_WRITE)
+		PROPERTY (private,	int64,						BytesTotal,		NUM_OPS,		STOCK_WRITE)
+		PROPERTY (private,	bool,							Primary,			BOOL_OPS,	STOCK_WRITE)
+		PROPERTY (private,	QFile*,						FilePointer,	NO_OPS,		STOCK_WRITE)
+
+	public methods:
 		explicit PartDownloadRequest (str url, str dest, bool primary, PartDownloader* parent);
 		PartDownloadRequest (const PartDownloadRequest&) = delete;
 		virtual ~PartDownloadRequest();
 		void updateToTable();
 		bool isFinished() const;
-		const State& state() const;
 
 		void operator= (const PartDownloadRequest&) = delete;
 
@@ -111,17 +123,6 @@
 		void readyRead();
 		void downloadProgress (qint64 recv, qint64 total);
 		void abort();
-
-	private:
-		PartDownloader* m_prompt;
-		str m_url, m_dest, m_fpath;
-		QNetworkAccessManager* m_nam;
-		QNetworkReply* m_reply;
-		bool m_firstUpdate;
-		State m_state;
-		int64 m_bytesRead, m_bytesTotal;
-		bool m_primary;
-		QFile* m_fp;
 };
 
 #endif // LDFORGE_DOWNLOAD_H
--- a/src/main.h	Fri Dec 06 21:30:58 2013 +0200
+++ b/src/main.h	Sat Dec 07 00:01:20 2013 +0200
@@ -46,6 +46,7 @@
 #include <stdarg.h>
 #include <QString>
 #include <QMutex>
+#include <QTextFormat>
 
 #include "property.h"
 #include "config.h"
@@ -119,6 +120,10 @@
 QString versionMoniker();
 QString fullVersionString();
 
+#define properties private
+#define typedefs public
+#define methods
+
 // -----------------------------------------------------------------------------
 #ifdef IN_IDE_PARSER // KDevelop workarounds:
 # error IN_IDE_PARSER is defined (this code is only for KDevelop workarounds)
--- a/src/property.h	Fri Dec 06 21:30:58 2013 +0200
+++ b/src/property.h	Sat Dec 07 00:01:20 2013 +0200
@@ -39,6 +39,7 @@
 #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 GET_READ_METHOD_LIST_OPS( NAME ) get##NAME()
 
 #define DEFINE_WRITE_METHOD_STOCK_WRITE( TYPE, NAME )	\
 		inline void set##NAME( TYPE const& NAME##_ )		\
@@ -86,4 +87,15 @@
 		{	set##NAME( !m_##NAME );						\
 		}
 
+#define DEFINE_PROPERTY_LIST_OPS( TYPE, NAME )				\
+		void pushTo##NAME( const TYPE::value_type& a )		\
+		{	TYPE tmp( m_##NAME );									\
+			tmp.push_back( a );										\
+			set##NAME( tmp );											\
+		}																	\
+																			\
+		inline void clear##NAME()									\
+		{	set##NAME( TYPE() );										\
+		}
+
 #endif // LDFORGE_PROPERTY_H
\ No newline at end of file

mercurial