- replaced the fmt/log/dlog/fprint macros in favor of template functions. renamed to format, print, dprint and fprint respectively.

Wed, 05 Mar 2014 12:47:00 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Wed, 05 Mar 2014 12:47:00 +0200
changeset 644
93dcd1a0e4bd
parent 643
a79277000830
child 645
c0708f2d22b3

- replaced the fmt/log/dlog/fprint macros in favor of template functions. renamed to format, print, dprint and fprint respectively.

CMakeLists.txt file | annotate | diff | comparison | revisions
src/AddObjectDialog.cc file | annotate | diff | comparison | revisions
src/ColorSelector.cc file | annotate | diff | comparison | revisions
src/Colors.cc file | annotate | diff | comparison | revisions
src/Configuration.cc file | annotate | diff | comparison | revisions
src/ConfigurationDialog.cc file | annotate | diff | comparison | revisions
src/CrashCatcher.cc file | annotate | diff | comparison | revisions
src/Dialogs.cc file | annotate | diff | comparison | revisions
src/Document.cc file | annotate | diff | comparison | revisions
src/EditHistory.cc file | annotate | diff | comparison | revisions
src/ExternalPrograms.cc file | annotate | diff | comparison | revisions
src/Format.h file | annotate | diff | comparison | revisions
src/GLRenderer.cc file | annotate | diff | comparison | revisions
src/GLRenderer.h file | annotate | diff | comparison | revisions
src/LDObject.cc file | annotate | diff | comparison | revisions
src/Macros.h file | annotate | diff | comparison | revisions
src/Main.cc file | annotate | diff | comparison | revisions
src/Main.h file | annotate | diff | comparison | revisions
src/MainWindow.cc file | annotate | diff | comparison | revisions
src/MessageLog.cc file | annotate | diff | comparison | revisions
src/Misc.cc file | annotate | diff | comparison | revisions
src/Misc.h file | annotate | diff | comparison | revisions
src/PartDownloader.cc file | annotate | diff | comparison | revisions
src/Primitives.cc file | annotate | diff | comparison | revisions
src/Types.cc file | annotate | diff | comparison | revisions
src/Types.h file | annotate | diff | comparison | revisions
src/actions/EditActions.cc file | annotate | diff | comparison | revisions
src/actions/MainActions.cc file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Wed Mar 05 05:31:07 2014 +0200
+++ b/CMakeLists.txt	Wed Mar 05 12:47:00 2014 +0200
@@ -72,6 +72,7 @@
 	src/Configuration.h
 	src/MainWindow.h
 	src/EditHistory.h
+	src/Format.h
 )
 
 set (LDForgeForms
--- a/src/AddObjectDialog.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/AddObjectDialog.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -126,7 +126,7 @@
 				for (Primitive& prim : cat->prims)
 				{
 					SubfileListItem* item = new SubfileListItem (parentItem, &prim);
-					item->setText (0, fmt ("%1 - %2", prim.name, prim.title));
+					item->setText (0, format ("%1 - %2", prim.name, prim.title));
 					subfileItems << item;
 
 					// If this primitive is the one the current object points to,
@@ -152,11 +152,11 @@
 
 		default:
 		{
-			critical (fmt ("Unhandled LDObject type %1 (%2) in AddObjectDialog", (int) type, typeName));
+			critical (format ("Unhandled LDObject type %1 (%2) in AddObjectDialog", (int) type, typeName));
 		} return;
 	}
 
-	QPixmap icon = getIcon (fmt ("add-%1", typeName));
+	QPixmap icon = getIcon (format ("add-%1", typeName));
 	LDObject* defaults = LDObject::getDefault (type);
 
 	lb_typeIcon = new QLabel;
@@ -261,7 +261,7 @@
 	QWidget::connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject()));
 	layout->addWidget (bbx_buttons, 5, 0, 1, 4);
 	setLayout (layout);
-	setWindowTitle (fmt (tr ("Edit %1"), typeName));
+	setWindowTitle (format (tr ("Edit %1"), typeName));
 
 	setWindowIcon (icon);
 	defaults->destroy();
@@ -277,7 +277,7 @@
 	button->setAutoFillBackground (true);
 
 	if (col)
-		button->setStyleSheet (fmt ("background-color: %1", col->hexcode));
+		button->setStyleSheet (format ("background-color: %1", col->hexcode));
 }
 
 // =============================================================================
@@ -412,7 +412,7 @@
 
 			if (!file)
 			{
-				critical (fmt ("Couldn't open `%1': %2", name, strerror (errno)));
+				critical (format ("Couldn't open `%1': %2", name, strerror (errno)));
 				return;
 			}
 
--- a/src/ColorSelector.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/ColorSelector.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -111,7 +111,7 @@
 
 		QPen pen (info->edgeColor, penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
 		m_scene->addRect (x, y, w, w, pen, col);
-		QGraphicsTextItem* numtext = m_scene->addText (fmt ("%1", i));
+		QGraphicsTextItem* numtext = m_scene->addText (format ("%1", i));
 		numtext->setDefaultTextColor ( (luma (col) < 80) ? Qt::white : Qt::black);
 		numtext->setPos (x, y);
 
@@ -147,7 +147,7 @@
 		return;
 	}
 
-	ui->colorLabel->setText (fmt ("%1 - %2", selection()->index, selection()->name));
+	ui->colorLabel->setText (format ("%1 - %2", selection()->index, selection()->name));
 }
 
 // =============================================================================
--- a/src/Colors.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Colors.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -36,7 +36,7 @@
 void initColors()
 {
 	LDColor* col;
-	log ("%1: initializing color information.\n", __func__);
+	print ("Initializing color information.\n");
 
 	// Always make sure there's 16 and 24 available. They're special like that.
 	col = new LDColor;
--- a/src/Configuration.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Configuration.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -61,7 +61,7 @@
 bool Config::load()
 {
 	QSettings* settings = getSettingsObject();
-	log ("config::load: Loading configuration file from %1\n", settings->fileName());
+	print ("config::load: Loading configuration file from %1\n", settings->fileName());
 
 	for (Config* cfg : g_configPointers)
 	{
@@ -79,12 +79,12 @@
 }
 
 // =============================================================================
+//
 // Save the configuration to disk
-// =============================================================================
+//
 bool Config::save()
 {
 	QSettings* settings = getSettingsObject();
-	log ("Saving configuration to %1...\n", settings->fileName());
 
 	for (Config* cfg : g_configs)
 	{
@@ -95,6 +95,7 @@
 	}
 
 	settings->sync();
+	print ("Configuration saved to %1.\n", settings->fileName());
 	settings->deleteLater();
 	return true;
 }
--- a/src/ConfigurationDialog.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/ConfigurationDialog.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -218,10 +218,10 @@
 	{
 		// Icon
 		lb_gridIcons[i] = new QLabel;
-		lb_gridIcons[i]->setPixmap (getIcon (fmt ("grid-%1", QString (g_GridInfo[i].name).toLower())));
+		lb_gridIcons[i]->setPixmap (getIcon (format ("grid-%1", QString (g_GridInfo[i].name).toLower())));
 
 		// Text label
-		lb_gridLabels[i] = new QLabel (fmt ("%1:", g_GridInfo[i].name));
+		lb_gridLabels[i] = new QLabel (format ("%1:", g_GridInfo[i].name));
 
 		QHBoxLayout* labellayout = new QHBoxLayout;
 		labellayout->addWidget (lb_gridIcons[i]);
@@ -587,7 +587,7 @@
 {
 	button->setIcon (getIcon ("colorselect"));
 	button->setAutoFillBackground (true);
-	button->setStyleSheet (fmt ("background-color: %1", value));
+	button->setStyleSheet (format ("background-color: %1", value));
 }
 
 // =============================================================================
@@ -693,7 +693,7 @@
 	}
 
 	assert (info != null);
-	QString fpath = QFileDialog::getOpenFileName (this, fmt ("Path to %1", info->name), *info->path, g_extProgPathFilter);
+	QString fpath = QFileDialog::getOpenFileName (this, format ("Path to %1", info->name), *info->path, g_extProgPathFilter);
 
 	if (fpath.isEmpty())
 		return;
@@ -720,7 +720,7 @@
 	QAction* act = item->action();
 	QString label = act->iconText();
 	QString keybind = item->keyConfig()->getValue().toString();
-	item->setText (fmt ("%1 (%2)", label, keybind));
+	item->setText (format ("%1 (%2)", label, keybind));
 }
 
 // =============================================================================
@@ -738,7 +738,7 @@
 		if (entry.isSeparator())
 			val += '|';
 		else
-			val += fmt ("%1", entry.color()->index);
+			val += format ("%1", entry.color()->index);
 	}
 
 	return val;
