kplato

kptaccount.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Dag Andersen <danders@get2net.dk>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation;
00007    version 2 of the License.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <qdom.h>
00021 #include <qstring.h>
00022 
00023 #include <klocale.h>
00024 
00025 #include <kdebug.h>
00026 
00027 #include "kptaccount.h"
00028 #include "kptduration.h"
00029 #include "kptproject.h"
00030 
00031 namespace KPlato
00032 {
00033 
00034 Account::Account()
00035     : m_name(),
00036       m_description(),
00037       m_list(0),
00038       m_parent(0),
00039       m_accountList(),
00040       m_costPlaces() {
00041     
00042     m_accountList.setAutoDelete(true);
00043     m_costPlaces.setAutoDelete(true);
00044 }
00045 
00046 Account::Account(QString name, QString description)
00047     : m_name(name),
00048       m_description(description),
00049       m_list(0),
00050       m_parent(0),
00051       m_accountList(),
00052       m_costPlaces() {
00053     
00054     m_accountList.setAutoDelete(true);
00055     m_costPlaces.setAutoDelete(true);
00056 }
00057 
00058 Account::~Account() {
00059     m_accountList.clear();
00060     if (findAccount() == this) {
00061         removeId(); // only remove myself (I may be just a working copy)
00062     }
00063     if (m_list)
00064         m_list->accountDeleted(this);
00065 }
00066     
00067 
00068 void Account::setName(QString name) {
00069     if (findAccount() == this) {
00070         removeId();
00071     }
00072     m_name = name;
00073     insertId();
00074 }
00075 
00076 void Account::append(Account *account){
00077     Q_ASSERT(account);
00078     m_accountList.append(account); 
00079     account->setList(m_list);
00080     account->setParent(this);
00081     insertId(account);
00082 }
00083 
00084 void Account::insertChildren() {
00085     AccountListIterator it = m_accountList;
00086     for (; it.current(); ++it) {
00087         it.current()->setList(m_list);
00088         it.current()->setParent(this);
00089         insertId(it.current());
00090         it.current()->insertChildren();
00091     }
00092 }
00093 
00094 void Account::take(Account *account) {
00095     if (account == 0) {
00096         return;
00097     }
00098     if (account->parent() == this) {
00099         m_accountList.take(m_accountList.findRef(account));
00100     } else if (account->parent()) {
00101         account->parent()->take(account);
00102     } else {
00103         m_list->take(account);
00104     }
00105     //kdDebug()<<k_funcinfo<<account->name()<<endl;
00106 }
00107     
00108 bool Account::load(QDomElement &element, const Project &project) {
00109     m_name = element.attribute("name");
00110     m_description = element.attribute("description");
00111     QDomNodeList list = element.childNodes();
00112     for (unsigned int i=0; i<list.count(); ++i) {
00113         if (list.item(i).isElement()) {
00114             QDomElement e = list.item(i).toElement();
00115             if (e.tagName() == "costplace") {
00116                 Account::CostPlace *child = new Account::CostPlace(this);
00117                 if (child->load(e, project)) {
00118                     append(child);
00119                 } else {
00120                     delete child;
00121                 }
00122             } else if (e.tagName() == "account") {
00123                 Account *child = new Account();
00124                 if (child->load(e, project)) {
00125                     m_accountList.append(child);
00126                 } else {
00127                     // TODO: Complain about this
00128                     kdWarning()<<k_funcinfo<<"Loading failed"<<endl;
00129                     delete child;
00130                 }
00131             }
00132         }
00133     }
00134     return true;
00135 }
00136 
00137 void Account::save(QDomElement &element) const {
00138     QDomElement me = element.ownerDocument().createElement("account");
00139     element.appendChild(me);
00140     me.setAttribute("name", m_name);
00141     me.setAttribute("description", m_description);
00142     QPtrListIterator<Account::CostPlace> cit = m_costPlaces;
00143     for (; cit.current(); ++cit) {
00144         cit.current()->save(me);
00145     }
00146     AccountListIterator it = m_accountList;
00147     for (; it.current(); ++it) {
00148         it.current()->save(me);
00149     }
00150 }
00151 
00152 Account::CostPlace *Account::findCostPlace(const Node &node) const {
00153     QPtrListIterator<CostPlace> it = m_costPlaces;
00154     for (; it.current(); ++it) {
00155         if (&node == it.current()->node()) {
00156             return it.current();
00157         }
00158     }
00159     return 0;    
00160 }
00161 
00162 Account::CostPlace *Account::findRunning(const Node &node) const {
00163     Account::CostPlace *cp = findCostPlace(node);
00164     return cp && cp->running() ? cp : 0;
00165 }
00166 
00167 void Account::removeRunning(const Node &node) {
00168     Account::CostPlace *cp = findRunning(node);
00169     if (cp) {
00170         cp->setRunning(false);
00171         if (cp->isEmpty()) {
00172             m_costPlaces.removeRef(cp);
00173         }
00174     }
00175 }
00176 
00177 void Account::addRunning(Node &node) {
00178     Account::CostPlace *cp = findCostPlace(node);
00179     if (cp) {
00180         cp->setRunning(true);
00181         return;
00182     }
00183     append(new CostPlace(this, &node, true));
00184 }
00185 
00186 Account::CostPlace *Account::findStartup(const Node &node) const {
00187     Account::CostPlace *cp = findCostPlace(node);
00188     return cp && cp->startup() ? cp : 0;
00189 }
00190 
00191 void Account::removeStartup(const Node &node) {
00192     Account::CostPlace *cp = findStartup(node);
00193     if (cp) {
00194         cp->setStartup(false);
00195         if (cp->isEmpty()) {
00196             m_costPlaces.removeRef(cp);
00197         }
00198     }
00199 }
00200 
00201 void Account::addStartup(Node &node) {
00202     Account::CostPlace *cp = findCostPlace(node);
00203     if (cp) {
00204         cp->setStartup(true);
00205         return;
00206     }
00207     append(new CostPlace(this, &node, false, true));
00208 
00209 }
00210 
00211 Account::CostPlace *Account::findShutdown(const Node &node) const {
00212     Account::CostPlace *cp = findCostPlace(node);
00213     return cp && cp->shutdown() ? cp : 0;
00214 }
00215 
00216 void Account::removeShutdown(const Node &node) {
00217     Account::CostPlace *cp = findShutdown(node);
00218     if (cp) {
00219         cp->setShutdown(false);
00220         if (cp->isEmpty()) {
00221             m_costPlaces.removeRef(cp);
00222         }
00223     }
00224 }
00225 
00226 void Account::addShutdown(Node &node) {
00227     Account::CostPlace *cp = findCostPlace(node);
00228     if (cp) {
00229         cp->setShutdown(true);
00230         return;
00231     }
00232     append(new CostPlace(this, &node, false, false, true));
00233 }
00234 
00235 Account *Account::findAccount(const QString &id) const {
00236     if (m_list) 
00237         return m_list->findAccount(id);
00238     return 0;
00239 }
00240 
00241 bool Account::removeId(const QString &id) {
00242     return (m_list ? m_list->removeId(id) : false);
00243 }
00244 
00245 bool Account::insertId() {
00246     return insertId(this);
00247 }
00248 
00249 bool Account::insertId(const Account *account) {
00250     return (m_list ? m_list->insertId(account) : false);
00251 }
00252 
00253 //------------------------------------
00254 Account::CostPlace::~CostPlace() {
00255     if (m_node) {
00256         if (m_running)
00257             m_node->setRunningAccount(0);
00258         if (m_startup)
00259             m_node->setStartupAccount(0);
00260         if (m_shutdown)
00261             m_node->setShutdownAccount(0);
00262     }
00263 }
00264 
00265 void Account::CostPlace::setRunning(bool on ) { 
00266     m_running = on;
00267     if (m_node)
00268         m_node->setRunningAccount(on ? m_account : 0);
00269 }
00270 
00271 void Account::CostPlace::setStartup(bool on ) { 
00272     m_startup = on;
00273     if (m_node)
00274         m_node->setStartupAccount(on ? m_account : 0);
00275 }
00276 
00277 void Account::CostPlace::setShutdown(bool on ) { 
00278     m_shutdown = on;
00279     if (m_node)
00280         m_node->setShutdownAccount(on ? m_account : 0);
00281 }
00282 
00283 bool Account::CostPlace::load(QDomElement &element, const Project &project) {
00284     //kdDebug()<<k_funcinfo<<endl;
00285     m_nodeId = element.attribute("node-id");
00286     if (m_nodeId.isEmpty()) {
00287         kdError()<<k_funcinfo<<"No node id"<<endl;
00288         return false;
00289     }
00290     m_node = project.findNode(m_nodeId);
00291     if (m_node == 0) {
00292         kdError()<<k_funcinfo<<"Cannot not find node with id: "<<m_nodeId<<endl;
00293         return false;
00294     }
00295     setRunning(element.attribute("running-cost").toInt());
00296     setStartup(element.attribute("startup-cost").toInt());
00297     setShutdown(element.attribute("shutdown-cost").toInt());
00298     return true;
00299 }
00300 
00301 void Account::CostPlace::save(QDomElement &element) const {
00302     //kdDebug()<<k_funcinfo<<endl;
00303     QDomElement me = element.ownerDocument().createElement("costplace");
00304     element.appendChild(me);
00305     me.setAttribute("node-id", m_nodeId);
00306     me.setAttribute("running-cost", m_running);
00307     me.setAttribute("startup-cost", m_startup);
00308     me.setAttribute("shutdown-cost", m_shutdown);
00309     
00310 }
00311 
00312 //---------------------------------
00313 Accounts::Accounts(Project &project)
00314     : m_project(project),
00315       m_accountList(),
00316       m_idDict(),
00317       m_defaultAccount(0) {
00318       
00319     m_accountList.setAutoDelete(true);
00320 }
00321 
00322 Accounts::~Accounts() {
00323     m_accountList.clear();
00324 }
00325 
00326 EffortCostMap Accounts::plannedCost(const Account &account, const QDate &start, const QDate &end) {
00327     EffortCostMap ec;
00328     QPtrListIterator<Account::CostPlace> it = account.costPlaces();
00329     for (; it.current(); ++it) {
00330         Node *n = it.current()->node();
00331         if (n == 0) {
00332             continue;
00333         }
00334         //kdDebug()<<k_funcinfo<<"n="<<n->name()<<endl;
00335         if (it.current()->running()) {
00336             ec += n->plannedEffortCostPrDay(start, end);
00337         }
00338         if (it.current()->startup()) {
00339             if (n->startTime().date() >= start &&
00340                 n->startTime().date() <= end)
00341                 ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost()));
00342         }
00343         if (it.current()->shutdown()) {
00344             if (n->endTime().date() >= start &&
00345                 n->endTime().date() <= end)
00346                 ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost()));
00347         }
00348     }
00349     if (&account == m_defaultAccount) {
00350         QDictIterator<Node> nit = m_project.nodeDict();
00351         for (; nit.current(); ++nit) {
00352             Node *n = nit.current();
00353             if (n->runningAccount() == 0) {
00354                 ec += n->plannedEffortCostPrDay(start, end);
00355             }
00356             if (n->startupAccount() == 0) {
00357                 if (n->startTime().date() >= start &&
00358                     n->startTime().date() <= end)
00359                     ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost()));
00360             }
00361             if (n->shutdownAccount() == 0) {
00362                 if (n->endTime().date() >= start &&
00363                     n->endTime().date() <= end)
00364                     ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost()));
00365             }
00366         }
00367     }
00368     return ec;
00369 }
00370 
00371 void Accounts::append(Account *account) {
00372     Q_ASSERT(account);
00373     m_accountList.append(account); 
00374     account->setList(this);
00375     account->setParent(0); // incase...
00376     insertId(account);
00377     //kdDebug()<<k_funcinfo<<account->name()<<endl;
00378     account->insertChildren();
00379 }
00380 
00381 void Accounts::take(Account *account){
00382     if (account == 0) {
00383         return;
00384     }
00385     removeId(account->name());
00386     if (account->parent()) {
00387         account->parent()->take(account);
00388         return;
00389     }
00390     m_accountList.take(m_accountList.findRef(account));
00391     //kdDebug()<<k_funcinfo<<account->name()<<endl;
00392 }
00393     
00394 bool Accounts::load(QDomElement &element, const Project &project) {
00395     QDomNodeList list = element.childNodes();
00396     for (unsigned int i=0; i<list.count(); ++i) {
00397         if (list.item(i).isElement()) {
00398             QDomElement e = list.item(i).toElement();
00399             if (e.tagName() == "account") {
00400                 Account *child = new Account();
00401                 if (child->load(e, project)) {
00402                     append(child);
00403                 } else {
00404                     // TODO: Complain about this
00405                     kdWarning()<<k_funcinfo<<"Loading failed"<<endl;
00406                     delete child;
00407                 }
00408             }
00409         }
00410     }
00411     if (element.hasAttribute("default-account")) {
00412         m_defaultAccount = findAccount(element.attribute("default-account"));
00413         if (m_defaultAccount == 0) {
00414             kdWarning()<<k_funcinfo<<"Could not find default account."<<endl;
00415         }
00416     }
00417     return true;
00418 }
00419 
00420 void Accounts::save(QDomElement &element) const {
00421     QDomElement me = element.ownerDocument().createElement("accounts");
00422     element.appendChild(me);
00423     if (m_defaultAccount) {
00424         me.setAttribute("default-account", m_defaultAccount->name());
00425     }
00426     AccountListIterator it = m_accountList;
00427     for (; it.current(); ++it) {
00428         it.current()->save(me);
00429     }
00430 }
00431 
00432 QStringList Accounts::costElements() const {
00433     QDictIterator<Account> it(m_idDict);
00434     QStringList l;
00435     for(; it.current(); ++it) {
00436         if (it.current()->isElement())
00437             l << it.currentKey();
00438     }
00439     return l;
00440 }
00441     
00442 
00443 QStringList Accounts::nameList() const {
00444     QDictIterator<Account> it(m_idDict);
00445     QStringList l;
00446     for(; it.current(); ++it) {
00447         l << it.currentKey();
00448     }
00449     return l;
00450 }
00451     
00452 Account *Accounts::findRunningAccount(const Node &node) const {
00453     QDictIterator<Account> it = m_idDict;
00454     for (; it.current(); ++it) {
00455         if (it.current()->findRunning(node))
00456             return it.current();
00457     }
00458     return 0;
00459 }
00460 
00461 Account *Accounts::findStartupAccount(const Node &node) const {
00462     QDictIterator<Account> it = m_idDict;
00463     for (; it.current(); ++it) {
00464         if (it.current()->findStartup(node))
00465             return it.current();
00466     }
00467     return 0;
00468 }
00469 
00470 Account *Accounts::findShutdownAccount(const Node &node) const {
00471     QDictIterator<Account> it = m_idDict;
00472     for (; it.current(); ++it) {
00473         if (it.current()->findShutdown(node))
00474             return it.current();
00475     }
00476     return 0;
00477 }
00478 
00479 Account *Accounts::findAccount(const QString &id) const {
00480     return m_idDict.find(id);
00481 }
00482 
00483 bool Accounts::insertId(const Account *account) {
00484     Q_ASSERT(account);
00485     Account *a = m_idDict.find(account->name());
00486     if (a == 0) {
00487         //kdDebug()<<k_funcinfo<<"'"<<account->name()<<"' inserted"<<endl;
00488         m_idDict.insert(account->name(), account);
00489         return true;
00490     }
00491     if (a == account) {
00492         kdDebug()<<k_funcinfo<<"'"<<a->name()<<"' allready exists"<<endl;
00493         return true;
00494     }
00495     //TODO: Create unique id?
00496     kdWarning()<<k_funcinfo<<"Insert failed"<<endl;
00497     return false;
00498 }
00499 
00500 bool Accounts::removeId(const QString &id) {
00501     bool res = m_idDict.remove(id);
00502     //kdDebug()<<k_funcinfo<<id<<": removed="<<res<<endl;
00503     return res;
00504 }
00505 
00506 #ifndef NDEBUG
00507 void Accounts::printDebug(QString /*indent*/) {
00508 }
00509 void Account::printDebug(QString /*indent*/) {
00510 }
00511 #endif
00512 } //namespace KPlato
KDE Home | KDE Accessibility Home | Description of Access Keys