Česky
Kamil Dudka

GED 2006 (C++)

File detail

Name:Downloadgedconf.cc [Download]
Location: ged2006 > src
Size:20.8 KB
Last modification:2007-08-29 02:16

Source code

/*
 * File: gedconf.cc
 * Project: GED -bitmap editor (ICP)
 * Author: Jakub Filak. xfilak01
 * Team: xdudka00, xfilak01, xhefka00, xhradi08
 * Created: 2006-04-14
 */
 
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
 
#include <iostream>
#include <fstream>
#include <string>
#include <map>
 
XERCES_CPP_NAMESPACE_USE 
 
#include "gedconf.h"
 
/* 
 * Initialize 
 */
GedConf *GedConf::_instance= 0;
 
/*
 * Create instance
 */
GedConf *GedConf::ptr () 
{
	if ( _instance == 0 ) {
		_instance = new GedConf();
	}
 
	return _instance;
}
 
/*
 *  Destroy on the end of program
 */
void GedConf::destroy()
{
	delete _instance;
}
 
/*
 *  Reset after
 */
GedConf::~GedConf()
{
	_instance = 0;
	_change = false;
}
 
/* 
 * Read config file, and parse plugin dir and macros
 */
void GedConf::readConfig( const char* pathToFile )
{
	std::ifstream config(pathToFile);
 
	if ( !config.is_open() ) {
		return;	// if cant open config file
	}
	else {
		config.close();	// if can then close file
	}
 
	try {
		XMLPlatformUtils::Initialize();
	}
	catch ( const XMLException& toCatch ) {
		char* message = XMLString::transcode( toCatch.getMessage() );
		std::cerr << "ged2006: warning: Error during initialization config file: " << message << std::endl;
		XMLString::release(&message);
		return;
	}
 
	XercesDOMParser* parser = new XercesDOMParser();
	parser->setValidationScheme( XercesDOMParser::Val_Always );	// volitelne
	parser->setDoNamespaces( true );	
 
	ErrorHandler* errorH = ( ErrorHandler* ) new HandlerBase();
	parser->setErrorHandler( errorH );	
 
	try {
		parser->parse( pathToFile );
	}
	catch ( const XMLException& toCatch ) {
		char* message = XMLString::transcode(toCatch.getMessage());
		std::cerr << "ged2006: warning: Error during parsing confi file: " << message << std::endl;
		XMLString::release(&message);
		return;
	}
	catch ( const DOMException& toCatch ) {
		char* message = XMLString::transcode(toCatch.msg);
		std::cerr << "ged2006: warning: Error during parsing config file: " << message << std::endl;
		XMLString::release(&message);
		return;
	}
	catch (...) {
		std::cerr << "ged2006: warning: Unexpected erro during parsing config file\n";
	}
 
	_PLFR = _MLFR = _HLFR = _ILFR = _FLFR = false;
	_lastCofingFile = pathToFile;
 
	DOMDocument* pDoc = parser->getDocument();
	DOMTreeWalker* tWalker = pDoc->createTreeWalker(pDoc->getDocumentElement(), 1, NULL, true);
	DOMNode* currentNode;
 
	XMLCh* PluginNodeName = XMLString::transcode("Plugins");
	XMLCh* MacroNodeName = XMLString::transcode("Macros");
	XMLCh* HelpNodeName = XMLString::transcode("Help");
	XMLCh* ImageNodeName = XMLString::transcode("Images");
	XMLCh* FontNodeName = XMLString::transcode("Fonts");
 
	while ( ( currentNode = tWalker->nextNode() ) != NULL ) {
		if ( currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) { 
			if ( XMLString::equals( PluginNodeName, currentNode->getNodeName()) ) {
				if ( currentNode->hasChildNodes() ) {	// if has child	then can try read dirs with plugins
					parsePluginDirs(currentNode->getChildNodes());	
				}
			}
			if ( XMLString::equals( MacroNodeName, currentNode->getNodeName()) ) {
				if ( currentNode->hasChildNodes()) {	// if has child then can try read macros
					parseMacros(currentNode->getChildNodes());	
				}
			}
			if ( XMLString::equals( HelpNodeName, currentNode->getNodeName()) ) {
				if ( currentNode->hasAttributes()) {	// only if has attribute
					parseNodeWithOneAttribute( currentNode, "dir", _helpdir, &_HLFR );
				}	
			}
			if ( XMLString::equals( ImageNodeName, currentNode->getNodeName()) ) {
				if ( currentNode->hasAttributes()) {	// only if has attribute
					parseNodeWithOneAttribute( currentNode, "dir", _imagesDir, &_ILFR );
				}	
			}
			if ( XMLString::equals( FontNodeName, currentNode->getNodeName()) ) {
				if ( currentNode->hasAttributes()) {	// only if has attribute
					parseFont( currentNode );
				}	
			}
		}
	}
 
	delete parser;
	delete errorH;
 
	delete [] PluginNodeName;
	delete [] MacroNodeName;
	delete [] HelpNodeName;
	delete [] ImageNodeName;
	delete [] FontNodeName;
 
	XMLPlatformUtils::Terminate();
 
	return;
}
 