@@ -791,7 +791,7 @@
 	if (seq == QKeySequence())
 		shortcut = "&lt;empty&gt;";
 
-	QString text = fmt ("<center><b>%1</b></center>", shortcut);
+	QString text = format ("<center><b>%1</b></center>", shortcut);
 	lb_output->setText (text);
 }
 
--- a/src/CrashCatcher.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/CrashCatcher.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -24,7 +24,11 @@
 #include <QMessageBox>
 #include <unistd.h>
 #include <signal.h>
-#include <sys/prctl.h>
+
+#ifdef Q_OS_LINUX
+# include <sys/prctl.h>
+#endif
+
 #include "CrashCatcher.h"
 #include "Types.h"
 #include "Dialogs.h"
@@ -44,7 +48,7 @@
 });
 
 // =============================================================================
-// =============================================================================
+//
 static void handleCrash (int sig)
 {
 	printf ("%s: crashed with signal %d, launching gdb\n", __func__, sig);
@@ -63,7 +67,7 @@
 
 	if (commandsFile.open())
 	{
-		commandsFile.write (fmt ("attach %1\n", pid).toLocal8Bit());
+		commandsFile.write (format ("attach %1\n", pid).toLocal8Bit());
 		commandsFile.write (QString ("backtrace full\n").toLocal8Bit());
 		commandsFile.write (QString ("detach\n").toLocal8Bit());
 		commandsFile.write (QString ("quit").toLocal8Bit());
@@ -78,13 +82,15 @@
 	// Linux doesn't allow ptrace to be used on anything but direct child processes
 	// so we need to use prctl to register an exception to this to allow GDB attach to us.
 	// We need to do this now and no earlier because only now we actually know GDB's PID.
+#ifdef Q_OS_LINUX
 	prctl (PR_SET_PTRACER, proc.pid(), 0, 0, 0);
+#endif
 
 	proc.waitForFinished (1000);
 	QString output = QString (proc.readAllStandardOutput());
 	QString err = QString (proc.readAllStandardError());
 
-	bombBox (fmt ("<h3>Program crashed with signal %1</h3>\n\n"
+	bombBox (format ("<h3>Program crashed with signal %1</h3>\n\n"
 		"%2"
 		"<p><b>GDB <tt>stdout</tt>:</b></p><pre>%3</pre>\n"
 		"<p><b>GDB <tt>stderr</tt>:</b></p><pre>%4</pre>",
@@ -92,7 +98,7 @@
 }
 
 // =============================================================================
-// =============================================================================
+//
 void initCrashCatcher()
 {
 	struct sigaction sighandler;
@@ -103,19 +109,20 @@
 	for (int sig : g_signalsToCatch)
 		sigaction (sig, &sighandler, null);
 
-	log ("%1: crash catcher hooked to signals: %2\n", __func__, g_signalsToCatch);
+	print ("%1: crash catcher hooked to signals: %2\n", __func__, g_signalsToCatch);
 }
 #endif // #ifdef __unix__
 
 // =============================================================================
+//
 // This function must be readily available in both Windows and Linux. We display
 // the bomb box straight in Windows while in Linux we let abort() trigger the
 // signal handler, which will cause the usual bomb box with GDB diagnostics.
 // Said prompt will embed the assertion failure information.
-// =============================================================================
+//
 void assertionFailure (const char* file, int line, const char* funcname, const char* expr)
 {
-	QString errmsg = fmt (
+	QString errmsg = format (
 		"<p><b>File</b>: <tt>%1</tt><br />"
 		"<b>Line</b>: <tt>%2</tt><br />"
 		"<b>Function:</b> <tt>%3</tt></p>"
--- a/src/Dialogs.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Dialogs.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -242,7 +242,7 @@
 {
 	if (LDPaths::tryConfigure (filename()) == false)
 	{
-		ui->status->setText (fmt ("<span style=\"color:#700; \">%1</span>", LDPaths::getError()));
+		ui->status->setText (format ("<span style=\"color:#700; \">%1</span>", LDPaths::getError()));
 		okButton()->setEnabled (false);
 		return;
 	}
@@ -290,7 +290,7 @@
 // =============================================================================
 void OpenProgressDialog::updateValues()
 {
-	ui->progressText->setText (fmt ("Parsing... %1 / %2", progress(), numLines()));
+	ui->progressText->setText (format ("Parsing... %1 / %2", progress(), numLines()));
 	ui->progressBar->setValue (progress());
 }
 
@@ -354,7 +354,7 @@
 	ui.buttonBox->addButton (static_cast<QAbstractButton*> (mailButton), QDialogButtonBox::HelpRole);
 	connect (ui.buttonBox, SIGNAL (helpRequested()), this, SLOT (slot_mail()));
 
-	setWindowTitle (fmt (tr ("About %1"), APPNAME));
+	setWindowTitle (format (tr ("About %1"), APPNAME));
 }
 
 // =============================================================================
--- a/src/Document.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Document.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -89,9 +89,9 @@
 			return false;
 		}
 
-		pathInfo.partsPath = fmt ("%1" DIRSLASH "parts", path);
-		pathInfo.LDConfigPath = fmt ("%1" DIRSLASH "LDConfig.ldr", path);
-		pathInfo.primsPath = fmt ("%1" DIRSLASH "p", path);
+		pathInfo.partsPath = format ("%1" DIRSLASH "parts", path);
+		pathInfo.LDConfigPath = format ("%1" DIRSLASH "LDConfig.ldr", path);
+		pathInfo.primsPath = format ("%1" DIRSLASH "p", path);
 
 		return true;
 	}
@@ -179,7 +179,7 @@
 		g_logoedStud2 = null;
 
 	g_win->updateDocumentList();
-	log ("Closed %1", name());
+	print ("Closed %1", name());
 }
 
 // =============================================================================
@@ -244,7 +244,7 @@
 		if (doc->fullPath().isEmpty())
 			continue;
 
-		QString partpath = fmt ("%1/%2", dirname (doc->fullPath()), relpath);
+		QString partpath = format ("%1/%2", dirname (doc->fullPath()), relpath);
 		QFile f (partpath);
 
 		if (f.exists())
@@ -272,7 +272,7 @@
 		return relpath;
 
 	// Try with just the LDraw path first
-	fullPath = fmt ("%1" DIRSLASH "%2", io_ldpath, relpath);
+	fullPath = format ("%1" DIRSLASH "%2", io_ldpath, relpath);
 
 	if (QFile::exists (fullPath))
 		return fullPath;
@@ -285,7 +285,7 @@
 		{
 			for (const QString& subdir : initlist<QString> ({ "parts", "p" }))
 			{
-				fullPath = fmt ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relpath);
+				fullPath = format ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relpath);
 
 				if (QFile::exists (fullPath))
 					return fullPath;
@@ -299,7 +299,7 @@
 
 QFile* openLDrawFile (QString relpath, bool subdirs, QString* pathpointer)
 {
-	log ("Opening %1...\n", relpath);
+	print ("Opening %1...\n", relpath);
 	QString path = findLDrawFilePath (relpath, subdirs);
 
 	if (pathpointer != null)
@@ -382,7 +382,7 @@
 		// Check for parse errors and warn about tthem
 		if (obj->type() == LDObject::EError)
 		{
-			log ("Couldn't parse line #%1: %2", progress() + 1, static_cast<LDError*> (obj)->reason());
+			print ("Couldn't parse line #%1: %2", progress() + 1, static_cast<LDError*> (obj)->reason());
 
 			if (warnings() != null)
 				(*warnings())++;
@@ -499,7 +499,7 @@
 	LDDocument* load = new LDDocument;
 	load->setFullPath (fullpath);
 	load->setName (LDDocument::shortenName (load->fullPath()));
-	dlog ("name: %1 (%2)", load->name(), load->fullPath());
+	dprint ("name: %1 (%2)", load->name(), load->fullPath());
 	g_loadedFiles << load;
 
 	// Don't take the file loading as actual edits to the file
@@ -524,7 +524,7 @@
 	{
 		LDDocument::setCurrent (load);
 		g_win->R()->setDocument (load);
-		log (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings);
+		print (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings);
 	}
 
 	load->history()->setIgnoring (false);
@@ -541,7 +541,7 @@
 	// If we have unsaved changes, warn and give the option of saving.
 	if (hasUnsavedChanges())
 	{
-		QString message = fmt (tr ("There are unsaved changes to %1. Should it be saved?"),
+		QString message = format (tr ("There are unsaved changes to %1. Should it be saved?"),
 			(name().length() > 0) ? name() : tr ("<anonymous>"));
 
 		int button = msgbox::question (g_win, tr ("Unsaved Changes"), message,
@@ -565,7 +565,7 @@
 
 				if (!save())
 				{
-					message = fmt (tr ("Failed to save %1 (%2)\nDo you still want to close?"),
+					message = format (tr ("Failed to save %1 (%2)\nDo you still want to close?"),
 						name(), strerror (errno));
 
 					if (msgbox::critical (g_win, tr ("Save Failure"), message,
@@ -683,7 +683,7 @@
 		{
 			// Tell the user loading failed.
 			setlocale (LC_ALL, "C");
-			critical (fmt (QObject::tr ("Failed to open %1: %2"), path, strerror (errno)));
+			critical (format (QObject::tr ("Failed to open %1: %2"), path, strerror (errno)));
 		}
 
 		g_loadingMainFile = false;
@@ -696,7 +696,7 @@
 	if (documentToReplace != null)
 	{
 		for (LDDocumentPointer* ptr : documentToReplace->references())
-		{	dlog ("ptr: %1 (%2)\n",
+		{	dprint ("ptr: %1 (%2)\n",
 				ptr, ptr->pointer() ? ptr->pointer()->name() : "<null>");
 
 			*ptr = file;
@@ -742,7 +742,7 @@
 		if (nameComment->text().left (6) == "Name: ")
 		{
 			QString newname = shortenName (savepath);
-			nameComment->setText (fmt ("Name: %1", newname));
+			nameComment->setText (format ("Name: %1", newname));
 			g_win->buildObjList();
 		}
 	}
@@ -788,7 +788,7 @@
 void checkTokenCount (QString line, const QStringList& tokens, int num)
 {
 	if (tokens.size() != num)
-		throw LDParseError (line, fmt ("Bad amount of tokens, expected %1, got %2", num, tokens.size()));
+		throw LDParseError (line, format ("Bad amount of tokens, expected %1, got %2", num, tokens.size()));
 }
 
 // =============================================================================
@@ -805,7 +805,7 @@
 		tokens[i].toDouble (&ok);
 
 		if (!ok && !scient.exactMatch (tokens[i]))
-			throw LDParseError (line, fmt ("Token #%1 was `%2`, expected a number (matched length: %3)", (i + 1), tokens[i], scient.matchedLength()));
+			throw LDParseError (line, format ("Token #%1 was `%2`, expected a number (matched length: %3)", (i + 1), tokens[i], scient.matchedLength()));
 	}
 }
 
@@ -854,7 +854,7 @@
 				if (tokens.size() > 2 && tokens[1] == "BFC")
 				{
 					for (int i = 0; i < LDBFC::NumStatements; ++i)
-						if (comm == fmt ("BFC %1", LDBFC::k_statementStrings [i]))
+						if (comm == format ("BFC %1", LDBFC::k_statementStrings [i]))
 							return new LDBFC ( (LDBFC::Statement) i);
 
 					// MLCAD is notorious for stuffing these statements in parts it
@@ -931,7 +931,7 @@
 				// here because the error object needs the document reference.
 				if (!load)
 				{
-					LDError* obj = new LDError (line, fmt ("Could not open %1", tokens[14]));
+					LDError* obj = new LDError (line, format ("Could not open %1", tokens[14]));
 					obj->setFileReferenced (tokens[14]);
 					return obj;
 				}
@@ -1047,7 +1047,7 @@
 			if (fileInfo)
 				ref->setFileInfo (fileInfo);
 			else
-				ref->replace (new LDError (ref->asText(), fmt ("Could not open %1", ref->fileInfo()->name())));
+				ref->replace (new LDError (ref->asText(), format ("Could not open %1", ref->fileInfo()->name())));
 		}
 
 		// Reparse gibberish files. It could be that they are invalid because
@@ -1069,7 +1069,7 @@
 
 #ifdef DEBUG
 	if (!isImplicit())
-		dlog ("Added object #%1 (%2)\n", obj->id(), obj->typeName());
+		dprint ("Added object #%1 (%2)\n", obj->id(), obj->typeName());
 #endif
 
 	obj->setDocument (this);
@@ -1095,7 +1095,7 @@
 
 #ifdef DEBUG
 	if (!isImplicit())
-		dlog ("Inserted object #%1 (%2) at %3\n", obj->id(), obj->typeName(), pos);
+		dprint ("Inserted object #%1 (%2) at %3\n", obj->id(), obj->typeName(), pos);
 #endif
 }
 
@@ -1305,7 +1305,7 @@
 		g_win->updateTitle();
 		g_win->R()->setDocument (f);
 		g_win->R()->repaint();
-		log ("Changed file to %1", f->getDisplayName());
+		print ("Changed file to %1", f->getDisplayName());
 	}
 }
 
@@ -1350,7 +1350,7 @@
 	g_logoedStud = openDocument ("stud-logo.dat", true);
 	g_logoedStud2 = openDocument ("stud2-logo.dat", true);
 
-	log (LDDocument::tr ("Logoed studs loaded.\n"));
+	print (LDDocument::tr ("Logoed studs loaded.\n"));
 }
 
 // =============================================================================
--- a/src/EditHistory.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/EditHistory.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -50,7 +50,7 @@
 	m_position--;
 	g_win->refresh();
 	g_win->updateActions();
-	dlog ("Position is now %1", position());
+	dprint ("Position is now %1", position());
 	setIgnoring (false);
 }
 
@@ -71,7 +71,7 @@
 	setPosition (position() + 1);
 	g_win->refresh();
 	g_win->updateActions();
-	dlog ("Position is now %1", position());
+	dprint ("Position is now %1", position());
 	setIgnoring (false);
 }
 
@@ -84,7 +84,7 @@
 			delete change;
 
 	m_changesets.clear();
-	dlog ("History: cleared");
+	dprint ("History: cleared");
 }
 
 // =============================================================================
@@ -104,7 +104,7 @@
 		m_changesets.removeLast();
 	}
 
-	dlog ("History: step added (%1 changes)", m_currentChangeset.size());
+	dprint ("History: step added (%1 changes)", m_currentChangeset.size());
 	m_changesets << m_currentChangeset;
 	m_currentChangeset.clear();
 	setPosition (position() + 1);
@@ -123,7 +123,7 @@
 
 	entry->setParent (this);
 	m_currentChangeset << entry;
-	dlog ("History: added entry of type %1", entry->getTypeName());
+	dprint ("History: added entry of type %1", entry->getTypeName());
 }
 
 // =============================================================================
--- a/src/ExternalPrograms.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/ExternalPrograms.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -144,7 +144,7 @@
 				wineblurb = "make sure Wine is installed and ";
 #endif
 
-			return fmt ("Program failed to start, %1check your permissions", wineblurb);
+			return format ("Program failed to start, %1check your permissions", wineblurb);
 		} break;
 
 		case QProcess::Crashed:
@@ -158,7 +158,7 @@
 			return "Unknown error";
 
 		case QProcess::Timedout:
-			return fmt ("Timed out (30 seconds)");
+			return format ("Timed out (30 seconds)");
 	}
 
 	return "";
@@ -194,7 +194,7 @@
 
 	if (!f.open (QIODevice::WriteOnly | QIODevice::Text))
 	{
-		critical (fmt ("Couldn't open temporary file %1 for writing: %2\n", fname, f.errorString()));
+		critical (format ("Couldn't open temporary file %1 for writing: %2\n", fname, f.errorString()));
 		return;
 	}
 
@@ -245,7 +245,7 @@
 	}
 #endif // _WIN32
 
-	log ("cmdline: %1 %2\n", path, argv.join (" "));
+	print ("Running command: %1 %2\n", path, argv.join (" "));
 
 	if (!input.open())
 		return false;
@@ -258,7 +258,7 @@
 
 	if (!proc.waitForStarted())
 	{
-		critical (fmt ("Couldn't start %1: %2\n", g_extProgNames[prog], processErrorString (prog, proc)));
+		critical (format ("Couldn't start %1: %2\n", g_extProgNames[prog], processErrorString (prog, proc)));
 		return false;
 	}
 
@@ -275,11 +275,11 @@
 
 	// Check the return code
 	if (proc.exitCode() != 0)
-		err = fmt ("Program exited abnormally (return code %1).",  proc.exitCode());
+		err = format ("Program exited abnormally (return code %1).",  proc.exitCode());
 
 	if (!err.isEmpty())
 	{
-		critical (fmt ("%1 failed: %2\n", g_extProgNames[prog], err));
+		critical (format ("%1 failed: %2\n", g_extProgNames[prog], err));
 		return false;
 	}
 
@@ -299,7 +299,7 @@
 
 	if (!f.open (QIODevice::ReadOnly))
 	{
-		critical (fmt ("Couldn't open temporary file %1 for reading.\n", fname));
+		critical (format ("Couldn't open temporary file %1 for reading.\n", fname));
 		return;
 	}
 
@@ -575,8 +575,8 @@
 	{
 		(ui.cb_oldsweep->isChecked() ? "-s" : ""),
 		(ui.cb_reverse->isChecked() ? "-r" : ""),
-		(ui.dsb_segsplit->value() != 0 ? fmt ("-l %1", ui.dsb_segsplit->value()) : ""),
-		(ui.sb_bias->value() != 0 ? fmt ("-s %1", ui.sb_bias->value()) : ""),
+		(ui.dsb_segsplit->value() != 0 ? format ("-l %1", ui.dsb_segsplit->value()) : ""),
+		(ui.sb_bias->value() != 0 ? format ("-s %1", ui.sb_bias->value()) : ""),
 		in1DATName,
 		in2DATName,
 		outDATName
@@ -672,10 +672,10 @@
 
 	QString argv = join (
 	{
-		fmt ("-p %1", ui.precision->value()),
-		fmt ("-af %1", ui.flatAngle->value()),
-		fmt ("-ac %1", ui.condAngle->value()),
-		fmt ("-ae %1", ui.edgeAngle->value()),
+		format ("-p %1", ui.precision->value()),
+		format ("-af %1", ui.flatAngle->value()),
+		format ("-ac %1", ui.condAngle->value()),
+		format ("-ae %1", ui.edgeAngle->value()),
 		ui.delLines->isChecked()     ? "-de" : "",
 		ui.delCondLines->isChecked() ? "-dc" : "",
 		ui.colored->isChecked()      ? "-c" : "",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Format.h	Wed Mar 05 12:47:00 2014 +0200
@@ -0,0 +1,145 @@
+#pragma once
+#include <QString>
+#include "Types.h"
+
+//!
+//! Converts a given value into a string that can be retrieved with text().
+//! Used as the argument type to the formatting functions, hence its name.
+//!
+class StringFormatArg
+{
+	public:
+		StringFormatArg (const QString& a) : m_text (a) {}
+		StringFormatArg (const char& a) : m_text (a) {}
+		StringFormatArg (const uchar& a) : m_text (a) {}
+		StringFormatArg (const QChar& a) : m_text (a) {}
+		StringFormatArg (int a) : m_text (QString::number (a)) {}
+		StringFormatArg (const float& a) : m_text (QString::number (a)) {}
+		StringFormatArg (const double& a) : m_text (QString::number (a)) {}
+		StringFormatArg (const Vertex& a) : m_text (a.toString (false)) {}
+		StringFormatArg (const Matrix& a) : m_text (a.toString()) {}
+		StringFormatArg (const char* a) : m_text (a) {}
+
+		StringFormatArg (const void* a)
+		{
+			m_text.sprintf ("%p", a);
+		}
+
+		template<typename T>
+		StringFormatArg (const QList<T>& a)
+		{
+			m_text = "{";
+
+			for (const T& it : a)
+			{
+				if (&it != &a.first())
+					m_text += ", ";
+
+				StringFormatArg arg (it);
+				m_text += arg.text();
+			}
+
+			m_text += "}";
+		}
+
+		inline QString text() const
+		{
+			return m_text;
+		}
+
+	private:
+		QString m_text;
+};
+
+//!
+//! Helper function for @c format
+//!
+template<typename Arg1, typename... Rest>
+void formatHelper (QString& str, Arg1 arg1, Rest... rest)
+{
+	str = str.arg (StringFormatArg (arg1).text());
+	formatHelper (str, rest...);
+}
+
+//!
+//! Overload of @c formatHelper with no template args
+//!
+static void formatHelper (QString& str) __attribute__ ((unused));
+static void formatHelper (QString& str)
+{
+	(void) str;
+}
+
+//!
+//! Format the message with the given args
+//! @param fmtstr The string to format
+//! @param args The args to format with
+//! @return The formatted string
+//!
+template<typename... Args>
+QString format (QString fmtstr, Args... args)
+{
+	formatHelper (fmtstr, args...);
+	return fmtstr;
+}
+
+//!
+//! From MessageLog.cc - declared here so that I don't need to include
+//! MessageLog.h here. Prints the given message to log.
+//!
+void printToLog (const QString& msg);
+
+//!
+//! Format and print the given args to the message log.
+//! @param fmtstr The string to format
+//! @param args The args to format with
+//!
+template<typename... Args>
+void print (QString fmtstr, Args... args)
+{
+	formatHelper (fmtstr, args...);
+	printToLog (fmtstr);
+}
+
+//!
+//! Format and print the given args to the given file descriptor
+//! @param fp The file descriptor to print to
+//! @param fmtstr The string to format
+//! @param args The args to format with
+//!
+template<typename... Args>
+void fprint (FILE* fp, QString fmtstr, Args... args)
+{
+	formatHelper (fmtstr, args...);
+	fprintf (fp, "%s", qPrintable (fmtstr));
+}
+
+//!
+//! Overload of @c fprint with a QIODevice
+//! @param dev The IO device to print to
+//! @param fmtstr The string to format
+//! @param args The args to format with
+//!
+template<typename... Args>
+void fprint (QIODevice& dev, QString fmtstr, Args... args)
+{
+	formatHelper (fmtstr, args...);
+	dev.write (fmtstr.toUtf8());
+}
+
+//!
+//! Exactly like print() except no-op in release builds.
+//! @param fmtstr The string to format
+//! @param args The args to format with
+//!
+template<typename... Args>
+void dprint (QString fmtstr, Args... args)
+{
+#ifndef RELEASE
+	formatHelper (fmtstr, args...);
+	printToLog (fmtstr);
+#else
+	(void) fmtstr;
+	(void) args;
+#endif
+}
\ No newline at end of file
--- a/src/GLRenderer.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/GLRenderer.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -138,7 +138,7 @@
 	// Init camera icons
 	for (const GL::EFixedCamera cam : g_Cameras)
 	{
-		QString iconname = fmt ("camera-%1", tr (g_CameraNames[cam]).toLower());
+		QString iconname = format ("camera-%1", tr (g_CameraNames[cam]).toLower());
 
 		CameraIcon* info = &m_cameraIcons[cam];
 		info->img = new QPixmap (getIcon (iconname));
@@ -351,7 +351,7 @@
 				if (obj->color() == i)
 					return;
 
-			log ("%1: Unknown color %2!\n", __func__, obj->color());
+			print ("%1: Unknown color %2!\n", __func__, obj->color());
 			g_warnedColors << obj->color();
 			return;
 		}
@@ -609,7 +609,7 @@
 		}
 
 		// Paint the coordinates onto the screen.
-		QString text = fmt (tr ("X: %1, Y: %2, Z: %3"), m_hoverpos[X], m_hoverpos[Y], m_hoverpos[Z]);
+		QString text = format (tr ("X: %1, Y: %2, Z: %3"), m_hoverpos[X], m_hoverpos[Y], m_hoverpos[Z]);
 		QFontMetrics metrics = QFontMetrics (font());
 		QRect textSize = metrics.boundingRect (0, 0, m_width, m_height, Qt::AlignCenter, text);
 		paint.setPen (textpen);
@@ -821,14 +821,14 @@
 			paint.drawPixmap (info.destRect, *info.img, info.srcRect);
 		}
 
-		QString fmtstr = tr ("%1 Camera");
+		QString formatstr = tr ("%1 Camera");
 
 		// Draw a label for the current camera in the bottom left corner
 		{
 			const int margin = 4;
 
 			QString label;
-			label = fmt (fmtstr, tr (g_CameraNames[camera()]));
+			label = format (formatstr, tr (g_CameraNames[camera()]));
 			paint.setPen (textpen);
 			paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), label);
 		}
@@ -840,7 +840,7 @@
 				m_drawToolTip = false;
 			else
 			{
-				QString label = fmt (fmtstr, tr (g_CameraNames[m_toolTipCamera]));
+				QString label = format (formatstr, tr (g_CameraNames[m_toolTipCamera]));
 				QToolTip::showText (m_globalpos, label);
 			}
 		}
--- a/src/GLRenderer.h	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/GLRenderer.h	Wed Mar 05 12:47:00 2014 +0200
@@ -19,6 +19,7 @@
 #pragma once
 #include <QGLWidget>
 #include "Main.h"
+#include "Macros.h"
 #include "LDObject.h"
 #include "Document.h"
 
@@ -285,6 +286,12 @@
 			return currentDocumentData().zoom[camera()];
 		}
 
