kplato

kptaccount.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005 Dag Andersen <danders@get2net.dk>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation;
7 version 2 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include <tqdom.h>
21#include <tqstring.h>
22
23#include <tdelocale.h>
24
25#include <kdebug.h>
26
27#include "kptaccount.h"
28#include "kptduration.h"
29#include "kptproject.h"
30
31namespace KPlato
32{
33
35 : m_name(),
36 m_description(),
37 m_list(0),
38 m_parent(0),
39 m_accountList(),
40 m_costPlaces() {
41
42 m_accountList.setAutoDelete(true);
43 m_costPlaces.setAutoDelete(true);
44}
45
46Account::Account(TQString name, TQString description)
47 : m_name(name),
48 m_description(description),
49 m_list(0),
50 m_parent(0),
51 m_accountList(),
52 m_costPlaces() {
53
54 m_accountList.setAutoDelete(true);
55 m_costPlaces.setAutoDelete(true);
56}
57
59 m_accountList.clear();
60 if (findAccount() == this) {
61 removeId(); // only remove myself (I may be just a working copy)
62 }
63 if (m_list)
64 m_list->accountDeleted(this);
65}
66
67
68void Account::setName(TQString name) {
69 if (findAccount() == this) {
70 removeId();
71 }
72 m_name = name;
73 insertId();
74}
75
76void Account::append(Account *account){
77 Q_ASSERT(account);
78 m_accountList.append(account);
79 account->setList(m_list);
80 account->setParent(this);
81 insertId(account);
82}
83
84void Account::insertChildren() {
85 AccountListIterator it = m_accountList;
86 for (; it.current(); ++it) {
87 it.current()->setList(m_list);
88 it.current()->setParent(this);
89 insertId(it.current());
90 it.current()->insertChildren();
91 }
92}
93
94void Account::take(Account *account) {
95 if (account == 0) {
96 return;
97 }
98 if (account->parent() == this) {
99 m_accountList.take(m_accountList.findRef(account));
100 } else if (account->parent()) {
101 account->parent()->take(account);
102 } else {
103 m_list->take(account);
104 }
105 //kdDebug()<<k_funcinfo<<account->name()<<endl;
106}
107
108bool Account::load(TQDomElement &element, const Project &project) {
109 m_name = element.attribute("name");
110 m_description = element.attribute("description");
111 TQDomNodeList list = element.childNodes();
112 for (unsigned int i=0; i<list.count(); ++i) {
113 if (list.item(i).isElement()) {
114 TQDomElement e = list.item(i).toElement();
115 if (e.tagName() == "costplace") {
116 Account::CostPlace *child = new Account::CostPlace(this);
117 if (child->load(e, project)) {
118 append(child);
119 } else {
120 delete child;
121 }
122 } else if (e.tagName() == "account") {
123 Account *child = new Account();
124 if (child->load(e, project)) {
125 m_accountList.append(child);
126 } else {
127 // TODO: Complain about this
128 kdWarning()<<k_funcinfo<<"Loading failed"<<endl;
129 delete child;
130 }
131 }
132 }
133 }
134 return true;
135}
136
137void Account::save(TQDomElement &element) const {
138 TQDomElement me = element.ownerDocument().createElement("account");
139 element.appendChild(me);
140 me.setAttribute("name", m_name);
141 me.setAttribute("description", m_description);
142 TQPtrListIterator<Account::CostPlace> cit = m_costPlaces;
143 for (; cit.current(); ++cit) {
144 cit.current()->save(me);
145 }
146 AccountListIterator it = m_accountList;
147 for (; it.current(); ++it) {
148 it.current()->save(me);
149 }
150}
151
152Account::CostPlace *Account::findCostPlace(const Node &node) const {
153 TQPtrListIterator<CostPlace> it = m_costPlaces;
154 for (; it.current(); ++it) {
155 if (&node == it.current()->node()) {
156 return it.current();
157 }
158 }
159 return 0;
160}
161
162Account::CostPlace *Account::findRunning(const Node &node) const {
163 Account::CostPlace *cp = findCostPlace(node);
164 return cp && cp->running() ? cp : 0;
165}
166
167void Account::removeRunning(const Node &node) {
168 Account::CostPlace *cp = findRunning(node);
169 if (cp) {
170 cp->setRunning(false);
171 if (cp->isEmpty()) {
172 m_costPlaces.removeRef(cp);
173 }
174 }
175}
176
177void Account::addRunning(Node &node) {
178 Account::CostPlace *cp = findCostPlace(node);
179 if (cp) {
180 cp->setRunning(true);
181 return;
182 }
183 append(new CostPlace(this, &node, true));
184}
185
186Account::CostPlace *Account::findStartup(const Node &node) const {
187 Account::CostPlace *cp = findCostPlace(node);
188 return cp && cp->startup() ? cp : 0;
189}
190
191void Account::removeStartup(const Node &node) {
192 Account::CostPlace *cp = findStartup(node);
193 if (cp) {
194 cp->setStartup(false);
195 if (cp->isEmpty()) {
196 m_costPlaces.removeRef(cp);
197 }
198 }
199}
200
201void Account::addStartup(Node &node) {
202 Account::CostPlace *cp = findCostPlace(node);
203 if (cp) {
204 cp->setStartup(true);
205 return;
206 }
207 append(new CostPlace(this, &node, false, true));
208
209}
210
211Account::CostPlace *Account::findShutdown(const Node &node) const {
212 Account::CostPlace *cp = findCostPlace(node);
213 return cp && cp->shutdown() ? cp : 0;
214}
215
216void Account::removeShutdown(const Node &node) {
217 Account::CostPlace *cp = findShutdown(node);
218 if (cp) {
219 cp->setShutdown(false);
220 if (cp->isEmpty()) {
221 m_costPlaces.removeRef(cp);
222 }
223 }
224}
225
226void Account::addShutdown(Node &node) {
227 Account::CostPlace *cp = findCostPlace(node);
228 if (cp) {
229 cp->setShutdown(true);
230 return;
231 }
232 append(new CostPlace(this, &node, false, false, true));
233}
234
235Account *Account::findAccount(const TQString &id) const {
236 if (m_list)
237 return m_list->findAccount(id);
238 return 0;
239}
240
241bool Account::removeId(const TQString &id) {
242 return (m_list ? m_list->removeId(id) : false);
243}
244
245bool Account::insertId() {
246 return insertId(this);
247}
248
249bool Account::insertId(const Account *account) {
250 return (m_list ? m_list->insertId(account) : false);
251}
252
253//------------------------------------
254Account::CostPlace::~CostPlace() {
255 if (m_node) {
256 if (m_running)
257 m_node->setRunningAccount(0);
258 if (m_startup)
259 m_node->setStartupAccount(0);
260 if (m_shutdown)
261 m_node->setShutdownAccount(0);
262 }
263}
264
265void Account::CostPlace::setRunning(bool on ) {
266 m_running = on;
267 if (m_node)
268 m_node->setRunningAccount(on ? m_account : 0);
269}
270
271void Account::CostPlace::setStartup(bool on ) {
272 m_startup = on;
273 if (m_node)
274 m_node->setStartupAccount(on ? m_account : 0);
275}
276
277void Account::CostPlace::setShutdown(bool on ) {
278 m_shutdown = on;
279 if (m_node)
280 m_node->setShutdownAccount(on ? m_account : 0);
281}
282
283bool Account::CostPlace::load(TQDomElement &element, const Project &project) {
284 //kdDebug()<<k_funcinfo<<endl;
285 m_nodeId = element.attribute("node-id");
286 if (m_nodeId.isEmpty()) {
287 kdError()<<k_funcinfo<<"No node id"<<endl;
288 return false;
289 }
290 m_node = project.findNode(m_nodeId);
291 if (m_node == 0) {
292 kdError()<<k_funcinfo<<"Cannot not find node with id: "<<m_nodeId<<endl;
293 return false;
294 }
295 setRunning(element.attribute("running-cost").toInt());
296 setStartup(element.attribute("startup-cost").toInt());
297 setShutdown(element.attribute("shutdown-cost").toInt());
298 return true;
299}
300
301void Account::CostPlace::save(TQDomElement &element) const {
302 //kdDebug()<<k_funcinfo<<endl;
303 TQDomElement me = element.ownerDocument().createElement("costplace");
304 element.appendChild(me);
305 me.setAttribute("node-id", m_nodeId);
306 me.setAttribute("running-cost", m_running);
307 me.setAttribute("startup-cost", m_startup);
308 me.setAttribute("shutdown-cost", m_shutdown);
309
310}
311
312//---------------------------------
313Accounts::Accounts(Project &project)
314 : m_project(project),
315 m_accountList(),
316 m_idDict(),
317 m_defaultAccount(0) {
318
319 m_accountList.setAutoDelete(true);
320}
321
322Accounts::~Accounts() {
323 m_accountList.clear();
324}
325
326EffortCostMap Accounts::plannedCost(const Account &account, const TQDate &start, const TQDate &end) {
327 EffortCostMap ec;
328 TQPtrListIterator<Account::CostPlace> it = account.costPlaces();
329 for (; it.current(); ++it) {
330 Node *n = it.current()->node();
331 if (n == 0) {
332 continue;
333 }
334 //kdDebug()<<k_funcinfo<<"n="<<n->name()<<endl;
335 if (it.current()->running()) {
336 ec += n->plannedEffortCostPrDay(start, end);
337 }
338 if (it.current()->startup()) {
339 if (n->startTime().date() >= start &&
340 n->startTime().date() <= end)
341 ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost()));
342 }
343 if (it.current()->shutdown()) {
344 if (n->endTime().date() >= start &&
345 n->endTime().date() <= end)
346 ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost()));
347 }
348 }
349 if (&account == m_defaultAccount) {
350 TQDictIterator<Node> nit = m_project.nodeDict();
351 for (; nit.current(); ++nit) {
352 Node *n = nit.current();
353 if (n->runningAccount() == 0) {
354 ec += n->plannedEffortCostPrDay(start, end);
355 }
356 if (n->startupAccount() == 0) {
357 if (n->startTime().date() >= start &&
358 n->startTime().date() <= end)
359 ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost()));
360 }
361 if (n->shutdownAccount() == 0) {
362 if (n->endTime().date() >= start &&
363 n->endTime().date() <= end)
364 ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost()));
365 }
366 }
367 }
368 return ec;
369}
370
371void Accounts::append(Account *account) {
372 Q_ASSERT(account);
373 m_accountList.append(account);
374 account->setList(this);
375 account->setParent(0); // incase...
376 insertId(account);
377 //kdDebug()<<k_funcinfo<<account->name()<<endl;
378 account->insertChildren();
379}
380
381void Accounts::take(Account *account){
382 if (account == 0) {
383 return;
384 }
385 removeId(account->name());
386 if (account->parent()) {
387 account->parent()->take(account);
388 return;
389 }
390 m_accountList.take(m_accountList.findRef(account));
391 //kdDebug()<<k_funcinfo<<account->name()<<endl;
392}
393
394bool Accounts::load(TQDomElement &element, const Project &project) {
395 TQDomNodeList list = element.childNodes();
396 for (unsigned int i=0; i<list.count(); ++i) {
397 if (list.item(i).isElement()) {
398 TQDomElement e = list.item(i).toElement();
399 if (e.tagName() == "account") {
400 Account *child = new Account();
401 if (child->load(e, project)) {
402 append(child);
403 } else {
404 // TODO: Complain about this
405 kdWarning()<<k_funcinfo<<"Loading failed"<<endl;
406 delete child;
407 }
408 }
409 }
410 }
411 if (element.hasAttribute("default-account")) {
412 m_defaultAccount = findAccount(element.attribute("default-account"));
413 if (m_defaultAccount == 0) {
414 kdWarning()<<k_funcinfo<<"Could not find default account."<<endl;
415 }
416 }
417 return true;
418}
419
420void Accounts::save(TQDomElement &element) const {
421 TQDomElement me = element.ownerDocument().createElement("accounts");
422 element.appendChild(me);
423 if (m_defaultAccount) {
424 me.setAttribute("default-account", m_defaultAccount->name());
425 }
426 AccountListIterator it = m_accountList;
427 for (; it.current(); ++it) {
428 it.current()->save(me);
429 }
430}
431
432TQStringList Accounts::costElements() const {
433 TQDictIterator<Account> it(m_idDict);
434 TQStringList l;
435 for(; it.current(); ++it) {
436 if (it.current()->isElement())
437 l << it.currentKey();
438 }
439 return l;
440}
441
442
443TQStringList Accounts::nameList() const {
444 TQDictIterator<Account> it(m_idDict);
445 TQStringList l;
446 for(; it.current(); ++it) {
447 l << it.currentKey();
448 }
449 return l;
450}
451
452Account *Accounts::findRunningAccount(const Node &node) const {
453 TQDictIterator<Account> it = m_idDict;
454 for (; it.current(); ++it) {
455 if (it.current()->findRunning(node))
456 return it.current();
457 }
458 return 0;
459}
460
461Account *Accounts::findStartupAccount(const Node &node) const {
462 TQDictIterator<Account> it = m_idDict;
463 for (; it.current(); ++it) {
464 if (it.current()->findStartup(node))
465 return it.current();
466 }
467 return 0;
468}
469
470Account *Accounts::findShutdownAccount(const Node &node) const {
471 TQDictIterator<Account> it = m_idDict;
472 for (; it.current(); ++it) {
473 if (it.current()->findShutdown(node))
474 return it.current();
475 }
476 return 0;
477}
478
479Account *Accounts::findAccount(const TQString &id) const {
480 return m_idDict.find(id);
481}
482
483bool Accounts::insertId(const Account *account) {
484 Q_ASSERT(account);
485 Account *a = m_idDict.find(account->name());
486 if (a == 0) {
487 //kdDebug()<<k_funcinfo<<"'"<<account->name()<<"' inserted"<<endl;
488 m_idDict.insert(account->name(), account);
489 return true;
490 }
491 if (a == account) {
492 kdDebug()<<k_funcinfo<<"'"<<a->name()<<"' allready exists"<<endl;
493 return true;
494 }
495 //TODO: Create unique id?
496 kdWarning()<<k_funcinfo<<"Insert failed"<<endl;
497 return false;
498}
499
500bool Accounts::removeId(const TQString &id) {
501 bool res = m_idDict.remove(id);
502 //kdDebug()<<k_funcinfo<<id<<": removed="<<res<<endl;
503 return res;
504}
505
506#ifndef NDEBUG
507void Accounts::printDebug(TQString /*indent*/) {
508}
509void Account::printDebug(TQString /*indent*/) {
510}
511#endif
512} //namespace KPlato
Account holds one account.
Definition kptaccount.h:49
~Account()
Destructor.
Account()
Constructor.
static const Duration zeroDuration
This is useful for occasions where we need a zero duration.
This class represents any node in the project, a node can be a project or a subproject or any task.
Definition kptnode.h:57
Project is the main node in a project, it contains child nodes and possibly sub-projects.
Definition kptproject.h:52