You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
421 lines
14 KiB
421 lines
14 KiB
/***************************************************************************
|
|
mymoneytemplate.cpp - description
|
|
-------------------
|
|
begin : Sat Aug 14 2004
|
|
copyright : (C) 2004 by Thomas Baumgart
|
|
email : ipwizard@users.sourceforge.net
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "kdecompat.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// QT Includes
|
|
|
|
#include <tqfile.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqapplication.h>
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// KDE Includes
|
|
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <kio/netaccess.h>
|
|
#include <ksavefile.h>
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Project Includes
|
|
|
|
#include "mymoneytemplate.h"
|
|
|
|
MyMoneyTemplate::MyMoneyTemplate() :
|
|
m_progressCallback(0)
|
|
{
|
|
}
|
|
|
|
MyMoneyTemplate::MyMoneyTemplate(const KURL& url) :
|
|
m_progressCallback(0)
|
|
{
|
|
loadTemplate(url);
|
|
}
|
|
|
|
MyMoneyTemplate::~MyMoneyTemplate()
|
|
{
|
|
}
|
|
|
|
bool MyMoneyTemplate::loadTemplate(const KURL& url)
|
|
{
|
|
TQString filename;
|
|
|
|
if(!url.isValid()) {
|
|
qDebug("Invalid template URL '%s'", url.url().latin1());
|
|
return false;
|
|
}
|
|
|
|
m_source = url;
|
|
if(url.isLocalFile()) {
|
|
filename = url.path();
|
|
|
|
} else {
|
|
bool rc;
|
|
rc = KIO::NetAccess::download(url, filename, tqApp->mainWidget());
|
|
if(!rc) {
|
|
KMessageBox::detailedError(tqApp->mainWidget(),
|
|
i18n("Error while loading file '%1'!").arg(url.url()),
|
|
KIO::NetAccess::lastErrorString(),
|
|
i18n("File access error"));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool rc = true;
|
|
TQFile file(filename);
|
|
TQFileInfo info(file);
|
|
if(!info.isFile()) {
|
|
TQString msg=i18n("<b>%1</b> is not a template file.").arg(filename);
|
|
KMessageBox::error(tqApp->mainWidget(), TQString("<p>")+msg, i18n("Filetype Error"));
|
|
return false;
|
|
}
|
|
|
|
if(file.open(IO_ReadOnly)) {
|
|
TQString errMsg;
|
|
int errLine, errColumn;
|
|
if(!m_doc.setContent(&file, &errMsg, &errLine, &errColumn)) {
|
|
TQString msg=i18n("Error while reading template file <b>%1</b> in line %2, column %3").arg(filename).arg(errLine).arg(errColumn);
|
|
KMessageBox::detailedError(tqApp->mainWidget(), TQString("<p>")+msg, errMsg, i18n("Template Error"));
|
|
rc = false;
|
|
} else {
|
|
rc = loadDescription();
|
|
}
|
|
file.close();
|
|
} else {
|
|
KMessageBox::sorry(tqApp->mainWidget(), i18n("File '%1' not found!").arg(filename));
|
|
rc = false;
|
|
}
|
|
|
|
// if a temporary file was constructed by NetAccess::download,
|
|
// then it will be removed with the next call. Otherwise, it
|
|
// stays untouched on the local filesystem
|
|
KIO::NetAccess::removeTempFile(filename);
|
|
return rc;
|
|
}
|
|
|
|
bool MyMoneyTemplate::loadDescription(void)
|
|
{
|
|
int validMask = 0x00;
|
|
const int validAccount = 0x01;
|
|
const int validTitle = 0x02;
|
|
const int validShort = 0x04;
|
|
const int validLong = 0x08;
|
|
const int invalid = 0x10;
|
|
const int validHeader = 0x0F;
|
|
|
|
TQDomElement rootElement = m_doc.documentElement();
|
|
if(!rootElement.isNull()
|
|
&& rootElement.tagName() == "kmymoney-account-template") {
|
|
TQDomNode child = rootElement.firstChild();
|
|
while(!child.isNull() && child.isElement()) {
|
|
TQDomElement childElement = child.toElement();
|
|
// qDebug("MyMoneyTemplate::import: Processing child node %s", childElement.tagName().data());
|
|
if(childElement.tagName() == "accounts") {
|
|
m_accounts = childElement.firstChild();
|
|
validMask |= validAccount;
|
|
} else if(childElement.tagName() == "title") {
|
|
m_title = childElement.text();
|
|
validMask |= validTitle;
|
|
} else if(childElement.tagName() == "shortdesc") {
|
|
m_shortDesc = childElement.text();
|
|
validMask |= validShort;
|
|
} else if(childElement.tagName() == "longdesc") {
|
|
m_longDesc = childElement.text();
|
|
validMask |= validLong;
|
|
} else {
|
|
KMessageBox::error(tqApp->mainWidget(), TQString("<p>")+i18n("Invalid tag <b>%1</b> in template file <b>%2</b>!").arg(childElement.tagName()).arg(m_source.prettyURL()));
|
|
validMask |= invalid;
|
|
}
|
|
child = child.nextSibling();
|
|
}
|
|
}
|
|
return validMask == validHeader;
|
|
}
|
|
|
|
bool MyMoneyTemplate::hierarchy(TQMap<TQString, TQListViewItem*>& list, const TQString& parent, TQDomNode account)
|
|
{
|
|
bool rc = true;
|
|
while(rc == true && !account.isNull()) {
|
|
if(account.isElement()) {
|
|
TQDomElement accountElement = account.toElement();
|
|
if(accountElement.tagName() == "account") {
|
|
TQString name = TQString("%1:%2").arg(parent).arg(accountElement.attribute("name"));
|
|
list[name] = 0;
|
|
hierarchy(list, name, account.firstChild());
|
|
}
|
|
}
|
|
account = account.nextSibling();
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
void MyMoneyTemplate::hierarchy(TQMap<TQString, TQListViewItem*>& list)
|
|
{
|
|
bool rc = !m_accounts.isNull();
|
|
TQDomNode accounts = m_accounts;
|
|
while(rc == true && !accounts.isNull() && accounts.isElement()) {
|
|
TQDomElement childElement = accounts.toElement();
|
|
if(childElement.tagName() == "account"
|
|
&& childElement.attribute("name") == "") {
|
|
switch(childElement.attribute("type").toUInt()) {
|
|
case MyMoneyAccount::Asset:
|
|
list[i18n("Asset")] = 0;
|
|
rc = hierarchy(list, i18n("Asset"), childElement.firstChild());
|
|
break;
|
|
case MyMoneyAccount::Liability:
|
|
list[i18n("Liability")] = 0;
|
|
rc = hierarchy(list, i18n("Liability"), childElement.firstChild());
|
|
break;
|
|
case MyMoneyAccount::Income:
|
|
list[i18n("Income")] = 0;
|
|
rc = hierarchy(list, i18n("Income"), childElement.firstChild());
|
|
break;
|
|
case MyMoneyAccount::Expense:
|
|
list[i18n("Expense")] = 0;
|
|
rc = hierarchy(list, i18n("Expense"), childElement.firstChild());
|
|
break;
|
|
case MyMoneyAccount::Equity:
|
|
list[i18n("Equity")] = 0;
|
|
rc = hierarchy(list, i18n("Equity"), childElement.firstChild());
|
|
break;
|
|
|
|
default:
|
|
rc = false;
|
|
break;
|
|
}
|
|
} else {
|
|
rc = false;
|
|
}
|
|
accounts = accounts.nextSibling();
|
|
}
|
|
}
|
|
|
|
bool MyMoneyTemplate::importTemplate(void(*callback)(int, int, const TQString&))
|
|
{
|
|
m_progressCallback = callback;
|
|
bool rc = !m_accounts.isNull();
|
|
MyMoneyFile* file = MyMoneyFile::instance();
|
|
signalProgress(0, m_doc.elementsByTagName("account").count(), i18n("Loading template %1").arg(m_source.url()));
|
|
m_accountsRead = 0;
|
|
|
|
while(rc == true && !m_accounts.isNull() && m_accounts.isElement()) {
|
|
TQDomElement childElement = m_accounts.toElement();
|
|
if(childElement.tagName() == "account"
|
|
&& childElement.attribute("name") == "") {
|
|
++m_accountsRead;
|
|
MyMoneyAccount parent;
|
|
switch(childElement.attribute("type").toUInt()) {
|
|
case MyMoneyAccount::Asset:
|
|
parent = file->asset();
|
|
break;
|
|
case MyMoneyAccount::Liability:
|
|
parent = file->liability();
|
|
break;
|
|
case MyMoneyAccount::Income:
|
|
parent = file->income();
|
|
break;
|
|
case MyMoneyAccount::Expense:
|
|
parent = file->expense();
|
|
break;
|
|
case MyMoneyAccount::Equity:
|
|
parent = file->equity();
|
|
break;
|
|
|
|
default:
|
|
KMessageBox::error(tqApp->mainWidget(), TQString("<p>")+i18n("Invalid top-level account type <b>%1</b> in template file <b>%2</b>!").arg(childElement.attribute("type")).arg(m_source.prettyURL()));
|
|
rc = false;
|
|
}
|
|
|
|
if(rc == true) {
|
|
rc = createAccounts(parent, childElement.firstChild());
|
|
}
|
|
} else {
|
|
rc = false;
|
|
}
|
|
m_accounts = m_accounts.nextSibling();
|
|
}
|
|
signalProgress(-1, -1);
|
|
return rc;
|
|
}
|
|
|
|
bool MyMoneyTemplate::createAccounts(MyMoneyAccount& parent, TQDomNode account)
|
|
{
|
|
bool rc = true;
|
|
while(rc == true && !account.isNull()) {
|
|
MyMoneyAccount acc;
|
|
if(account.isElement()) {
|
|
TQDomElement accountElement = account.toElement();
|
|
if(accountElement.tagName() == "account") {
|
|
signalProgress(++m_accountsRead, 0);
|
|
TQValueList<MyMoneyAccount> subAccountList;
|
|
TQValueList<MyMoneyAccount>::ConstIterator it;
|
|
it = subAccountList.end();
|
|
if(!parent.accountList().isEmpty()) {
|
|
MyMoneyFile::instance()->accountList(subAccountList, parent.accountList());
|
|
for(it = subAccountList.begin(); it != subAccountList.end(); ++it) {
|
|
if((*it).name() == accountElement.attribute("name")) {
|
|
acc = *it;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(it == subAccountList.end()) {
|
|
// not found, we need to create it
|
|
acc.setName(accountElement.attribute("name"));
|
|
acc.setAccountType(static_cast<MyMoneyAccount::_accountTypeE>(accountElement.attribute("type").toUInt()));
|
|
setFlags(acc, account.firstChild());
|
|
try {
|
|
MyMoneyFile::instance()->addAccount(acc, parent);
|
|
} catch(MyMoneyException *e) {
|
|
delete e;
|
|
}
|
|
}
|
|
createAccounts(acc, account.firstChild());
|
|
}
|
|
}
|
|
account = account.nextSibling();
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
bool MyMoneyTemplate::setFlags(MyMoneyAccount& acc, TQDomNode flags)
|
|
{
|
|
bool rc = true;
|
|
while(rc == true && !flags.isNull()) {
|
|
if(flags.isElement()) {
|
|
TQDomElement flagElement = flags.toElement();
|
|
if(flagElement.tagName() == "flag") {
|
|
// make sure, we only store flags we know!
|
|
TQString value = flagElement.attribute("name");
|
|
if(value == "Tax") {
|
|
acc.setValue(value.latin1(), "Yes");
|
|
} else {
|
|
KMessageBox::error(tqApp->mainWidget(), TQString("<p>")+i18n("Invalid flag type <b>%1</b> for account <b>%3</b> in template file <b>%2</b>!").arg(flagElement.attribute("name")).arg(m_source.prettyURL()).arg(acc.name()));
|
|
rc = false;
|
|
}
|
|
}
|
|
}
|
|
flags = flags.nextSibling();
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
void MyMoneyTemplate::signalProgress(int current, int total, const TQString& msg)
|
|
{
|
|
if(m_progressCallback != 0)
|
|
(*m_progressCallback)(current, total, msg);
|
|
}
|
|
|
|
bool MyMoneyTemplate::exportTemplate(void(*callback)(int, int, const TQString&))
|
|
{
|
|
m_progressCallback = callback;
|
|
|
|
m_doc = TQDomDocument("KMYMONEY-TEMPLATE");
|
|
|
|
TQDomProcessingInstruction instruct = m_doc.createProcessingInstruction(TQString("xml"), TQString("version=\"1.0\" encoding=\"utf-8\""));
|
|
m_doc.appendChild(instruct);
|
|
|
|
TQDomElement mainElement = m_doc.createElement("kmymoney-account-template");
|
|
m_doc.appendChild(mainElement);
|
|
|
|
TQDomElement title = m_doc.createElement("title");
|
|
mainElement.appendChild(title);
|
|
|
|
TQDomElement shortDesc = m_doc.createElement("shortdesc");
|
|
mainElement.appendChild(shortDesc);
|
|
|
|
TQDomElement longDesc = m_doc.createElement("longdesc");
|
|
mainElement.appendChild(longDesc);
|
|
|
|
TQDomElement accounts = m_doc.createElement("accounts");
|
|
mainElement.appendChild(accounts);
|
|
|
|
// addAccountStructure(accounts, MyMoneyFile::instance()->asset());
|
|
// addAccountStructure(accounts, MyMoneyFile::instance()->liability());
|
|
addAccountStructure(accounts, MyMoneyFile::instance()->income());
|
|
addAccountStructure(accounts, MyMoneyFile::instance()->expense());
|
|
// addAccountStructure(accounts, MyMoneyFile::instance()->equity());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MyMoneyTemplate::addAccountStructure(TQDomElement& parent, const MyMoneyAccount& acc)
|
|
{
|
|
TQDomElement account = m_doc.createElement("account");
|
|
parent.appendChild(account);
|
|
|
|
if(MyMoneyFile::instance()->isStandardAccount(acc.id()))
|
|
account.setAttribute(TQString("name"), TQString());
|
|
else
|
|
account.setAttribute(TQString("name"), acc.name());
|
|
account.setAttribute(TQString("type"), acc.accountType());
|
|
|
|
// FIXME: add tax flag stuff
|
|
|
|
// any child accounts?
|
|
if(acc.accountList().count() > 0) {
|
|
TQValueList<MyMoneyAccount> list;
|
|
MyMoneyFile::instance()->accountList(list, acc.accountList(), false);
|
|
TQValueList<MyMoneyAccount>::Iterator it;
|
|
for(it = list.begin(); it != list.end(); ++it) {
|
|
addAccountStructure(account, *it);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MyMoneyTemplate::saveTemplate(const KURL& url)
|
|
{
|
|
TQString filename;
|
|
|
|
if(!url.isValid()) {
|
|
qDebug("Invalid template URL '%s'", url.url().latin1());
|
|
return false;
|
|
}
|
|
|
|
if(url.isLocalFile()) {
|
|
filename = url.path();
|
|
KSaveFile qfile(filename, 0600);
|
|
if(qfile.status() == 0) {
|
|
saveToLocalFile(qfile.file());
|
|
if(!qfile.close()) {
|
|
throw new MYMONEYEXCEPTION(i18n("Unable to write changes to '%1'").arg(filename));
|
|
}
|
|
} else {
|
|
throw new MYMONEYEXCEPTION(i18n("Unable to write changes to '%1'").arg(filename));
|
|
}
|
|
} else {
|
|
KTempFile tmpfile;
|
|
saveToLocalFile(tmpfile.file());
|
|
if(!KIO::NetAccess::upload(tmpfile.name(), url, NULL))
|
|
throw new MYMONEYEXCEPTION(i18n("Unable to upload to '%1'").arg(url.url()));
|
|
tmpfile.unlink();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MyMoneyTemplate::saveToLocalFile(TQFile* qfile)
|
|
{
|
|
TQTextStream stream(qfile);
|
|
stream.setEncoding(TQTextStream::UnicodeUTF8);
|
|
stream << m_doc.toString();
|
|
|
|
return true;
|
|
}
|