+		template<typename... Args>
+		inline QString format (QString fmtstr, Args... args)
+		{
+			return ::format (fmtstr, args...);
+		}
+
 	private slots:
 		void           slot_toolTipTimer();
 };
--- a/src/LDObject.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/LDObject.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -80,14 +80,14 @@
 //
 QString LDComment::asText() const
 {
-	return fmt ("0 %1", text());
+	return format ("0 %1", text());
 }
 
 // =============================================================================
 //
 QString LDSubfile::asText() const
 {
-	QString val = fmt ("1 %1 %2 ", color(), position());
+	QString val = format ("1 %1 %2 ", color(), position());
 	val += transform().toString();
 	val += ' ';
 	val += fileInfo()->name();
@@ -98,10 +98,10 @@
 //
 QString LDLine::asText() const
 {
-	QString val = fmt ("2 %1", color());
+	QString val = format ("2 %1", color());
 
 	for (int i = 0; i < 2; ++i)
-		val += fmt (" %1", vertex (i));
+		val += format (" %1", vertex (i));
 
 	return val;
 }
@@ -110,10 +110,10 @@
 //
 QString LDTriangle::asText() const
 {
-	QString val = fmt ("3 %1", color());
+	QString val = format ("3 %1", color());
 
 	for (int i = 0; i < 3; ++i)
-		val += fmt (" %1", vertex (i));
+		val += format (" %1", vertex (i));
 
 	return val;
 }
@@ -122,10 +122,10 @@
 //
 QString LDQuad::asText() const
 {
-	QString val = fmt ("4 %1", color());
+	QString val = format ("4 %1", color());
 
 	for (int i = 0; i < 4; ++i)
-		val += fmt (" %1", vertex (i));
+		val += format (" %1", vertex (i));
 
 	return val;
 }
@@ -134,11 +134,11 @@
 //
 QString LDCondLine::asText() const
 {
-	QString val = fmt ("5 %1", color());
+	QString val = format ("5 %1", color());
 
 	// Add the coordinates
 	for (int i = 0; i < 4; ++i)
-		val += fmt (" %1", vertex (i));
+		val += format (" %1", vertex (i));
 
 	return val;
 }
@@ -154,7 +154,7 @@
 //
 QString LDVertex::asText() const
 {
-	return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos);
+	return format ("0 !LDFORGE VERTEX %1 %2", color(), pos);
 }
 
 // =============================================================================
