/* This file is part of the KDE project Copyright (C) 2005 Dag Andersen <danders@get2net.dk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; version 2 of the License. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include <tqdom.h> #include <tqstring.h> #include <klocale.h> #include <kdebug.h> #include "kptaccount.h" #include "kptduration.h" #include "kptproject.h" namespace KPlato { Account::Account() : m_name(), m_description(), m_list(0), m_parent(0), m_accountList(), m_costPlaces() { m_accountList.setAutoDelete(true); m_costPlaces.setAutoDelete(true); } Account::Account(TQString name, TQString description) : m_name(name), m_description(description), m_list(0), m_parent(0), m_accountList(), m_costPlaces() { m_accountList.setAutoDelete(true); m_costPlaces.setAutoDelete(true); } Account::~Account() { m_accountList.clear(); if (findAccount() == this) { removeId(); // only remove myself (I may be just a working copy) } if (m_list) m_list->accountDeleted(this); } void Account::setName(TQString name) { if (findAccount() == this) { removeId(); } m_name = name; insertId(); } void Account::append(Account *account){ Q_ASSERT(account); m_accountList.append(account); account->setList(m_list); account->setParent(this); insertId(account); } void Account::insertChildren() { AccountListIterator it = m_accountList; for (; it.current(); ++it) { it.current()->setList(m_list); it.current()->setParent(this); insertId(it.current()); it.current()->insertChildren(); } } void Account::take(Account *account) { if (account == 0) { return; } if (account->tqparent() == this) { m_accountList.take(m_accountList.tqfindRef(account)); } else if (account->tqparent()) { account->tqparent()->take(account); } else { m_list->take(account); } //kdDebug()<<k_funcinfo<<account->name()<<endl; } bool Account::load(TQDomElement &element, const Project &project) { m_name = element.attribute("name"); m_description = element.attribute("description"); TQDomNodeList list = element.childNodes(); for (unsigned int i=0; i<list.count(); ++i) { if (list.item(i).isElement()) { TQDomElement e = list.item(i).toElement(); if (e.tagName() == "costplace") { Account::CostPlace *child = new Account::CostPlace(this); if (child->load(e, project)) { append(child); } else { delete child; } } else if (e.tagName() == "account") { Account *child = new Account(); if (child->load(e, project)) { m_accountList.append(child); } else { // TODO: Complain about this kdWarning()<<k_funcinfo<<"Loading failed"<<endl; delete child; } } } } return true; } void Account::save(TQDomElement &element) const { TQDomElement me = element.ownerDocument().createElement("account"); element.appendChild(me); me.setAttribute("name", m_name); me.setAttribute("description", m_description); TQPtrListIterator<Account::CostPlace> cit = m_costPlaces; for (; cit.current(); ++cit) { cit.current()->save(me); } AccountListIterator it = m_accountList; for (; it.current(); ++it) { it.current()->save(me); } } Account::CostPlace *Account::findCostPlace(const Node &node) const { TQPtrListIterator<CostPlace> it = m_costPlaces; for (; it.current(); ++it) { if (&node == it.current()->node()) { return it.current(); } } return 0; } Account::CostPlace *Account::findRunning(const Node &node) const { Account::CostPlace *cp = findCostPlace(node); return cp && cp->running() ? cp : 0; } void Account::removeRunning(const Node &node) { Account::CostPlace *cp = findRunning(node); if (cp) { cp->setRunning(false); if (cp->isEmpty()) { m_costPlaces.removeRef(cp); } } } void Account::addRunning(Node &node) { Account::CostPlace *cp = findCostPlace(node); if (cp) { cp->setRunning(true); return; } append(new CostPlace(this, &node, true)); } Account::CostPlace *Account::findStartup(const Node &node) const { Account::CostPlace *cp = findCostPlace(node); return cp && cp->startup() ? cp : 0; } void Account::removeStartup(const Node &node) { Account::CostPlace *cp = findStartup(node); if (cp) { cp->setStartup(false); if (cp->isEmpty()) { m_costPlaces.removeRef(cp); } } } void Account::addStartup(Node &node) { Account::CostPlace *cp = findCostPlace(node); if (cp) { cp->setStartup(true); return; } append(new CostPlace(this, &node, false, true)); } Account::CostPlace *Account::findShutdown(const Node &node) const { Account::CostPlace *cp = findCostPlace(node); return cp && cp->shutdown() ? cp : 0; } void Account::removeShutdown(const Node &node) { Account::CostPlace *cp = findShutdown(node); if (cp) { cp->setShutdown(false); if (cp->isEmpty()) { m_costPlaces.removeRef(cp); } } } void Account::addShutdown(Node &node) { Account::CostPlace *cp = findCostPlace(node); if (cp) { cp->setShutdown(true); return; } append(new CostPlace(this, &node, false, false, true)); } Account *Account::findAccount(const TQString &id) const { if (m_list) return m_list->findAccount(id); return 0; } bool Account::removeId(const TQString &id) { return (m_list ? m_list->removeId(id) : false); } bool Account::insertId() { return insertId(this); } bool Account::insertId(const Account *account) { return (m_list ? m_list->insertId(account) : false); } //------------------------------------ Account::CostPlace::~CostPlace() { if (m_node) { if (m_running) m_node->setRunningAccount(0); if (m_startup) m_node->setStartupAccount(0); if (m_shutdown) m_node->setShutdownAccount(0); } } void Account::CostPlace::setRunning(bool on ) { m_running = on; if (m_node) m_node->setRunningAccount(on ? m_account : 0); } void Account::CostPlace::setStartup(bool on ) { m_startup = on; if (m_node) m_node->setStartupAccount(on ? m_account : 0); } void Account::CostPlace::setShutdown(bool on ) { m_shutdown = on; if (m_node) m_node->setShutdownAccount(on ? m_account : 0); } bool Account::CostPlace::load(TQDomElement &element, const Project &project) { //kdDebug()<<k_funcinfo<<endl; m_nodeId = element.attribute("node-id"); if (m_nodeId.isEmpty()) { kdError()<<k_funcinfo<<"No node id"<<endl; return false; } m_node = project.findNode(m_nodeId); if (m_node == 0) { kdError()<<k_funcinfo<<"Cannot not find node with id: "<<m_nodeId<<endl; return false; } setRunning(element.attribute("running-cost").toInt()); setStartup(element.attribute("startup-cost").toInt()); setShutdown(element.attribute("shutdown-cost").toInt()); return true; } void Account::CostPlace::save(TQDomElement &element) const { //kdDebug()<<k_funcinfo<<endl; TQDomElement me = element.ownerDocument().createElement("costplace"); element.appendChild(me); me.setAttribute("node-id", m_nodeId); me.setAttribute("running-cost", m_running); me.setAttribute("startup-cost", m_startup); me.setAttribute("shutdown-cost", m_shutdown); } //--------------------------------- Accounts::Accounts(Project &project) : m_project(project), m_accountList(), m_idDict(), m_defaultAccount(0) { m_accountList.setAutoDelete(true); } Accounts::~Accounts() { m_accountList.clear(); } EffortCostMap Accounts::plannedCost(const Account &account, const TQDate &start, const TQDate &end) { EffortCostMap ec; TQPtrListIterator<Account::CostPlace> it = account.costPlaces(); for (; it.current(); ++it) { Node *n = it.current()->node(); if (n == 0) { continue; } //kdDebug()<<k_funcinfo<<"n="<<n->name()<<endl; if (it.current()->running()) { ec += n->plannedEffortCostPrDay(start, end); } if (it.current()->startup()) { if (n->startTime().date() >= start && n->startTime().date() <= end) ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost())); } if (it.current()->shutdown()) { if (n->endTime().date() >= start && n->endTime().date() <= end) ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost())); } } if (&account == m_defaultAccount) { TQDictIterator<Node> nit = m_project.nodeDict(); for (; nit.current(); ++nit) { Node *n = nit.current(); if (n->runningAccount() == 0) { ec += n->plannedEffortCostPrDay(start, end); } if (n->startupAccount() == 0) { if (n->startTime().date() >= start && n->startTime().date() <= end) ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost())); } if (n->shutdownAccount() == 0) { if (n->endTime().date() >= start && n->endTime().date() <= end) ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost())); } } } return ec; } void Accounts::append(Account *account) { Q_ASSERT(account); m_accountList.append(account); account->setList(this); account->setParent(0); // incase... insertId(account); //kdDebug()<<k_funcinfo<<account->name()<<endl; account->insertChildren(); } void Accounts::take(Account *account){ if (account == 0) { return; } removeId(account->name()); if (account->tqparent()) { account->tqparent()->take(account); return; } m_accountList.take(m_accountList.tqfindRef(account)); //kdDebug()<<k_funcinfo<<account->name()<<endl; } bool Accounts::load(TQDomElement &element, const Project &project) { TQDomNodeList list = element.childNodes(); for (unsigned int i=0; i<list.count(); ++i) { if (list.item(i).isElement()) { TQDomElement e = list.item(i).toElement(); if (e.tagName() == "account") { Account *child = new Account(); if (child->load(e, project)) { append(child); } else { // TODO: Complain about this kdWarning()<<k_funcinfo<<"Loading failed"<<endl; delete child; } } } } if (element.hasAttribute("default-account")) { m_defaultAccount = findAccount(element.attribute("default-account")); if (m_defaultAccount == 0) { kdWarning()<<k_funcinfo<<"Could not find default account."<<endl; } } return true; } void Accounts::save(TQDomElement &element) const { TQDomElement me = element.ownerDocument().createElement("accounts"); element.appendChild(me); if (m_defaultAccount) { me.setAttribute("default-account", m_defaultAccount->name()); } AccountListIterator it = m_accountList; for (; it.current(); ++it) { it.current()->save(me); } } TQStringList Accounts::costElements() const { TQDictIterator<Account> it(m_idDict); TQStringList l; for(; it.current(); ++it) { if (it.current()->isElement()) l << it.currentKey(); } return l; } TQStringList Accounts::nameList() const { TQDictIterator<Account> it(m_idDict); TQStringList l; for(; it.current(); ++it) { l << it.currentKey(); } return l; } Account *Accounts::findRunningAccount(const Node &node) const { TQDictIterator<Account> it = m_idDict; for (; it.current(); ++it) { if (it.current()->findRunning(node)) return it.current(); } return 0; } Account *Accounts::findStartupAccount(const Node &node) const { TQDictIterator<Account> it = m_idDict; for (; it.current(); ++it) { if (it.current()->findStartup(node)) return it.current(); } return 0; } Account *Accounts::findShutdownAccount(const Node &node) const { TQDictIterator<Account> it = m_idDict; for (; it.current(); ++it) { if (it.current()->findShutdown(node)) return it.current(); } return 0; } Account *Accounts::findAccount(const TQString &id) const { return m_idDict.tqfind(id); } bool Accounts::insertId(const Account *account) { Q_ASSERT(account); Account *a = m_idDict.tqfind(account->name()); if (a == 0) { //kdDebug()<<k_funcinfo<<"'"<<account->name()<<"' inserted"<<endl; m_idDict.insert(account->name(), account); return true; } if (a == account) { kdDebug()<<k_funcinfo<<"'"<<a->name()<<"' allready exists"<<endl; return true; } //TODO: Create unique id? kdWarning()<<k_funcinfo<<"Insert failed"<<endl; return false; } bool Accounts::removeId(const TQString &id) { bool res = m_idDict.remove(id); //kdDebug()<<k_funcinfo<<id<<": removed="<<res<<endl; return res; } #ifndef NDEBUG void Accounts::printDebug(TQString /*indent*/) { } void Account::printDebug(TQString /*indent*/) { } #endif } //namespace KPlato