/*
 * To saving config file
 */
void GedConf::saveConfig()
{	
	if ( !_change ) {
		return;
	}
 
	try {
		XMLPlatformUtils::Initialize();
	}
	catch ( const XMLException& toCatch ) {
		char* message = XMLString::transcode( toCatch.getMessage() );
		std::cerr << "ged2006: warning: Error during initialization: " << message << std::endl;
		XMLString::release(&message);
		return;
	}
 
	XMLCh tStr[100];
	XMLString::transcode( "xml", tStr, 99 );
	DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(tStr);
	DOMDocument* pDoc = impl->createDocument();
	DOMWriter* writer = ((DOMImplementationLS*)impl)->createDOMWriter();
 
	if ( writer->canSetFeature( XMLUni::fgDOMWRTDiscardDefaultContent, false ) ){
		writer->setFeature( XMLUni::fgDOMWRTDiscardDefaultContent, false );
	}
 
	if ( writer->canSetFeature( XMLUni::fgDOMWRTFormatPrettyPrint, true )){
		writer->setFeature( XMLUni::fgDOMWRTFormatPrettyPrint, true);
	}
 
	XMLString::transcode("UTF-8", tStr, 99 );
	pDoc->setEncoding(tStr);				// set encoding
 
	XMLString::transcode("1.0", tStr, 99 );
	pDoc->setVersion(tStr);					// set version of xml
 
	XMLString::transcode("Data", tStr, 99);
	DOMNode* root = pDoc->createElement(tStr); 		// creating root node with tag Data
 
	/* CREATING HELP NODE */
	if ( _HLFR ) {
		XMLString::transcode("Help", tStr, 99);
		DOMElement* helpNode = pDoc->createElement(tStr); 		// creating elemnt for help dir
 
		XMLString::transcode("dir", tStr, 99);
		XMLCh* value = XMLString::transcode( _helpdir.c_str() );	// transcode help dir string
		helpNode->setAttribute( tStr, value );				// set attribute to dir node
		delete [] value;
 
		root->appendChild( helpNode );		// append help node
	}
 
	/* CREATING IMAGES NODE */
	if ( _ILFR ) {
		XMLString::transcode("Images", tStr, 99);
		DOMElement* imageNode = pDoc->createElement(tStr); 		// creating elemnt for help dir
 
		XMLString::transcode("dir", tStr, 99);
		XMLCh* value = XMLString::transcode( _imagesDir.c_str() );	// transcode help dir string
		imageNode->setAttribute( tStr, value );				// set attribute to dir node
		delete [] value;
 
		root->appendChild( imageNode );		// append help node
	}
 
	/* CREATING FONT NODE */
	if ( _FLFR ) {
		XMLString::transcode("Fonts", tStr, 99);
		DOMElement* fontNode = pDoc->createElement(tStr); 		// creating elemnt for help dir
 
		XMLString::transcode("file", tStr, 99);
		XMLCh* value = XMLString::transcode( _fontFile.c_str() );	// transcode help dir string
		fontNode->setAttribute( tStr, value );				// set attribute to dir node
		delete [] value;
 
		XMLString::transcode("dpi", tStr, 99);
		value = XMLString::transcode( _fontDPI.c_str() );	// transcode help dir string
		fontNode->setAttribute( tStr, value );				// set attribute to dir node
		delete [] value;
 
		XMLString::transcode("size", tStr, 99);
		value = XMLString::transcode( _fontSize.c_str() );	// transcode help dir string
		fontNode->setAttribute( tStr, value );				// set attribute to dir node
		delete [] value;
 
		root->appendChild( fontNode );		// append help node
	}
 
	/* CREATING PLUGIN DIRS NODES */
	if ( !_PluginDirs.empty() && _PLFR ) {
		XMLString::transcode("Plugins", tStr, 99);
		DOMNode* rootChild = pDoc->createElement(tStr); 	// mreating first child of root with tag Plugins
		root->appendChild(rootChild);				// append Plugins node
 
		PluginDirsListIterator pIter = _PluginDirs.begin();
 
		while ( pIter != _PluginDirs.end()) {
			if ( pIter->second == _lastCofingFile ) { 		// only if is form last cofig or new, and or isn`t empty
				XMLString::transcode("dir",tStr, 99);
				DOMNode* tnode = pDoc->createElement( tStr ); 	// create node dir for Plugins
 
				rootChild->appendChild( tnode ); 		// append node dir
 
				XMLString::transcode( pIter->first.c_str(), tStr, 99);  // transcode path to dir
 
				tnode->appendChild(pDoc->createTextNode(tStr));  // append text to dir node, value is path to dir
 
			}
			pIter++;
		}
	}
 
	/* CREATING MACROS NODES */
	if ( !_MacroList.empty() && _MLFR ) {
		XMLString::transcode("Macros", tStr, 99);
		DOMNode* rootChild = pDoc->createElement(tStr); 		// creating second child of root with tag Macros
		root->appendChild(rootChild);			// append Macros node
 
		MacroList::iterator mIter = _MacroList.begin();	// iterator for macro list
 
		while ( mIter != _MacroList.end() ) {
			if ( mIter->second == _lastCofingFile ) {
				XMLString::transcode( "macro",tStr, 99 );
				DOMElement* tnode = pDoc->createElement( tStr );	// create element macro
 
				XMLString::transcode( "name",tStr, 99 );		
				XMLCh* value = XMLString::transcode( mIter->first.c_str() );	// transcode value
				tnode->setAttribute( tStr, value );			// set attribute 'name' with value value
 
				CommandVector::iterator cIter = _MacroCommands[mIter->first].begin();	// iterator for command vector
 
				while ( cIter != _MacroCommands[mIter->first].end() ) {
					XMLString::transcode( "command", tStr, 99);
				       	DOMElement* comNode = pDoc->createElement( tStr );	// create elemnt command
 
					XMLCh* tname = XMLString::transcode("name");
					XMLCh* tparams = XMLString::transcode("params");
					XMLCh* tnameVal = XMLString::transcode(cIter->getName().c_str());	// value for name
					XMLCh* tparamsVal = XMLString::transcode(cIter->getParam().c_str());	// value for param
 
					comNode->setAttribute(tname, tnameVal);			// set attribute name
					comNode->setAttribute(tparams, tparamsVal);		// set attribute param
 
					tnode->appendChild(comNode);	// append node command to macro
 
					delete [] tname;
					delete [] tnameVal;
					delete [] tparams;
					delete [] tparamsVal;
 
					cIter++;
				}
 
				rootChild->appendChild( tnode );	// append node macro to root
				delete [] value;
			}
			mIter++;
		}
	}
 
	if ( !_lastCofingFile.empty() ) {	// check to can write to last config file
		std::ofstream config(_lastCofingFile.c_str()); 
 
		if ( !config.is_open() ) {
			_lastCofingFile = "ged.conf";	// if cant write we set config file to ged.conf
		}
		else {
			config.close();		// if can then close file
		}
	}
	else {
		_lastCofingFile = "ged.conf";	// if doest exist config file we set config file to ged.conf
	}
 
	XMLFormatTarget* mFoTa = new LocalFileFormatTarget(_lastCofingFile.c_str() );
 
	pDoc->appendChild( root );	
 
	/* WRITING FILE */
	try {
		writer->writeNode( mFoTa, *pDoc);	// write config file
	}
	catch (const XMLException& toCatch ) {
		char* message = XMLString::transcode(toCatch.getMessage());
		std::cerr <<  "ged2006: warning: Error message" << message << std::endl;
		XMLString::release(&message);
		return;
	}
	catch (const DOMException& toCatch) {
		char* message = XMLString::transcode(toCatch.msg);
		std::cerr << "ged2006: warning: Exception message is: " << message << "\n";
	        XMLString::release(&message);
		return;
	}
	catch (...) {
		std::cerr << "ged2006: warning: Unexpected Exception \n" ;
	}
 
	_change = false;
 
	writer->release();
	pDoc->release();
	delete mFoTa;
 
	XMLPlatformUtils::Terminate();
 
	return;
}
 