@@ -182,7 +182,7 @@
 
 QString LDBFC::asText() const
 {
-	return fmt ("0 BFC %1", LDBFC::k_statementStrings[m_statement]);
+	return format ("0 BFC %1", LDBFC::k_statementStrings[m_statement]);
 }
 
 // =============================================================================
@@ -426,13 +426,13 @@
 		if (!firstDetails)
 			text += ", ";
 
-		QString noun = fmt ("%1%2", typeName (objType), plural (count));
+		QString noun = format ("%1%2", typeName (objType), plural (count));
 
 		// Plural of "vertex" is "vertices", correct that
 		if (objType == EVertex && count != 1)
 			noun = "vertices";
 
-		text += fmt ("%1 %2", count, noun);
+		text += format ("%1 %2", count, noun);
 		firstDetails = false;
 	}
 
@@ -639,7 +639,7 @@
 //
 QString LDOverlay::asText() const
 {
-	return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6",
+	return format ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6",
 		fileName(), camera(), x(), y(), width(), height());
 }
 
@@ -747,12 +747,7 @@
 //
 void LDObject::select()
 {
-	if (!document())
-	{
-		log ("Warning: Object #%1 cannot be selected as it is not assigned a file!\n", id());
-		return;
-	}
-
+	assert (document() != null);
 	document()->addToSelection (this);
 }
 
