Work on import engines : remove libxml dependency in favor of QtXml
This commit is contained in:
		
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							| @@ -4,8 +4,9 @@ SHARE_DIR=$(DESTDIR)$(ROOT_DIR)"/share/kisscount/" | |||||||
| DOC_DIR=$(DESTDIR)$(ROOT_DIR)"/share/doc/kisscount/" | DOC_DIR=$(DESTDIR)$(ROOT_DIR)"/share/doc/kisscount/" | ||||||
| BIN_DIR=$(DESTDIR)$(ROOT_DIR)"/bin/" | BIN_DIR=$(DESTDIR)$(ROOT_DIR)"/bin/" | ||||||
|  |  | ||||||
| QT_PACKAGES="QtCore QtGui QtSql" | QT_PACKAGES="QtCore QtGui QtSql QtXml" | ||||||
| CXXFLAGS=`pkg-config --cflags $(QT_PACKAGES)` -Wall -Isrc -ggdb -fPIC | CXXFLAGS=`pkg-config --cflags $(QT_PACKAGES)` | ||||||
|  | CXXFLAGS+=-Wall -Isrc -ggdb -fPIC | ||||||
| CXXFLAGS+=-I/usr/include/libxml2 | CXXFLAGS+=-I/usr/include/libxml2 | ||||||
| CXXFLAGS+=-DRESSOURCES_ROOT="\"$(SHARE_DIR)\"" | CXXFLAGS+=-DRESSOURCES_ROOT="\"$(SHARE_DIR)\"" | ||||||
| # For developpers | # For developpers | ||||||
| @@ -13,7 +14,6 @@ CXXFLAGS+=-DRESSOURCES_ROOT="\"$(SHARE_DIR)\"" | |||||||
|  |  | ||||||
| LDFLAGS=`pkg-config --libs $(QT_PACKAGES)` | LDFLAGS=`pkg-config --libs $(QT_PACKAGES)` | ||||||
| LDFLAGS+=-lofx | LDFLAGS+=-lofx | ||||||
| LDFLAGS+=-lxml2 |  | ||||||
|  |  | ||||||
| CXX=$(HOST)g++ | CXX=$(HOST)g++ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,42 +24,32 @@ | |||||||
|  |  | ||||||
| static GrisbiImportEngine grisbiImportEngine; | static GrisbiImportEngine grisbiImportEngine; | ||||||
|  |  | ||||||
| void GrisbiImportEngine::LoadAccount(GrisbiImportEngine* _this, const char** attrs) | void GrisbiImportEngine::LoadAccount(const QXmlAttributes& attrs) | ||||||
| { | { | ||||||
|     int i, id; |     int id, i; | ||||||
|     QString account_number, name, key; |     QString account_number, name, key; | ||||||
|     Account ac; |     Account ac; | ||||||
|  |  | ||||||
|     for (i=0; attrs[i]; i+=2) |     name = attrs.value("name"); | ||||||
|     { |     id = attrs.value("Number").toInt(); | ||||||
| 	if (!strcmp(attrs[i], "Name")) |     account_number = attrs.value("Bank_account_number"); | ||||||
| 	    name = attrs[i+1]; |     key = attrs.value("Key"); | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "Number")) |  | ||||||
| 	    id = QString(attrs[i+1]).toInt(); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "Bank_account_number")) |  | ||||||
| 	    account_number = attrs[i+1]; |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "Key")) |  | ||||||
| 	    key = attrs[i+1]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     account_number += key; |     account_number += key; | ||||||
|  |  | ||||||
|     UNESCAPE_CHARS(name); |     UNESCAPE_CHARS(name); | ||||||
|     UNESCAPE_CHARS(account_number); |     UNESCAPE_CHARS(account_number); | ||||||
|  |  | ||||||
|     for (i=0; i<(int)_this->_user->_accounts.size(); i++) |     for (i=0; i<(int)_user->_accounts.size(); i++) | ||||||
|     { |     { | ||||||
| 	if (_this->_user->_accounts[i].number == account_number) | 	if (_user->_accounts[i].number == account_number) | ||||||
| 	{ | 	{ | ||||||
| 	    _this->_accounts[id] = _this->_user->_accounts[i].id; | 	    _accounts[id] = _user->_accounts[i].id; | ||||||
| 	    return; | 	    return; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     _this->_accounts[id] = 0; |     _accounts[id] = 0; | ||||||
|     ac.number = account_number; |     ac.number = account_number; | ||||||
|     ac.name = name; |     ac.name = name; | ||||||
|     ac.shared = false; |     ac.shared = false; | ||||||
| @@ -68,48 +58,41 @@ void GrisbiImportEngine::LoadAccount(GrisbiImportEngine* _this, const char** att | |||||||
|     ac.is_owner = true; |     ac.is_owner = true; | ||||||
|     ac._virtual = false; |     ac._virtual = false; | ||||||
|     ac.hidden = false; |     ac.hidden = false; | ||||||
|     _this->_unresolvedAccounts.push_back(ac); |     _unresolvedAccounts.push_back(ac); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GrisbiImportEngine::LoadCategory(GrisbiImportEngine* _this, const char** attrs) | void GrisbiImportEngine::LoadCategory(const QXmlAttributes& attrs) | ||||||
| { | { | ||||||
|     QString name; |     QString name; | ||||||
|     int i, id; |     int id, i; | ||||||
|     Category cat; |     Category cat; | ||||||
|  |  | ||||||
|     for (i=0; attrs[i]; i+=2) |     name = attrs.value("Na"); | ||||||
|     { |     id = attrs.value("Nb").toInt(); | ||||||
| 	if (!strcmp(attrs[i], "Na")) |  | ||||||
| 	    name = attrs[i+1]; |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "Nb")) |  | ||||||
| 	    id = QString(attrs[i+1]).toInt(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     UNESCAPE_CHARS(name); |     UNESCAPE_CHARS(name); | ||||||
|  |  | ||||||
|     for (i=0; i<(int)_this->_user->_categories.size(); i++) |     for (i=0; i<(int)_user->_categories.size(); i++) | ||||||
|     { |     { | ||||||
| 	if (_this->_user->_categories[i].name == name) | 	if (_user->_categories[i].name == name) | ||||||
| 	{ | 	{ | ||||||
| 	    _this->_categories[id] = _this->_user->_categories[i].id; | 	    _categories[id] = _user->_categories[i].id; | ||||||
| 	    return; | 	    return; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     _this->_categories[id] = 0; |     _categories[id] = 0; | ||||||
|     cat.id = id; |     cat.id = id; | ||||||
|     cat.name = name; |     cat.name = name; | ||||||
|     cat.parent = 0; |     cat.parent = 0; | ||||||
|     cat.backcolor = view::OWN_GREEN ;  |     cat.backcolor = view::OWN_GREEN ;  | ||||||
|     cat.forecolor = Qt::black;  |     cat.forecolor = Qt::black;  | ||||||
|     cat.fix_cost = false; |     cat.fix_cost = false; | ||||||
|     _this->_unresolvedCategories.push_back(cat); |     _unresolvedCategories.push_back(cat); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GrisbiImportEngine::LoadOperation(GrisbiImportEngine* _this, const char** attrs) | void GrisbiImportEngine::LoadOperation(const QXmlAttributes& attrs) | ||||||
| { | { | ||||||
|     int i; |  | ||||||
|     static int id=0; |     static int id=0; | ||||||
|     Operation op; |     Operation op; | ||||||
|     QDate date; |     QDate date; | ||||||
| @@ -125,74 +108,54 @@ void GrisbiImportEngine::LoadOperation(GrisbiImportEngine* _this, const char** a | |||||||
|     op.meta = false; |     op.meta = false; | ||||||
|     op._virtual = false; |     op._virtual = false; | ||||||
|  |  | ||||||
|     for (i=0; attrs[i]; i+=2) |     op.account = _accounts[attrs.value("Ac").toInt()]; | ||||||
|     { |  | ||||||
| 	if (!strcmp(attrs[i], "Ac")) |  | ||||||
| 	    op.account = _this->_accounts[QString(attrs[i+1]).toInt()]; |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "Dt")) |     date.fromString(attrs.value("Dt"), "MM/%dd/%yyyy"); | ||||||
| 	{ |     op.day = date.day(); | ||||||
| 	    date.fromString(attrs[i+1], "MM/%dd/%yyyy"); |     op.month = date.month(); | ||||||
| 	    op.day = date.day(); |     op.year = date.year();	     | ||||||
| 	    op.month = date.month(); |     op.amount = attrs.value("Am").toDouble(); | ||||||
| 	    op.year = date.year();	     |     op.category = _categories[attrs.value("Ca").toInt()]; | ||||||
| 	} |     op.description = attrs.value("No"); | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "Am")) |  | ||||||
| 	{ |  | ||||||
| 	    op.amount = QString(attrs[i+1]).toDouble(); |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	else if (!strcmp(attrs[i], "Ca")) |  | ||||||
| 	    op.category = _this->_categories[QString(attrs[i+1]).toInt()]; |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "No")) |  | ||||||
| 	    op.description = attrs[i+1]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     UNESCAPE_CHARS(op.description); |     UNESCAPE_CHARS(op.description); | ||||||
|  |  | ||||||
|     _this->_operations.push_back(op); |     _operations.push_back(op); | ||||||
|     _this->_descriptions[op.id] = op.description; |     _descriptions[op.id] = op.description; | ||||||
|  |  | ||||||
|     _this->MatchPattern(op.description, op); |     MatchPattern(op.description, op); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GrisbiImportEngine::GrisbiStartElement(void* user_data, const xmlChar* name_, const xmlChar** attrs_) | bool GrisbiImportEngine::startElement (const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& attrs) | ||||||
| { | { | ||||||
|     GrisbiImportEngine* _this = (GrisbiImportEngine*) user_data; |  | ||||||
|     static char first = 0; |     static char first = 0; | ||||||
|     int i; |  | ||||||
|     const char** attrs = (const char**) attrs_; |  | ||||||
|     const char* name = (const char*) name_; |  | ||||||
|  |  | ||||||
|     if (!first && strcmp(name, "Grisbi")) |     if (!first && qName != "Grisbi") | ||||||
|     { |     { | ||||||
| 	throw "Invalid file !"; | 	throw "Invalid file !"; | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
| 	first = 1; | 	first = 1; | ||||||
|      |      | ||||||
|     if (!strcmp(name, "General")) |     if (qName == "General") | ||||||
|     { |     { | ||||||
| 	for (i=0; attrs[i]; i+=2) | 	if (attrs.value("File_version") < "0.6.0") | ||||||
| 	{ | 	    throw "Unsupported version !"; | ||||||
| 	    if (!strcmp(attrs[i], "File_version") && strcmp(attrs[i+1], "0.6.0") < 0) |  | ||||||
| 		throw "Unsupported version !"; |  | ||||||
|  |  | ||||||
| 	    else if (!strcmp(attrs[i], "Crypt_file") && !strcmp(attrs[i+1], "1")) | 	if (attrs.value("Crypt_file") == "1") | ||||||
| 		throw "Crypted file !"; | 	    throw "Crypted file !"; | ||||||
| 	} |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     else if (!strcmp(name, "Account")) |     else if (qName == "Account") | ||||||
| 	LoadAccount(_this, attrs); | 	LoadAccount(attrs); | ||||||
|  |  | ||||||
|     else if (!strcmp(name, "Category")) |     else if (qName == "Category") | ||||||
| 	LoadCategory(_this, attrs); | 	LoadCategory(attrs); | ||||||
|  |  | ||||||
|     else if (!strcmp(name, "Transaction")) |     else if (qName == "Transaction") | ||||||
| 	LoadOperation(_this, attrs); | 	LoadOperation(attrs); | ||||||
|  |  | ||||||
|  |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| GrisbiImportEngine::GrisbiImportEngine() | GrisbiImportEngine::GrisbiImportEngine() | ||||||
| @@ -202,7 +165,7 @@ GrisbiImportEngine::GrisbiImportEngine() | |||||||
|     _shortExt = ".gsb"; |     _shortExt = ".gsb"; | ||||||
|     _longExt = _("Grisbi files (*.gsb)"); |     _longExt = _("Grisbi files (*.gsb)"); | ||||||
|  |  | ||||||
|     _sax.startElement = GrisbiStartElement ; |     _sax.setContentHandler(this); | ||||||
| } | } | ||||||
|  |  | ||||||
| GrisbiImportEngine::~GrisbiImportEngine() | GrisbiImportEngine::~GrisbiImportEngine() | ||||||
| @@ -211,19 +174,22 @@ GrisbiImportEngine::~GrisbiImportEngine() | |||||||
|  |  | ||||||
| bool GrisbiImportEngine::HandleFile(const QString& path, User* user, Database* db, KissCount* kiss) | bool GrisbiImportEngine::HandleFile(const QString& path, User* user, Database* db, KissCount* kiss) | ||||||
| { | { | ||||||
|     int res = -1; |     bool res = false; | ||||||
|  |     QFile file(path); | ||||||
|  |  | ||||||
|     if (!ImportEngine::HandleFile(path, user, db, kiss)) return false; |     if (!ImportEngine::HandleFile(path, user, db, kiss)) return false; | ||||||
|  |  | ||||||
|     try |     try | ||||||
|     { |     { | ||||||
| 	res = xmlSAXUserParseFile(&_sax, this, path.toStdString().c_str()); | 	res = _sax.parse(&file); | ||||||
|     } |     } | ||||||
|     catch (const char* s) |     catch (const char* s) | ||||||
|     { |     { | ||||||
| 	std::cout << "GrisbiImportEngine :: " << s << std::endl; | 	std::cout << "GrisbiImportEngine :: " << s << std::endl; | ||||||
| 	res = -1; | 	res = false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return res >= 0; |     file.close(); | ||||||
|  |  | ||||||
|  |     return res; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,11 +20,12 @@ | |||||||
| #ifndef GRISBIIMPORTENGINE_H | #ifndef GRISBIIMPORTENGINE_H | ||||||
| #define GRISBIIMPORTENGINE_H | #define GRISBIIMPORTENGINE_H | ||||||
|  |  | ||||||
| #include <libxml/parser.h> | #include <QXmlDefaultHandler> | ||||||
|  | #include <QXmlAttributes> | ||||||
|  |  | ||||||
| #include "ImportEngine.hpp" | #include "ImportEngine.hpp" | ||||||
|  |  | ||||||
| class GrisbiImportEngine : public ImportEngine { | class GrisbiImportEngine : public ImportEngine, public QXmlDefaultHandler { | ||||||
| public: | public: | ||||||
|     GrisbiImportEngine(); |     GrisbiImportEngine(); | ||||||
|     ~GrisbiImportEngine(); |     ~GrisbiImportEngine(); | ||||||
| @@ -32,12 +33,13 @@ public: | |||||||
|     virtual bool HandleFile(const QString& path, User* user, Database* db, KissCount* kiss); |     virtual bool HandleFile(const QString& path, User* user, Database* db, KissCount* kiss); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     xmlSAXHandler _sax; |     QXmlSimpleReader _sax; | ||||||
|  |  | ||||||
|     static void GrisbiStartElement(void* user_data, const xmlChar* name_, const xmlChar** attrs_); |     bool startElement (const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts); | ||||||
|     static void LoadAccount(GrisbiImportEngine* _this, const char** attrs); |  | ||||||
|     static void LoadCategory(GrisbiImportEngine* _this, const char** attrs); |     void LoadAccount(const QXmlAttributes& atts); | ||||||
|     static void LoadOperation(GrisbiImportEngine* _this, const char** attrs); |     void LoadCategory(const QXmlAttributes& atts); | ||||||
|  |     void LoadOperation(const QXmlAttributes& atts); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -18,39 +18,93 @@ | |||||||
| */ | */ | ||||||
|  |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | #include <QXmlInputSource> | ||||||
|  |  | ||||||
| #include "XMLImportEngine.hpp" | #include "XMLImportEngine.hpp" | ||||||
|  |  | ||||||
| static XMLImportEngine xmlImportEngine; | static XMLImportEngine xmlImportEngine; | ||||||
|  |  | ||||||
| void XMLImportEngine::LoadAccount(XMLImportEngine* _this, const char** attrs) | XMLImportEngine::XMLImportEngine() | ||||||
| { | { | ||||||
|     int i, id; |     KissCount::RegisterImportEngine(this); | ||||||
|  |  | ||||||
|  |     _shortExt = ".xml"; | ||||||
|  |     _longExt = _("KissCount xml files (*.xml)"); | ||||||
|  |  | ||||||
|  |     _sax.setContentHandler(this); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | XMLImportEngine::~XMLImportEngine() | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool XMLImportEngine::HandleFile(const QString& path, User* user, Database* db, KissCount* kiss) | ||||||
|  | { | ||||||
|  |     bool res = false; | ||||||
|  |     QFile file(path); | ||||||
|  |  | ||||||
|  |     if (!ImportEngine::HandleFile(path, user, db, kiss)) return false; | ||||||
|  |  | ||||||
|  |     if (!file.open(QIODevice::ReadOnly)) | ||||||
|  |     { | ||||||
|  | 	std::cout << "Error can't open the file " << path.toStdString() << std::endl; | ||||||
|  | 	return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     try | ||||||
|  |     { | ||||||
|  | 	res = _sax.parse(&file); | ||||||
|  |     } | ||||||
|  |     catch (const char* s) | ||||||
|  |     { | ||||||
|  | 	std::cout << "XMLImportEngine :: " << s << std::endl; | ||||||
|  | 	res = false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     file.close(); | ||||||
|  |  | ||||||
|  |     return res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool XMLImportEngine::startElement (const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& attrs) | ||||||
|  | { | ||||||
|  |     if (qName == "kisscount") | ||||||
|  |     { | ||||||
|  | 	if (attrs.value("version") != "1") | ||||||
|  | 	    throw "Unsupported version !"; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     else if (qName == "account") | ||||||
|  | 	LoadAccount(attrs); | ||||||
|  |  | ||||||
|  |     else if (qName == "account_amount") | ||||||
|  | 	LoadAccountAmount(attrs); | ||||||
|  |  | ||||||
|  |     else if (qName == "category") | ||||||
|  | 	LoadCategory(attrs); | ||||||
|  |  | ||||||
|  |     else if (qName == "operation") | ||||||
|  | 	LoadOperation(attrs); | ||||||
|  |     else | ||||||
|  | 	std::cout << "Unknown element : '" << qName.toStdString() << "'" << std::endl; | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void XMLImportEngine::LoadAccount(const QXmlAttributes& attrs) | ||||||
|  | { | ||||||
|  |     int id; | ||||||
|     QString account_number, name; |     QString account_number, name; | ||||||
|     Account ac; |     Account ac; | ||||||
|     static int unknownAccount = 0; |     static int unknownAccount = 0; | ||||||
|  |  | ||||||
|     ac.id = 0; |     ac.id = 0; | ||||||
|     for (i=0; attrs[i]; i+=2) |  | ||||||
|     { |  | ||||||
| 	if (!strcmp(attrs[i], "name")) |  | ||||||
| 	    ac.name = attrs[i+1]; |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "id")) |     ac.name = attrs.value("name"); | ||||||
| 	    ac.id = id = QString(attrs[i+1]).toInt(); |     ac.id = id = attrs.value("id").toInt(); | ||||||
|  |     ac.number = account_number = attrs.value("number"); | ||||||
| 	else if (!strcmp(attrs[i], "number")) |     ac.blocked = (attrs.value("blocked") == "1"); | ||||||
| 	    ac.number = account_number = attrs[i+1]; |     ac._virtual = (attrs.value("virtual") == "1"); | ||||||
|  |     ac.hidden = (attrs.value("hidden") == "1"); | ||||||
| 	else if (!strcmp(attrs[i], "blocked")) |  | ||||||
| 	    ac.blocked = (QString(attrs[i+1]) == "1"); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "virtual")) |  | ||||||
| 	    ac._virtual = (QString(attrs[i+1]) == "1"); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "hidden")) |  | ||||||
| 	    ac.hidden = (QString(attrs[i+1]) == "1"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     UNESCAPE_CHARS(ac.name); |     UNESCAPE_CHARS(ac.name); | ||||||
|     UNESCAPE_CHARS(ac.number); |     UNESCAPE_CHARS(ac.number); | ||||||
| @@ -62,7 +116,7 @@ void XMLImportEngine::LoadAccount(XMLImportEngine* _this, const char** attrs) | |||||||
|     if (account_number.size()) |     if (account_number.size()) | ||||||
|     { |     { | ||||||
| 	try { | 	try { | ||||||
| 	    _this->_accounts[ac.id] = _this->_user->GetAccountIdFromAccountNumber(account_number); | 	    _accounts[ac.id] = _user->GetAccountIdFromAccountNumber(account_number); | ||||||
| 	    return; | 	    return; | ||||||
| 	} | 	} | ||||||
| 	catch (User::AccountNotFound) | 	catch (User::AccountNotFound) | ||||||
| @@ -70,224 +124,94 @@ void XMLImportEngine::LoadAccount(XMLImportEngine* _this, const char** attrs) | |||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     _this->_accounts[id] = --unknownAccount; |     _accounts[id] = --unknownAccount; | ||||||
|     _this->_unresolvedAccounts.push_back(ac); |     _unresolvedAccounts.push_back(ac); | ||||||
| } | } | ||||||
|  |  | ||||||
| void XMLImportEngine::LoadAccountAmount(XMLImportEngine* _this, const char** attrs) | void XMLImportEngine::LoadAccountAmount(const QXmlAttributes& attrs) | ||||||
| { | { | ||||||
|     AccountAmount accountAmount; |     AccountAmount accountAmount; | ||||||
|     int i; |  | ||||||
|     double amount; |     double amount; | ||||||
|      |      | ||||||
|     for (i=0; attrs[i]; i+=2) |     accountAmount.account = attrs.value("account").toInt(); | ||||||
|     { |     accountAmount.month = attrs.value("month").toInt(); | ||||||
| 	if (!strcmp(attrs[i], "account")) |     accountAmount.year = attrs.value("year").toInt(); | ||||||
| 	    accountAmount.account = QString(attrs[i+1]).toInt(); |     amount = attrs.value("amount").toDouble(); | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "month")) |     _accountAmounts[accountAmount] = amount; | ||||||
| 	{ |  | ||||||
| 	    accountAmount.month = QString(attrs[i+1]).toInt(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "year")) |  | ||||||
| 	{ |  | ||||||
| 	    accountAmount.year = QString(attrs[i+1]).toInt(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "amount")) |  | ||||||
| 	    amount = QString(attrs[i+1]).toDouble(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     _this->_accountAmounts[accountAmount] = amount; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void XMLImportEngine::LoadCategory(XMLImportEngine* _this, const char** attrs) | void XMLImportEngine::LoadCategory(const QXmlAttributes& attrs) | ||||||
| { | { | ||||||
|     QString name; |     QString name; | ||||||
|     int i, id; |     int id; | ||||||
|     long rgb; |     long rgb; | ||||||
|     Category cat; |     Category cat; | ||||||
|     static int unknownCategory = 0; |     static int unknownCategory = 0; | ||||||
|  |  | ||||||
|     for (i=0; attrs[i]; i+=2) |     cat.fix_cost = false; | ||||||
|  |  | ||||||
|  |     cat.name = name = attrs.value("name"); | ||||||
|  |     cat.id = id = attrs.value("id").toInt(); | ||||||
|  |     cat.parent = attrs.value("parent").toInt(); | ||||||
|  |     cat.font = attrs.value("font"); | ||||||
|  |  | ||||||
|  |     if (attrs.value("backcolor") != "") | ||||||
|     { |     { | ||||||
| 	if (!strcmp(attrs[i], "name")) | 	rgb = attrs.value("backcolor").toInt(0, 16); | ||||||
| 	    cat.name = name = QString(attrs[i+1]); | 	cat.backcolor = QColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF); | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "id")) |  | ||||||
| 	    cat.id = id = QString(attrs[i+1]).toInt(); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "parent")) |  | ||||||
| 	    cat.parent = id = QString(attrs[i+1]).toInt(); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "font")) |  | ||||||
| 	    cat.font = QString(attrs[i+1]); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "backcolor")) |  | ||||||
| 	{ |  | ||||||
| 	    rgb = QString(attrs[i+1]).toInt(0, 16); |  | ||||||
| 	    cat.backcolor = QColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "forecolor")) |  | ||||||
| 	{ |  | ||||||
| 	    rgb = QString(attrs[i+1]).toInt(0, 16); |  | ||||||
| 	    cat.forecolor = QColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "fix_cost")) |  | ||||||
| 	    cat.fix_cost = (QString(attrs[i+1]) == "1"); |  | ||||||
|     } |     } | ||||||
|  |     else | ||||||
|  | 	cat.backcolor = view::OWN_GREEN; | ||||||
|  |  | ||||||
|  |     if (attrs.value("forecolor") != "") | ||||||
|  |     { | ||||||
|  | 	rgb = attrs.value("forecolor").toInt(0, 16); | ||||||
|  | 	cat.forecolor = QColor((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  | 	cat.forecolor = Qt::black; | ||||||
|  |  | ||||||
|  |     cat.fix_cost = (attrs.value("fix_cost") == "1"); | ||||||
|  |  | ||||||
|     UNESCAPE_CHARS(cat.name); |     UNESCAPE_CHARS(cat.name); | ||||||
|  |  | ||||||
|     int catId = _this->_user->GetCategoryId(name); |     int catId = _user->GetCategoryId(name); | ||||||
|  |  | ||||||
|     if (catId) |     if (catId) | ||||||
|     { |     { | ||||||
| 	_this->_categories[id] = catId; | 	_categories[id] = catId; | ||||||
| 	return; | 	return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     _this->_categories[id] = --unknownCategory; |     _categories[id] = --unknownCategory; | ||||||
|     _this->_unresolvedCategories.push_back(cat); |     _unresolvedCategories.push_back(cat); | ||||||
| } | } | ||||||
|  |  | ||||||
| void XMLImportEngine::LoadOperation(XMLImportEngine* _this, const char** attrs) | void XMLImportEngine::LoadOperation(const QXmlAttributes& attrs) | ||||||
| { | { | ||||||
|     int i; |  | ||||||
|     Operation op; |     Operation op; | ||||||
|  |  | ||||||
|     for (i=0; attrs[i]; i+=2) |     op.id = attrs.value("id").toInt(); | ||||||
|     { |     op.parent = attrs.value("parent").toInt(); | ||||||
| 	if (!strcmp(attrs[i], "id")) |     op.day = attrs.value("day").toInt(); | ||||||
| 	    op.id = QString(attrs[i+1]).toInt(); |     op.month = attrs.value("month").toInt(); | ||||||
|  |     op.year = attrs.value("year").toInt(); | ||||||
| 	else if (!strcmp(attrs[i], "parent")) |     op.amount = attrs.value("amount").toDouble(); | ||||||
| 	    op.parent = QString(attrs[i+1]).toInt(); |     op.description = attrs.value("description"); | ||||||
|  |     op.category = attrs.value("category").toInt(); | ||||||
| 	else if (!strcmp(attrs[i], "day")) |     op.category = (attrs.value("fix_cost") == "1"); | ||||||
| 	{ |     op.account = attrs.value("account").toInt(); | ||||||
| 	    op.day = QString(attrs[i+1]).toInt(); |     op.checked = (attrs.value("checked") == "1"); | ||||||
| 	} |     op.transfert = attrs.value("transfert").toInt(); | ||||||
|  |     op.formula = attrs.value("formula"); | ||||||
| 	else if (!strcmp(attrs[i], "month")) |     op.meta = (attrs.value("meta") == "1"); | ||||||
| 	{ |     op._virtual = (attrs.value("virtual") == "1"); | ||||||
| 	    op.month = QString(attrs[i+1]).toInt(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "year")) |  | ||||||
| 	{ |  | ||||||
| 	    op.year = QString(attrs[i+1]).toInt(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "amount")) |  | ||||||
| 	{ |  | ||||||
| 	    op.amount = QString(attrs[i+1]).toDouble(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "description")) |  | ||||||
| 	    op.description = QString(attrs[i+1]); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "category")) |  | ||||||
| 	    op.category = _this->_categories[QString(attrs[i+1]).toInt()]; |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "fix_cost")) |  | ||||||
| 	    op.fix_cost = (QString(attrs[i+1]) == "1"); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "account")) |  | ||||||
| 	    op.account = _this->_accounts[QString(attrs[i+1]).toInt()]; |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "checked")) |  | ||||||
| 	    op.checked = (QString(attrs[i+1]) == "1"); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "transfert")) |  | ||||||
| 	    op.transfert = QString(attrs[i+1]).toInt(); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "formula")) |  | ||||||
| 	    op.formula = QString(attrs[i+1]); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "meta")) |  | ||||||
| 	    op.meta = (QString(attrs[i+1]) == "1"); |  | ||||||
|  |  | ||||||
| 	else if (!strcmp(attrs[i], "virtual")) |  | ||||||
| 	    op._virtual = (QString(attrs[i+1]) == "1"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     UNESCAPE_CHARS(op.description); |     UNESCAPE_CHARS(op.description); | ||||||
|  |  | ||||||
|     _this->_operations.push_back(op); |     _operations.push_back(op); | ||||||
|     _this->_descriptions[op.id] = op.description; |     _descriptions[op.id] = op.description; | ||||||
|  |  | ||||||
|     _this->MatchPattern(op.description, op); |     MatchPattern(op.description, op); | ||||||
| } |  | ||||||
|  |  | ||||||
| void XMLImportEngine::XmlStartElement(void* user_data, const xmlChar* name_, const xmlChar** attrs_) |  | ||||||
| { |  | ||||||
|     XMLImportEngine* _this = (XMLImportEngine*) user_data; |  | ||||||
|     int i; |  | ||||||
|     const char** attrs = (const char**) attrs_; |  | ||||||
|     const char* name = (const char*) name_; |  | ||||||
|  |  | ||||||
|     // if (!first && strcmp(name, "Xml")) |  | ||||||
|     // { |  | ||||||
|     // 	throw "Invalid file !"; |  | ||||||
|     // } |  | ||||||
|     // else |  | ||||||
|     // 	first = 1; |  | ||||||
|      |  | ||||||
|     if (!strcmp(name, "kisscount")) |  | ||||||
|     { |  | ||||||
| 	for (i=0; attrs[i]; i+=2) |  | ||||||
| 	{ |  | ||||||
| 	    if (!strcmp(attrs[i], "version") && strcmp(attrs[i+1], "1")) |  | ||||||
| 		throw "Unsupported version !"; |  | ||||||
| 	} |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     else if (!strcmp(name, "account")) |  | ||||||
| 	LoadAccount(_this, attrs); |  | ||||||
|  |  | ||||||
|     else if (!strcmp(name, "account_amount")) |  | ||||||
| 	LoadAccountAmount(_this, attrs); |  | ||||||
|  |  | ||||||
|     else if (!strcmp(name, "category")) |  | ||||||
| 	LoadCategory(_this, attrs); |  | ||||||
|  |  | ||||||
|     else if (!strcmp(name, "operation")) |  | ||||||
| 	LoadOperation(_this, attrs); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| XMLImportEngine::XMLImportEngine() |  | ||||||
| { |  | ||||||
|     KissCount::RegisterImportEngine(this); |  | ||||||
|  |  | ||||||
|     _shortExt = ".xml"; |  | ||||||
|     _longExt = _("KissCount xml files (*.xml)"); |  | ||||||
|  |  | ||||||
|     _sax.startElement = XmlStartElement ; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| XMLImportEngine::~XMLImportEngine() |  | ||||||
| { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bool XMLImportEngine::HandleFile(const QString& path, User* user, Database* db, KissCount* kiss) |  | ||||||
| { |  | ||||||
|     int res = -1 ; |  | ||||||
|      |  | ||||||
|     if (!ImportEngine::HandleFile(path, user, db, kiss)) return false; |  | ||||||
|  |  | ||||||
|     try |  | ||||||
|     { |  | ||||||
| 	res = xmlSAXUserParseFile(&_sax, this, path.toStdString().c_str()) >= 0; |  | ||||||
|     } |  | ||||||
|     catch (const char* s) |  | ||||||
|     { |  | ||||||
| 	std::cout << "XMLImportEngine :: " << s << std::endl; |  | ||||||
| 	res = -1; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return res >= 0; |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,11 +20,12 @@ | |||||||
| #ifndef XMLIMPORTENGINE_H | #ifndef XMLIMPORTENGINE_H | ||||||
| #define XMLIMPORTENGINE_H | #define XMLIMPORTENGINE_H | ||||||
|  |  | ||||||
| #include <libxml/parser.h> | #include <QXmlDefaultHandler> | ||||||
|  | #include <QXmlAttributes> | ||||||
|  |  | ||||||
| #include "ImportEngine.hpp" | #include "ImportEngine.hpp" | ||||||
|  |  | ||||||
| class XMLImportEngine : public ImportEngine { | class XMLImportEngine : public ImportEngine, public QXmlDefaultHandler { | ||||||
| public: | public: | ||||||
|     XMLImportEngine(); |     XMLImportEngine(); | ||||||
|     ~XMLImportEngine(); |     ~XMLImportEngine(); | ||||||
| @@ -32,13 +33,14 @@ public: | |||||||
|     virtual bool HandleFile(const QString& path, User* user, Database* db, KissCount* kiss); |     virtual bool HandleFile(const QString& path, User* user, Database* db, KissCount* kiss); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     xmlSAXHandler _sax; |     QXmlSimpleReader _sax; | ||||||
|  |  | ||||||
|     static void XmlStartElement(void* user_data, const xmlChar* name_, const xmlChar** attrs_); |     bool startElement (const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts); | ||||||
|     static void LoadAccount(XMLImportEngine* _this, const char** attrs); |  | ||||||
|     static void LoadAccountAmount(XMLImportEngine* _this, const char** attrs); |     void LoadAccount(const QXmlAttributes& atts); | ||||||
|     static void LoadCategory(XMLImportEngine* _this, const char** attrs); |     void LoadAccountAmount(const QXmlAttributes& atts); | ||||||
|     static void LoadOperation(XMLImportEngine* _this, const char** attrs); |     void LoadCategory(const QXmlAttributes& atts); | ||||||
|  |     void LoadOperation(const QXmlAttributes& atts); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user