/*
 *  Create list of dirs
 */
void GedConf::parsePluginDirs( DOMNodeList* listPluginNodes )
{
	XMLCh* tagDir = XMLString::transcode("dir");
 
	for ( XMLSize_t i = 0; i < listPluginNodes->getLength(); i++ ) {	// go throw out list of all childs node
		DOMNode* current = listPluginNodes->item(i);	// take child
 
		if ( current->getNodeType() == DOMNode::ELEMENT_NODE ) {		// if is child element node
 
			if ( XMLString::equals(tagDir, current->getNodeName()) ) { 	// and if has name dir
 
				if ( current->hasChildNodes() ) {			// and has some childs
					current = current->getFirstChild();		// take his first child
 
					if ( current->getNodeType() == DOMNode::TEXT_NODE ) {	// if is child text node
						char* tmp = XMLString::transcode(current->getNodeValue());	// read his value
 
						if ( tmp != NULL ) {
							_PluginDirs[std::string( tmp )] = _lastCofingFile;	// and store his value
							_PLFR = true;
							delete [] tmp;
						}
					}
				}
			}
		}
	}
 
	delete [] tagDir;
}
 
/*
 * Retur map of dirs maped with their config files
 */
PluginDirsList GedConf::getPluginDirs()
{
	return _PluginDirs;
}
 
