summaryrefslogtreecommitdiffstats
path: root/kplato/kptaccount.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kplato/kptaccount.cc')
-rw-r--r--kplato/kptaccount.cc512
1 files changed, 512 insertions, 0 deletions
diff --git a/kplato/kptaccount.cc b/kplato/kptaccount.cc
new file mode 100644
index 00000000..42dff604
--- /dev/null
+++ b/kplato/kptaccount.cc
@@ -0,0 +1,512 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Dag Andersen <[email protected]>
+
+ 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 <qdom.h>
+#include <qstring.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(QString name, QString 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(QString 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->parent() == this) {
+ m_accountList.take(m_accountList.findRef(account));
+ } else if (account->parent()) {
+ account->parent()->take(account);
+ } else {
+ m_list->take(account);
+ }
+ //kdDebug()<<k_funcinfo<<account->name()<<endl;
+}
+
+bool Account::load(QDomElement &element, const Project &project) {
+ m_name = element.attribute("name");
+ m_description = element.attribute("description");
+ QDomNodeList list = element.childNodes();
+ for (unsigned int i=0; i<list.count(); ++i) {
+ if (list.item(i).isElement()) {
+ QDomElement 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(QDomElement &element) const {
+ QDomElement me = element.ownerDocument().createElement("account");
+ element.appendChild(me);
+ me.setAttribute("name", m_name);
+ me.setAttribute("description", m_description);
+ QPtrListIterator<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 {
+ QPtrListIterator<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 QString &id) const {
+ if (m_list)
+ return m_list->findAccount(id);
+ return 0;
+}
+
+bool Account::removeId(const QString &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(QDomElement &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(QDomElement &element) const {
+ //kdDebug()<<k_funcinfo<<endl;
+ QDomElement 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 QDate &start, const QDate &end) {
+ EffortCostMap ec;
+ QPtrListIterator<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) {
+ QDictIterator<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->parent()) {
+ account->parent()->take(account);
+ return;
+ }
+ m_accountList.take(m_accountList.findRef(account));
+ //kdDebug()<<k_funcinfo<<account->name()<<endl;
+}
+
+bool Accounts::load(QDomElement &element, const Project &project) {
+ QDomNodeList list = element.childNodes();
+ for (unsigned int i=0; i<list.count(); ++i) {
+ if (list.item(i).isElement()) {
+ QDomElement 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(QDomElement &element) const {
+ QDomElement 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);
+ }
+}
+
+QStringList Accounts::costElements() const {
+ QDictIterator<Account> it(m_idDict);
+ QStringList l;
+ for(; it.current(); ++it) {
+ if (it.current()->isElement())
+ l << it.currentKey();
+ }
+ return l;
+}
+
+
+QStringList Accounts::nameList() const {
+ QDictIterator<Account> it(m_idDict);
+ QStringList l;
+ for(; it.current(); ++it) {
+ l << it.currentKey();
+ }
+ return l;
+}
+
+Account *Accounts::findRunningAccount(const Node &node) const {
+ QDictIterator<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 {
+ QDictIterator<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 {
+ QDictIterator<Account> it = m_idDict;
+ for (; it.current(); ++it) {
+ if (it.current()->findShutdown(node))
+ return it.current();
+ }
+ return 0;
+}
+
+Account *Accounts::findAccount(const QString &id) const {
+ return m_idDict.find(id);
+}
+
+bool Accounts::insertId(const Account *account) {
+ Q_ASSERT(account);
+ Account *a = m_idDict.find(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 QString &id) {
+ bool res = m_idDict.remove(id);
+ //kdDebug()<<k_funcinfo<<id<<": removed="<<res<<endl;
+ return res;
+}
+
+#ifndef NDEBUG
+void Accounts::printDebug(QString /*indent*/) {
+}
+void Account::printDebug(QString /*indent*/) {
+}
+#endif
+} //namespace KPlato