@@ -760,12 +755,7 @@
 //
 void LDObject::unselect()
 {
-	if (!document())
-	{
-		log ("Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", id());
-		return;
-	}
-
+	assert (document() != null);
 	document()->removeFromSelection (this);
 }
 
--- a/src/Macros.h	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Macros.h	Wed Mar 05 12:47:00 2014 +0200
@@ -18,6 +18,10 @@
 
 #pragma once
 
+#ifndef __GNUC__
+# define __attribute__(X)
+#endif
+
 // =============================================================================
 //
 #define PROPERTY(ACCESS, TYPE, READ, WRITE, WRITETYPE)			\
@@ -65,17 +69,7 @@
 
 // =============================================================================
 //
-#ifdef IN_IDE_PARSER
-void dlog(void, ...) {}
-#else
-# ifdef DEBUG
-#  define dlog(...) log (QString (__PRETTY_FUNCTION__) + ": " __VA_ARGS__)
-# else
-#  define dlog(...)
-# endif // DEBUG
-#endif // IN_IDE_PARSER
-
-#define dvalof(A) dlog ("value of '%1' = %2\n", #A, A)
+#define dvalof(A) dprint ("value of '%1' = %2\n", #A, A)
 
 // =============================================================================
 //
--- a/src/Main.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Main.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -56,12 +56,12 @@
 	// Load or create the configuration
 	if (!Config::load())
 	{
-		log ("Creating configuration file...\n");
+		print ("Creating configuration file...\n");
 
 		if (Config::save())
-			log ("Configuration file successfully created.\n");
+			print ("Configuration file successfully created.\n");
 		else
-			log ("failed to create configuration file!\n");
+			critical ("Failed to create configuration file!\n");
 	}
 
 	LDPaths::initPaths();
@@ -82,21 +82,3 @@
 	loadPrimitives();
 	return app.exec();
 }
-
-// =============================================================================
-//
-void doPrint (QFile& f, QList<StringFormatArg> args)
-{
-	QString msg = DoFormat (args);
-	f.write (msg.toUtf8());
-	f.flush();
-}
-
-// =============================================================================
-//
-void doPrint (FILE* fp, QList<StringFormatArg> args)
-{
-	QString msg = DoFormat (args);
-	fwrite (msg.toStdString().c_str(), 1, msg.length(), fp);
-	fflush (fp);
-}
--- a/src/Main.h	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Main.h	Wed Mar 05 12:47:00 2014 +0200
@@ -30,6 +30,7 @@
 #include "Macros.h"
 #include "Version.h"
 #include "Configuration.h"
+#include "Format.h"
 
 // Null pointer
 static const std::nullptr_t null = nullptr;
--- a/src/MainWindow.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/MainWindow.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -115,7 +115,7 @@
 //
 KeySequenceConfig* MainWindow::shortcutForAction (QAction* act)
 {
-	QString keycfgname = fmt ("key_%1", act->objectName());
+	QString keycfgname = format ("key_%1", act->objectName());
 	return KeySequenceConfig::getByName (keycfgname);
 }
 