/*
 * Map new dir with last config gfile
 */
void GedConf::setPluginDir( const char* pathToDir )
{	
	if ( _lastCofingFile.empty() ) {	// if doesnt exist config file
		_lastCofingFile = "ged.conf";
	}
 
	_PLFR = true;
	_change = true;
	_PluginDirs[std::string(  pathToDir )] = _lastCofingFile;	// store dir with plugins
}
 
/*
 * remove config file, should be used only to local config file
 */
void GedConf::removePluginDir( const char* pathToDir )
{	
	PluginDirsListIterator pIter = _PluginDirs.find( std::string( pathToDir ) );
 
	if ( pIter == _PluginDirs.end() || pIter->second != _lastCofingFile ) {		// if isnt from last config file
		return;			// or if dont find dir to delete,                  the change is imposible
	}
 
	_PLFR = true;
	_change = true;	
	_PluginDirs.erase( pIter );
}
 
/*
 * Read macro commands from config file and store this to commands vector
 * and return this vector
 */
CommandVector GedConf::parseMacroCommands( DOMNodeList* listPluginNodes )
{
	XMLCh* tagCommand = XMLString::transcode("command");
	XMLCh* tagName = XMLString::transcode("name");
	XMLCh* tagParams = XMLString::transcode("params");
	CommandVector commands;
 
	for ( XMLSize_t i = 0; i < listPluginNodes->getLength(); i++ ) {	// go throw out list of all childs node
		DOMNode* current = listPluginNodes->item(i);			// take child
 
		if ( current->getNodeType() == DOMNode::ELEMENT_NODE &&	XMLString::equals(tagCommand, current->getNodeName())) {
			// if child has name command and is element node then
			if ( current->hasAttributes()) {	// if has attributes
				char* tmpName = NULL;
				char* tmpParams = NULL;
 
				DOMNamedNodeMap* attribut = current->getAttributes();	// create attributes list
				current = attribut->getNamedItem(tagName);		// take attribute name
 
				if ( current != NULL && current->getNodeType() == DOMNode::ATTRIBUTE_NODE ) {	// if not NULL and is attribute node
					tmpName = XMLString::transcode(current->getNodeValue());		// transcode name value
				}
 
				current = attribut->getNamedItem(tagParams);		// take attribute params
 
				if ( current != NULL && current->getNodeType() == DOMNode::ATTRIBUTE_NODE ) {	// if not NULL and is attribute node
					tmpParams = XMLString::transcode(current->getNodeValue());		// transcode params value
				}
 
				if ( tmpName != NULL && tmpParams != NULL ) {	// if has all attributes and vales then store this data
					commands.push_back(GedMacroCommand(tmpName,tmpParams));
					delete [] tmpName;
					delete [] tmpParams;
				}
				else{ 
				       	if ( tmpName != NULL ) {
						delete [] tmpName;
					}
 
					if ( tmpParams != NULL ) {
						delete [] tmpParams;
					}
				}
			}
		}
	}
 
	delete [] tagCommand;
	delete [] tagName;
	delete [] tagParams;
 
	return	commands;
}
 
