src/config.cpp

Fri, 02 Aug 2013 16:33:30 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Fri, 02 Aug 2013 16:33:30 +0300
changeset 421
7d26db0be944
parent 359
bcdfc801658b
child 430
8458cf2719d1
permissions
-rw-r--r--

style cleanup - it should be all unified now

/*
 *  LDForge: LDraw parts authoring CAD
 *  Copyright (C) 2013 Santeri Piippo
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <errno.h>
#include <time.h>
#include <QDir>
#include <QTextStream>
#include "common.h"
#include "config.h"
#include "misc.h"
#include "gui.h"

config* g_configPointers[MAX_CONFIG];
static ushort g_cfgPointerCursor = 0;

// =============================================================================
// Load the configuration from file
bool config::load() {
	print ("config::load: Loading configuration file...\n");
	print ("config::load: Path to configuration is %1\n", filepath());

	// Locale must be disabled for atof
	setlocale (LC_NUMERIC, "C");

	File f (filepath(), File::Read);
	int ln = 0;

	if (!f)
		return false;

	// Read the values.
for (str line : f) {
		ln++;

		if (line.isEmpty() || line[0] == '#')
			continue; // Empty line or comment.

		// Find the equals sign.
		int equals = line.indexOf ('=');
		
		if (equals == -1) {
			fprint (stderr, "couldn't find `=` sign in entry `%1`\n", line);
			continue;
		}
		
		str entry = line.left (equals);
		str valstring = line.right (line.length() - equals - 1);
		
		// Find the config entry for this.
		config* cfg = null;
		
		for (config* i : g_configPointers) {
			if (!i)
				break;
			
			if (entry == i->name)
				cfg = i;
		}
		
		if (!cfg) {
			fprint (stderr, "unknown config `%1`\n", entry);
			continue;
		}
		
		switch (cfg->getType()) {
		case Type_int:
			static_cast<intconfig*> (cfg)->value = valstring.toInt();
			break;
		
		case Type_str:
			static_cast<strconfig*> (cfg)->value = valstring;
			break;
		
		case Type_float:
			static_cast<floatconfig*> (cfg)->value = valstring.toFloat();
			break;
		
		case Type_bool: {
			bool& val = static_cast<boolconfig*> (cfg)->value;
			
			if (valstring.toUpper() == "TRUE" || valstring == "1")
				val = true;
			elif (valstring.toUpper() == "FALSE" || valstring == "0")
				val = false;
			
			break;
		}
		
		case Type_keyseq:
			static_cast<keyseqconfig*> (cfg)->value = keyseq::fromString (valstring);
			break;
		
		default:
			break;
		}
	}
	
	f.close();
	return true;
}

extern_cfg (str, io_ldpath);

// =============================================================================
// Save the configuration to disk
bool config::save() {
	// The function will write floats, disable the locale now so that they
	// are written properly.
	setlocale (LC_NUMERIC, "C");
	
	// If the directory doesn't exist, create it now.
	if (QDir (dirpath()).exists() == false) {
		fprint (stderr, "Creating config path %1...\n", dirpath());
		
		if (!QDir().mkpath (dirpath())) {
			critical ("Failed to create the configuration directory. Configuration cannot be saved!\n");
			return false;
		}
	}
	
	File f (filepath(), File::Write);
	print ("writing cfg to %1\n", filepath());
	
	if (!f) {
		critical (fmt (QObject::tr ("Cannot save configuration, cannot open %1 for writing: %2\n"),
			filepath(), strerror (errno)));
		return false;
	}
	
	fprint (f, "# Configuration file for " APPNAME "\n");
	str valstring;
	
	for (config* cfg : g_configPointers) {
		if (!cfg)
			break;
		
		if (cfg->isDefault())
			continue;
		
		switch (cfg->getType()) {
		case Type_int:
			valstring = fmt ("%1", static_cast<intconfig*> (cfg)->value);
			break;
		
		case Type_str:
			valstring = static_cast<strconfig*> (cfg)->value;
			break;
		
		case Type_float:
			valstring = fmt ("%1", static_cast<floatconfig*> (cfg)->value);
			break;
		
		case Type_bool:
			valstring = (static_cast<boolconfig*> (cfg)->value) ? "true" : "false";
			break;
		
		case Type_keyseq:
			valstring = static_cast<keyseqconfig*> (cfg)->value.toString();
			break;
		
		default:
			break;
		}
		
		// Write the entry now.
		fprint (f, "%1=%2\n", cfg->name, valstring);
	}
	
	f.close();
	return true;
}

// =============================================================================
void config::reset() {
	for (config* cfg : g_configPointers) {
		if (!cfg)
			break;
		
		cfg->resetValue();
	}
}

// =============================================================================
str config::filepath() {
	str path = fmt ("%1%2.cfg", dirpath(), str (APPNAME).toLower());
	return path;
}

// =============================================================================
str config::dirpath() {
#ifndef _WIN32
	return fmt ("%1" DIRSLASH ".%2" DIRSLASH,
		QDir::homePath(), str (APPNAME).toLower());
#else
	return fmt ("%1" DIRSLASH APPNAME DIRSLASH, QDir::homePath());
#endif // _WIN32
}

void addConfig (config* ptr) {
	if (g_cfgPointerCursor == 0)
		memset (g_configPointers, 0, sizeof g_configPointers);
	
	assert (g_cfgPointerCursor < MAX_CONFIG);
	g_configPointers[g_cfgPointerCursor++] = ptr;
}

mercurial