@@ -136,15 +136,10 @@
 //
 void MainWindow::slot_action()
 {
-	// Get the name of the sender object and use it to compose the slot name.
-	QString methodName = fmt ("slot_%1", sender()->objectName());
-
-#ifdef DEBUG
-	log ("Action %1 triggered", sender()->objectName());
-#endif
-
-	// Now invoke this slot to call the action.
-	QMetaObject::invokeMethod (this, methodName.toAscii().constData(), Qt::DirectConnection);
+	// Get the name of the sender object and use it to compose the slot name,
+	// then invoke this slot to call the action.
+	QMetaObject::invokeMethod (this,
+		qPrintable (format ("slot_%1", sender()->objectName())), Qt::DirectConnection);
 	endAction();
 }
 
@@ -257,22 +252,22 @@
 //
 void MainWindow::updateTitle()
 {
-	QString title = fmt (APPNAME " %1", fullVersionString());
+	QString title = format (APPNAME " %1", fullVersionString());
 
 	// Append our current file if we have one
 	if (getCurrentDocument())
 	{
 		if (getCurrentDocument()->name().length() > 0)
-			title += fmt (": %1", basename (getCurrentDocument()->name()));
+			title += format (": %1", basename (getCurrentDocument()->name()));
 		else
-			title += fmt (": <anonymous>");
+			title += format (": <anonymous>");
 
 		if (getCurrentDocument()->getObjectCount() > 0 &&
 				getCurrentDocument()->getObject (0)->type() == LDObject::EComment)
 		{
 			// Append title
 			LDComment* comm = static_cast<LDComment*> (getCurrentDocument()->getObject (0));
-			title += fmt (": %1", comm->text());
+			title += format (": %1", comm->text());
 		}
 
 		if (getCurrentDocument()->hasUnsavedChanges())
@@ -363,7 +358,7 @@
 
 			case LDObject::EError:
 			{
-				descr = fmt ("ERROR: %1", obj->asText());
+				descr = format ("ERROR: %1", obj->asText());
 				break;
 			}
 
@@ -377,10 +372,10 @@
 			{
 				LDSubfile* ref = static_cast<LDSubfile*> (obj);
 
-				descr = fmt ("%1 %2, (", ref->fileInfo()->getDisplayName(), ref->position().toString (true));
+				descr = format ("%1 %2, (", ref->fileInfo()->getDisplayName(), ref->position().toString (true));
 
 				for (int i = 0; i < 9; ++i)
-					descr += fmt ("%1%2", ref->transform()[i], (i != 8) ? " " : "");
+					descr += format ("%1%2", ref->transform()[i], (i != 8) ? " " : "");
 
 				descr += ')';
 				break;
@@ -395,7 +390,7 @@
 			case LDObject::EOverlay:
 			{
 				LDOverlay* ovl = static_cast<LDOverlay*> (obj);
-				descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()],
+				descr = format ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()],
 					basename (ovl->fileName()), ovl->x(), ovl->y(),
 					ovl->width(), ovl->height());
 				break;
@@ -771,14 +766,14 @@
 		if (f == getCurrentDocument())
 			updateTitle();
 
-		log ("Saved to %1.", path);
+		print ("Saved to %1.", path);
 
 		// Add it to recent files
 		addRecentFile (path);
 		return true;
 	}
 
-	QString message = fmt (tr ("Failed to save to %1: %2"), path, strerror (errno));
+	QString message = format (tr ("Failed to save to %1: %2"), path, strerror (errno));
 
 	// Tell the user the save failed, and give the option for saving as with it.
 	QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, g_win);
@@ -811,7 +806,7 @@
 //
 QPixmap getIcon (QString iconName)
 {
-	return (QPixmap (fmt (":/icons/%1.png", iconName)));
+	return (QPixmap (format (":/icons/%1.png", iconName)));
 }
 
 // =============================================================================
@@ -884,7 +879,7 @@
 		assert (col != null);
 
 		QIcon ico = makeColorIcon (col, 16);