/*
 * Read macros from config file, using parseMacroCommands for creating command vector
 */
void GedConf::parseMacros( DOMNodeList* listPluginNodes )
{
	XMLCh* tagMacro = XMLString::transcode("macro");
	XMLCh* tagName = XMLString::transcode("name");
 
	for ( XMLSize_t i = 0; i < listPluginNodes->getLength(); i++ ) {	// go throw out list of all childs node
		DOMNode* current = listPluginNodes->item(i);			// take child
 
		if ( current->getNodeType() == DOMNode::ELEMENT_NODE &&	XMLString::equals(tagMacro, current->getNodeName())) {
			// if is element node and has name macro
			if ( current->hasAttributes()) { // and if has attributes	
				DOMNamedNodeMap* attribut = current->getAttributes();
				DOMNode* forList = current;				// save node macro
				current = attribut->getNamedItem(tagName);		// take attribute with name 'name'
 
				if ( current != NULL && current->getNodeType() == DOMNode::ATTRIBUTE_NODE ) {  	// if exist and is attribute node
					char* tmp = XMLString::transcode(current->getNodeValue());		// transcode attribute value
 
					if ( tmp != NULL ) {
						CommandVector tcomm = parseMacroCommands( forList->getChildNodes() );	// create vector of commands
 
						if ( !tcomm.empty() ) {
							_MacroList[std::string(tmp)] = _lastCofingFile;	// store macro name with his config file
							_MacroCommands[std::string(tmp)] = tcomm;	// store commads wtih macro name
							_MLFR = true;
						}
 
						delete [] tmp;
					}
				}
			}
		}
	}
 
	delete [] tagMacro;
	delete [] tagName;
}
 
/*
 * return map with first item macro name and second item config file
 */
MacroList GedConf::getMacroList()
{
	return _MacroList;
}
 
/*
 * return vector of commands used in macro
 */
CommandVector GedConf::getCommands( const std::string macroName )
{
	return _MacroCommands[macroName];	// return Command vector by macro name
}
 
/*
 * Remove macro, without efect to macro which ins't from last user config file
 */
void GedConf::removeMacro( const std::string macroName )
{
	MacroList::iterator mIter = _MacroList.find( macroName );
 
	if ( mIter == _MacroList.end() || mIter->second != _lastCofingFile )	{	// if not from last config
		return;			// or if dont  find nacro,			   the remove action is not saving
	}
 
	_MLFR = true;
	_change = true;
	_MacroList.erase( mIter );	// delete macro from config file
 
	MacroCommands::iterator cIter = _MacroCommands.begin();
 
	while ( cIter != _MacroCommands.end() && cIter->first != macroName ) {	// finding commands
		cIter++;
	}
 
	if ( cIter != _MacroCommands.end() ) {
		_MacroCommands.erase( cIter );	// delete commands
	}
}
 
