src/ldconfig.cc

Wed, 08 Jan 2014 13:57:10 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Wed, 08 Jan 2014 13:57:10 +0200
changeset 608
487db37f0bb3
parent 606
3dd6f343ec06
child 609
a8dc74a809c6
permissions
-rw-r--r--

- if loading another file to replace an explicitly loaded file, this file won't get closed automatically and thus needs to be manually closed. We also need to check that it's safe to close before doing this. Also fixed a rather argh problem with ::save not using the proper path...

/*
 *  LDForge: LDraw parts authoring CAD
 *  Copyright (C) 2013, 2014 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 "document.h"
#include "ldconfig.h"
#include "gui.h"
#include "misc.h"
#include "colors.h"

// =============================================================================
// Helper function for parseLDConfig
// -----------------------------------------------------------------------------
static bool parseLDConfigTag (LDConfigParser& pars, char const* tag, QString& val)
{
	int pos;

	// Try find the token and get its position
	if (!pars.findToken (pos, tag, 1))
		return false;

	// Get the token after it and store it into val
	return pars.getToken (val, pos + 1);
}

// =============================================================================
// -----------------------------------------------------------------------------
void parseLDConfig()
{
	File* f = openLDrawFile ("LDConfig.ldr", false);

	if (!f)
	{
		critical (fmt (QObject::tr ("Unable to open LDConfig.ldr for parsing: %1"),
			strerror (errno)));
		return;
	}

	// Read in the lines
	for (QString line : *f)
	{
		if (line.length() == 0 || line[0] != '0')
			continue; // empty or illogical

		line.remove ('\r');
		line.remove ('\n');

		// Parse the line
		LDConfigParser pars (line, ' ');

		int code = 0, alpha = 255;
		QString name, facename, edgename, valuestr;

		// Check 0 !COLOUR, parse the name
		if (!pars.tokenCompare (0, "0") || !pars.tokenCompare (1, "!COLOUR") || !pars.getToken (name, 2))
			continue;

		// Replace underscores in the name with spaces for readability
		name.replace ("_", " ");

		// Get the CODE tag
		if (!parseLDConfigTag (pars, "CODE", valuestr))
			continue;

		if (!numeric (valuestr))
			continue; // not a number

		// Ensure that the code is within [0 - 511]
		bool ok;
		code = valuestr.toShort (&ok);

		if (!ok || code < 0 || code >= 512)
			continue;

		// VALUE and EDGE tags
		if (!parseLDConfigTag (pars, "VALUE", facename) || !parseLDConfigTag (pars, "EDGE", edgename))
			continue;

		// Ensure that our colors are correct
		QColor faceColor (facename),
			edgeColor (edgename);

		if (!faceColor.isValid() || !edgeColor.isValid())
			continue;

		// Parse alpha if given.
		if (parseLDConfigTag (pars, "ALPHA", valuestr))
			alpha = clamp (valuestr.toInt(), 0, 255);

		LDColor* col = new LDColor;
		col->name = name;
		col->faceColor = faceColor;
		col->edgeColor = edgeColor;
		col->hexcode = facename;
		col->faceColor.setAlpha (alpha);
		col->index = code;
		setColor (code, col);
	}

	delete f;
}

// =============================================================================
// -----------------------------------------------------------------------------
LDConfigParser::LDConfigParser (QString inText, char sep)
{
	m_tokens = inText.split (sep, QString::SkipEmptyParts);
	m_pos = -1;
}

// =============================================================================
// -----------------------------------------------------------------------------
bool LDConfigParser::isAtBeginning()
{
	return m_pos == -1;
}

// =============================================================================
// -----------------------------------------------------------------------------
bool LDConfigParser::isAtEnd()
{
	return m_pos == m_tokens.size() - 1;
}

// =============================================================================
// -----------------------------------------------------------------------------
bool LDConfigParser::getToken (QString& val, const int pos)
{
	if (pos >= m_tokens.size())
		return false;

	val = m_tokens[pos];
	return true;
}

// =============================================================================
// -----------------------------------------------------------------------------
bool LDConfigParser::getNextToken (QString& val)
{
	return getToken (val, ++m_pos);
}

// =============================================================================
// -----------------------------------------------------------------------------
bool LDConfigParser::peekNextToken (QString& val)
{
	return getToken (val, m_pos + 1);
}

// =============================================================================
// -----------------------------------------------------------------------------
bool LDConfigParser::findToken (int& result, char const* needle, int args)
{
	for (int i = 0; i < (m_tokens.size() - args); ++i)
	{
		if (m_tokens[i] == needle)
		{
			result = i;
			return true;
		}
	}

	return false;
}

// =============================================================================
// -----------------------------------------------------------------------------
void LDConfigParser::rewind()
{
	m_pos = -1;
}

// =============================================================================
// -----------------------------------------------------------------------------
void LDConfigParser::seek (int amount, bool rel)
{
	m_pos = (rel ? m_pos : 0) + amount;
}

// =============================================================================
// -----------------------------------------------------------------------------
int LDConfigParser::getSize()
{
	return m_tokens.size();
}

// =============================================================================
// -----------------------------------------------------------------------------
bool LDConfigParser::tokenCompare (int inPos, const char* sOther)
{
	QString tok;

	if (!getToken (tok, inPos))
		return false;

	return (tok == sOther);
}

mercurial