-		box->addItem (ico, fmt ("[%1] %2 (%3 object%4)",
+		box->addItem (ico, format ("[%1] %2 (%3 object%4)",
 			pair.first, col->name, pair.second, plural (pair.second)));
 		box->setItemData (row, pair.first);
 
--- a/src/MessageLog.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/MessageLog.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -120,16 +120,12 @@
 }
 
 // =============================================================================
-// log() interface - format the argument list and add the resulting string to
-// the main message manager.
 //
-void DoLog (std::initializer_list<StringFormatArg> args)
+void printToLog (const QString& msg)
 {
-	const QString msg = DoFormat (args);
-
 	for (QString& a : msg.split ("\n", QString::SkipEmptyParts))
 	{
-		if (g_win)
+		if (g_win != null)
 			g_win->addMessage (a);
 
 		// Also print it to stdout
--- a/src/Misc.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Misc.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -284,12 +284,12 @@
 
 // =============================================================================
 //
-QString join (initlist<StringFormatArg> vals, QString delim)
+QString join (QList<StringFormatArg> vals, QString delim)
 {
 	QStringList list;
 
 	for (const StringFormatArg& arg : vals)
-		list << arg.value();
+		list << arg.text();
 
 	return list.join (delim);
 }
--- a/src/Misc.h	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Misc.h	Wed Mar 05 12:47:00 2014 +0200
@@ -39,7 +39,7 @@
 
 void roundToDecimals (double& a, int decimals);
 
-QString join (initlist<StringFormatArg> vals, QString delim = " ");
+QString join (QList< StringFormatArg > vals, QString delim = " ");
 
 // Grid stuff
 struct gridinfo
--- a/src/PartDownloader.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/PartDownloader.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -223,7 +223,7 @@
 
 		if (QFile::exists (PartDownloader::getDownloadPath() + DIRSLASH + dest))
 		{
-			const QString overwritemsg = fmt (tr ("%1 already exists in download directory. Overwrite?"), dest);
+			const QString overwritemsg = format (tr ("%1 already exists in download directory. Overwrite?"), dest);
 			if (!confirm (tr ("Overwrite?"), overwritemsg))
 				return;
 		}
@@ -339,12 +339,12 @@
 
 	QDir dir (dirpath);
 
-	if (!dir.exists())
+	if (dir.exists() == false)
 	{
-		log ("Creating %1...\n", dirpath);
+		print ("Creating %1...\n", dirpath);
 
 		if (!dir.mkpath (dirpath))
-			critical (fmt (tr ("Couldn't create the directory %1!"), dirpath));
+			critical (format (tr ("Couldn't create the directory %1!"), dirpath));
 	}
 
 	setNetworkReply (networkManager()->get (QNetworkRequest (QUrl (url))));
@@ -401,7 +401,7 @@
 
 	if (isFirstUpdate())
 	{
-		lb = new QLabel (fmt ("<b>%1</b>", destinaton()), table);
+		lb = new QLabel (format ("<b>%1</b>", destinaton()), table);
 		table->setCellWidget (tableRow(), labelcol, lb);
 	}
 
@@ -505,7 +505,7 @@
 
 		if (!filePointer()->open (QIODevice::WriteOnly))
 		{
-			critical (fmt (tr ("Couldn't open %1 for writing: %2"), filePath(), strerror (errno)));
+			critical (format (tr ("Couldn't open %1 for writing: %2"), filePath(), strerror (errno)));
 			setState (EFailed);
 			networkReply()->abort();
 			updateToTable();
--- a/src/Primitives.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Primitives.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -59,7 +59,7 @@
 	// Try to load prims.cfg
 	QFile conf (Config::filepath ("prims.cfg"));
 
-	if (!conf.open (QIODevice::ReadOnly))
+	if (conf.open (QIODevice::ReadOnly) == false)
 	{
 		// No prims.cfg, build it
 		PrimitiveScanner::start();
@@ -85,7 +85,7 @@
 		}
 
 		PrimitiveCategory::populateCategories();
-		log ("%1 primitives loaded.\n", g_primitives.size());
+		print ("%1 primitives loaded.\n", g_primitives.size());
 	}
 }
 
@@ -116,7 +116,7 @@
 	m_baselen = dir.absolutePath().length();
 	recursiveGetFilenames (dir, m_files);
 	emit starting (m_files.size());
-	log ("Scanning primitives...");
+	print ("Scanning primitives...");
 }
 
 // =============================================================================
@@ -167,7 +167,7 @@
 		QFile conf (path);
 
 		if (!conf.open (QIODevice::WriteOnly | QIODevice::Text))
-			critical (fmt ("Couldn't write primitive list %1: %2",
+			critical (format ("Couldn't write primitive list %1: %2",
 				path, conf.errorString()));
 		else
 		{
@@ -179,7 +179,7 @@
 
 		g_primitives = m_prims;
 		PrimitiveCategory::populateCategories();
-		log ("%1 primitives scanned", g_primitives.size());
+		print ("%1 primitives scanned", g_primitives.size());
 		g_activeScanner = null;
 		emit workDone();
 		deleteLater();
@@ -281,7 +281,7 @@
 
 	if (!f.open (QIODevice::ReadOnly))
 	{
-		critical (fmt (QObject::tr ("Failed to open primitive categories: %1"), f.errorString()));
+		critical (format (QObject::tr ("Failed to open primitive categories: %1"), f.errorString()));
 		return;
 	}
 
@@ -316,7 +316,7 @@
 				type = ETitleRegex;
 			else
 			{
-				log (tr ("Warning: unknown command \"%1\" on line \"%2\""), cmd, line);
+				print (tr ("Warning: unknown command \"%1\" on line \"%2\""), cmd, line);
 				continue;
 			}
 
@@ -325,7 +325,7 @@
 			cat->regexes << entry;
 		}
 		else
-			log ("Warning: Rules given before the first category name");
+			print ("Warning: Rules given before the first category name");
 	}
 
 	if (cat->isValidToInclude())
@@ -343,9 +343,9 @@
 //
 bool PrimitiveCategory::isValidToInclude()
 {
-	if (regexes.size() == 0)
+	if (regexes.isEmpty())
 	{
-		log (tr ("Warning: category \"%1\" left without patterns"), name());
+		print (tr ("Warning: category \"%1\" left without patterns"), name());
 		deleteLater();
 		return false;
 	}
@@ -565,10 +565,10 @@
 	}
 
 	// Compose some general information: prefix, fraction, root, ring number
-	QString prefix = (divs == g_lores) ? "" : fmt ("%1/", divs);
-	QString frac = fmt ("%1-%2", numer, denom);
+	QString prefix = (divs == g_lores) ? "" : format ("%1/", divs);
+	QString frac = format ("%1-%2", numer, denom);
 	QString root = g_radialNameRoots[type];
-	QString numstr = (type == Ring || type == Cone) ? fmt ("%1", num) : "";
+	QString numstr = (type == Ring || type == Cone) ? format ("%1", num) : "";
 
 	// Truncate the root if necessary (7-16rin4.dat for instance).
 	// However, always keep the root at least 2 characters.
@@ -598,10 +598,10 @@
 			(num < 10) ? "  " :
 			(num < 100) ? " "  : "";
 
-		descr = fmt ("%1 %2%3 x %4", primitiveTypeName (type), spacing, num, frac);
+		descr = format ("%1 %2%3 x %4", primitiveTypeName (type), spacing, num, frac);
 	}
 	else
-		descr = fmt ("%1 %2", primitiveTypeName (type), frac);
+		descr = format ("%1 %2", primitiveTypeName (type), frac);
 
 	// Prepend "Hi-Res" if 48/ primitive.
 	if (divs == g_hires)
@@ -616,15 +616,15 @@
 	if (ld_defaultname.isEmpty() == false)
 	{
 		license = getLicenseText (ld_defaultlicense);
-		author = fmt ("%1 [%2]", ld_defaultname, ld_defaultuser);
+		author = format ("%1 [%2]", ld_defaultname, ld_defaultuser);
 	}
 
 	f->addObjects (
 	{
 		new LDComment (descr),
-		new LDComment (fmt ("Name: %1", name)),
-		new LDComment (fmt ("Author: %1", author)),
-		new LDComment (fmt ("!LDRAW_ORG Unofficial_%1Primitive", divs == g_hires ? "48_" : "")),
+		new LDComment (format ("Name: %1", name)),
+		new LDComment (format ("Author: %1", author)),
+		new LDComment (format ("!LDRAW_ORG Unofficial_%1Primitive", divs == g_hires ? "48_" : "")),
 		new LDComment (license),
 		new LDEmpty,
 		new LDBFC (LDBFC::CertifyCCW),
--- a/src/Types.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Types.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -29,19 +29,6 @@
 
 // =============================================================================
 //
-QString DoFormat (QList<StringFormatArg> args)
-{
-	assert (args.size() >= 1);
-	QString text = args[0].value();
-
-	for (uchar i = 1; i < args.size(); ++i)
-		text = text.arg (args[i].value());
-
-	return text;
-}
-
-// =============================================================================
-//
 Vertex::Vertex (double x, double y, double z)
 {
 	m_coords[X] = x;
@@ -83,12 +70,12 @@
 //
 QString Vertex::toString (bool mangled) const
 {
-	QString fmtstr = "%1 %2 %3";
+	QString formatstr = "%1 %2 %3";
 
 	if (mangled)
-		fmtstr = "(%1, %2, %3)";
+		formatstr = "(%1, %2, %3)";
 
-	return fmt (fmtstr, x(), y(), z());
+	return format (formatstr, x(), y(), z());
 }
 
 // =============================================================================
@@ -210,14 +197,14 @@
 
 // =============================================================================
 //
-void Matrix::puts() const
+void Matrix::dump() const
 {
 	for (int i = 0; i < 3; ++i)
 	{
 		for (int j = 0; j < 3; ++j)
-			log ("%1\t", m_vals[ (i * 3) + j]);
+			print ("%1\t", m_vals[ (i * 3) + j]);
 
-		log ("\n");
+		print ("\n");
 	}
 }
 
--- a/src/Types.h	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/Types.h	Wed Mar 05 12:47:00 2014 +0200
@@ -71,7 +71,7 @@
 
 		double			getDeterminant() const;
 		Matrix			mult (const Matrix& other) const;
-		void			puts() const;
+		void			dump() const;
 		QString			toString() const;
 		void			zero();
 		Matrix&			operator= (const Matrix& other);
@@ -203,61 +203,6 @@
 Q_DECLARE_METATYPE (Vertex)
 
 // =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-// StringFormatArg
-//
-// Converts a given value into a string that can be retrieved with ::value().
-// Used as the argument type to the formatting functions, hence its name.
-// =============================================================================
-class StringFormatArg
-{
-	public:
-		StringFormatArg (const QString& a) : m_val (a) {}
-		StringFormatArg (const char& a) : m_val (a) {}
-		StringFormatArg (const uchar& a) : m_val (a) {}
-		StringFormatArg (const QChar& a) : m_val (a) {}
-		StringFormatArg (int a) : m_val (QString::number (a)) {}
-		StringFormatArg (const float& a) : m_val (QString::number (a)) {}
-		StringFormatArg (const double& a) : m_val (QString::number (a)) {}
-		StringFormatArg (const Vertex& a) : m_val (a.toString (false)) {}
-		StringFormatArg (const Matrix& a) : m_val (a.toString()) {}
-		StringFormatArg (const char* a) : m_val (a) {}
-
-		StringFormatArg (const void* a)
-		{
-			m_val.sprintf ("%p", a);
-		}
-
-		template<class T> StringFormatArg (const QList<T>& a)
-		{
-			m_val = "{ ";
-
-			for (const T& it : a)
-			{
-				if (&it != &a.first())
-					m_val += ", ";
-
-				StringFormatArg arg (it);
-				m_val += arg.value();
-			}
-
-			if (!a.isEmpty())
-				m_val += " ";
-
-			m_val += "}";
-		}
-
-		inline QString value() const
-		{
-			return m_val;
-		}
-
-	private:
-		QString m_val;
-};
-
-// =============================================================================
 // LDBoundingBox
 //
 // The bounding box is the box that encompasses a given set of objects.
@@ -282,29 +227,6 @@
 		LDBoundingBox& operator<< (const Vertex& v);
 };
 
-// Formatter function
-QString DoFormat (QList<StringFormatArg> args);
-
-// printf replacement
-void doPrint (QFile& f, QList<StringFormatArg> args);
-void doPrint (FILE* fp, QList<StringFormatArg> args);
-
-// log() - universal access to the message log. Defined here so that I don't have
-// to include MessageLog.h here and recompile everything every time that file changes.
-void DoLog (std::initializer_list<StringFormatArg> args);
-
-// Macros to access these functions
-# ifndef IN_IDE_PARSER 
-#define fmt(...) DoFormat ({__VA_ARGS__})
-# define fprint(F, ...) doPrint (F, {__VA_ARGS__})
-# define log(...) DoLog({ __VA_ARGS__ })
-#else
-QString fmt (const char* fmtstr, ...);
-void fprint (QFile& f, const char* fmtstr, ...);
-void fprint (FILE* fp, const char* fmtstr, ...);
-void log (const char* fmtstr, ...);
-#endif
-
 extern const Vertex g_origin; // Vertex at (0, 0, 0)
 extern const Matrix g_identity; // Identity matrix
 
--- a/src/actions/EditActions.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/actions/EditActions.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -69,7 +69,7 @@
 {
 	int num = copyToClipboard();
 	deleteSelection();
-	log (tr ("%1 objects cut"), num);
+	print (tr ("%1 objects cut"), num);
 }
 
 // =============================================================================
@@ -77,7 +77,7 @@
 DEFINE_ACTION (Copy, CTRL (C))
 {
 	int num = copyToClipboard();
-	log (tr ("%1 objects copied"), num);
+	print (tr ("%1 objects copied"), num);
 }
 
 // =============================================================================
@@ -98,7 +98,7 @@
 		++num;
 	}
 
-	log (tr ("%1 objects pasted"), num);
+	print (tr ("%1 objects pasted"), num);
 	refresh();
 	scrollToSelection();
 }
@@ -108,7 +108,7 @@
 DEFINE_ACTION (Delete, KEY (Delete))
 {
 	int num = deleteSelection();
-	log (tr ("%1 objects deleted"), num);
+	print (tr ("%1 objects deleted"), num);
 }
 
 // =============================================================================
@@ -198,7 +198,7 @@
 		num++;
 	}
 