/*
 * Adding macro when macro doesnt exist or adding commad to macro when macro exist,
 * first param is name of macro, second param is name of command and third param is params of command
 */
void GedConf::addMacro( const char* macroName, const char* commandName, const char* commandParams )
{
	if ( _lastCofingFile.empty() ) {	// if config file doesnt exist
		_lastCofingFile = "ged.conf";	// then we saved to ged.conf
	}
 
	_MLFR = true;
	_change = true;
	_MacroList[std::string(macroName)] = _lastCofingFile;	// map name with last config file
	_MacroCommands[macroName].push_back( GedMacroCommand( std::string(commandName), std::string(commandParams))); // add command
}
 
 
/*
 * Read dir which contains help files
 */
void GedConf::parseNodeWithOneAttribute( DOMNode* helpNode, const char* nName, std::string &store, bool* record )
{
	XMLCh* tagDir = XMLString::transcode(nName);
 
	DOMNamedNodeMap* attribut = helpNode->getAttributes();	// get all atributes
	DOMNode* current = attribut->getNamedItem(tagDir);	// take atribute dir
 
	if ( current != NULL && current->getNodeType() == DOMNode::ATTRIBUTE_NODE ) {	// if has attribute dir
		char* tmp = XMLString::transcode(current->getNodeValue());		// transcode value
 
		if ( tmp != NULL ) {
			store = tmp;		// store dir
			*record = true;
			delete [] tmp;
		}
	}
 
	delete [] tagDir;
}
 
/*
 * Return string with help dir
 */
std::string GedConf::getHelpDir()
{	
	if ( !_helpdir.empty() ) {
		return _helpdir;
	}
	else {
		return std::string("helpdir"); // if config files doesnt contain help dir then is used this
	}
}
 
/*
 * Return string with images dir
 */
std::string GedConf::getImageDir()
{	
	if ( !_imagesDir.empty()) {
		return _imagesDir;
	}
	else {
		return std::string("images"); // if config files doesnt contain help dir then is used this
	}
}
 
/*
 * Read node with font
 */
void GedConf::parseFont( DOMNode *fontNode)
{
	XMLCh* aFile = XMLString::transcode("file");
	XMLCh* aDpi = XMLString::transcode("dpi");
	XMLCh* aSize = XMLString::transcode("size");
 
	char* value = NULL;
 
	DOMNamedNodeMap* attribut = fontNode->getAttributes();	// create attributes list
 
	DOMNode* current = attribut->getNamedItem( aFile );		// take attribute name
 
	if ( current != NULL && current->getNodeType() == DOMNode::ATTRIBUTE_NODE ) {	// if not NULL and is attribute node
		value = XMLString::transcode(current->getNodeValue());		// transcode name value
		if ( value != NULL ) {
			_fontFile = value;
			delete [] value;
		}
	}
 
	current = attribut->getNamedItem( aDpi );		// take attribute params
 
	if ( current != NULL && current->getNodeType() == DOMNode::ATTRIBUTE_NODE ) {	// if not NULL and is attribute node
		value = XMLString::transcode(current->getNodeValue());		// transcode name value
		if ( value != NULL ) {
			_fontDPI = value;
			delete [] value;
		}
	}
 
	current = attribut->getNamedItem( aSize );		// take attribute params
 
	if ( current != NULL && current->getNodeType() == DOMNode::ATTRIBUTE_NODE ) {	// if not NULL and is attribute node
		value = XMLString::transcode(current->getNodeValue());		// transcode name value
		if ( value != NULL ) {
			_fontSize = value;
			delete [] value;
		}
	}
 
	_FLFR = true;
 
	delete [] aSize;
	delete [] aDpi;
	delete [] aFile;
}
 
/*
 * To get font property
 */
void GedConf::getFont( std::string &fileName, std::string &dpi, std::string &size )
{
	fileName = _fontFile;
	dpi = _fontDPI;
	size = _fontSize;
}