-	log ("%1 quadrilaterals split", num);
+	print ("%1 quadrilaterals split", num);
 	refresh();
 }
 
@@ -318,7 +318,7 @@
 		num += numLines;
 	}
 
-	log (tr ("Added %1 border lines"), num);
+	print (tr ("Added %1 border lines"), num);
 	refresh();
 }
 
@@ -347,7 +347,7 @@
 		}
 	}
 
-	log (tr ("Added %1 vertices"), num);
+	print (tr ("Added %1 vertices"), num);
 	refresh();
 }
 
@@ -599,7 +599,7 @@
 		}
 	}
 
-	log (tr ("Rounded %1 values"), num);
+	print (tr ("Rounded %1 values"), num);
 	refreshObjectList();
 	refresh();
 }
@@ -625,7 +625,7 @@
 		num++;
 	}
 
-	log (tr ("%1 objects uncolored"), num);
+	print (tr ("%1 objects uncolored"), num);
 	refresh();
 }
 
@@ -677,7 +677,7 @@
 		}
 	}
 
-	log (tr ("Altered %1 values"), num);
+	print (tr ("Altered %1 values"), num);
 	refresh();
 }
 
@@ -732,7 +732,7 @@
 		++num;
 	}
 
-	log (tr ("Demoted %1 conditional lines"), num);
+	print (tr ("Demoted %1 conditional lines"), num);
 	refresh();
 }
 
@@ -758,7 +758,7 @@
 
 	if (colnum >= MAX_COLORS)
 	{
-		log (tr ("Cannot auto-color: all colors are in use!"));
+		print (tr ("Cannot auto-color: all colors are in use!"));
 		return;
 	}
 
@@ -771,7 +771,7 @@
 		R()->compileObject (obj);
 	}
 
-	log (tr ("Auto-colored: new color is [%1] %2"), colnum, getColor (colnum)->name);
+	print (tr ("Auto-colored: new color is [%1] %2"), colnum, getColor (colnum)->name);
 	refresh();
 }
 
@@ -794,7 +794,7 @@
 		return;
 
 	// Create the comment object based on input
-	QString commentText = fmt ("!HISTORY %1 [%2] %3",
+	QString commentText = format ("!HISTORY %1 [%2] %3",
 		ui->m_date->date().toString ("yyyy-MM-dd"),
 		ui->m_username->text(),
 		ui->m_comment->text());
--- a/src/actions/MainActions.cc	Wed Mar 05 05:31:07 2014 +0200
+++ b/src/actions/MainActions.cc	Wed Mar 05 12:47:00 2014 +0200
@@ -55,7 +55,7 @@
 	QString authortext = ld_defaultname;
 
 	if (!ld_defaultuser.isEmpty())
-		authortext.append (fmt (" [%1]", ld_defaultuser));
+		authortext.append (format (" [%1]", ld_defaultuser));
 
 	ui.le_author->setText (authortext);
 
@@ -75,7 +75,7 @@
 
 		default:
 			QMessageBox::warning (null, "Warning",
-				fmt ("Unknown ld_defaultlicense value %1!", ld_defaultlicense));
+				format ("Unknown ld_defaultlicense value %1!", ld_defaultlicense));
 			break;
 	}
 
@@ -96,8 +96,8 @@
 	{
 		new LDComment (ui.le_title->text()),
 		new LDComment ("Name: <untitled>.dat"),
-		new LDComment (fmt ("Author: %1", ui.le_author->text())),
-		new LDComment (fmt ("!LDRAW_ORG Unofficial_Part")),
+		new LDComment (format ("Author: %1", ui.le_author->text())),
+		new LDComment (format ("!LDRAW_ORG Unofficial_Part")),
 		(license != "" ? new LDComment (license) : null),
 		new LDEmpty,
 		new LDBFC (BFCType),
@@ -392,7 +392,7 @@
 
 	if (!f.open (QIODevice::ReadOnly))
 	{
-		critical (fmt ("Couldn't open %1 (%2)", fname, f.errorString()));
+		critical (format ("Couldn't open %1 (%2)", fname, f.errorString()));
 		return;
 	}
 
@@ -429,7 +429,7 @@
 
 	if (!file.open (QIODevice::WriteOnly | QIODevice::Text))
 	{
-		critical (fmt ("Unable to open %1 for writing (%2)", fname, file.errorString()));
+		critical (format ("Unable to open %1 for writing (%2)", fname, file.errorString()));
 		return;
 	}
 
@@ -494,12 +494,12 @@
 	if (root.right (4) == ".dat")
 		root.chop (4);
 
-	QString defaultname = (root.length() > 0) ? fmt ("%1.png", root) : "";
+	QString defaultname = (root.length() > 0) ? format ("%1.png", root) : "";
 	QString fname = QFileDialog::getSaveFileName (g_win, "Save Screencap", defaultname,
 				"PNG images (*.png);;JPG images (*.jpg);;BMP images (*.bmp);;All Files (*.*)");
 
 	if (fname.length() > 0 && !img.save (fname))
-		critical (fmt ("Couldn't open %1 for writing to save screencap: %2", fname, strerror (errno)));
+		critical (format ("Couldn't open %1 for writing to save screencap: %2", fname, strerror (errno)));
 
 	delete[] imgdata;
 }
@@ -609,7 +609,7 @@
 
 	bool ok;
 	double depth = QInputDialog::getDouble (g_win, "Set Draw Depth",
-											fmt ("Depth value for %1 Camera:", R()->getCameraName()),
+											format ("Depth value for %1 Camera:", R()->getCameraName()),
 											R()->getDepthValue(), -10000.0f, 10000.0f, 3, &ok);
 
 	if (ok)
@@ -754,7 +754,7 @@
 	{
 		QString desiredPath = subdirname + "/s";
 		QString title = tr ("Create subfile directory?");
-		QString text = fmt (tr ("The directory <b>%1</b> is suggested for "
+		QString text = format (tr ("The directory <b>%1</b> is suggested for "
 			"subfiles. This directory does not exist, create it?"), desiredPath);
 
 		if (QDir (desiredPath).exists() || confirm (title, text))
@@ -824,8 +824,8 @@
 	{
 		new LDComment (subtitle),
 		new LDComment ("Name: "),
-		new LDComment (fmt ("Author: %1 [%2]", ld_defaultname, ld_defaultuser)),
-		new LDComment (fmt ("!LDRAW_ORG Unofficial_Subpart")),
+		new LDComment (format ("Author: %1 [%2]", ld_defaultname, ld_defaultuser)),
+		new LDComment (format ("!LDRAW_ORG Unofficial_Subpart")),
 		(license != "" ? new LDComment (license) : null),
 		new LDEmpty,
 		new LDBFC (bfctype),

mercurial