1 /*
2  * CoreAttributes.h - TaskJuggler
3  *
4  * Copyright (c) 2001, 2002, 2003, 2004, 2005 by Chris Schlaeger <cs@kde.org>
5  * Copyright (c) 2011 by Dag Andersen <danders@get2net.dk>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * $Id$
12  */
13 
14 // clazy:excludeall=qstring-arg
15 #include "CoreAttributes.h"
16 #include "CoreAttributesList.h"
17 #include "CustomAttributeDefinition.h"
18 // #include "TextAttribute.h"
19 // #include "ReferenceAttribute.h"
20 #include "Task.h"
21 
22 namespace TJ
23 {
24 
25 
CoreAttributes(Project * p,const QString & i,const QString & n,CoreAttributes * parent_,const QString & df,uint dl)26 CoreAttributes::CoreAttributes(Project* p, const QString& i,
27                                const QString& n,
28                                CoreAttributes* parent_, const QString& df,
29                                uint dl) :
30     project(p),
31     id(i),
32     name(n),
33     parent(parent_),
34     definitionFile(df),
35     definitionLine(dl),
36     sequenceNo(0),
37     hierarchNo(0),
38     index(-1),
39     hierarchIndex(0),
40     sub(new CoreAttributesList()),
41     flags(),
42     customAttributes()
43 {
44 //     customAttributes.setAutoDelete(true);
45     if (parent_)
46         parent_->sub->append(this);
47 
48 //     qDebug()<<"CoreAttributes:"<<this;
49 }
50 
~CoreAttributes()51 CoreAttributes::~CoreAttributes()
52 {
53     qDebug()<<"~CoreAttributes:"<<this;
54     while (!sub->isEmpty())
55         delete sub->takeFirst();
56     if (parent && parent->sub->contains(this))
57         parent->sub->removeAt(parent->sub->indexOf(this));
58     delete sub;
59     while (!customAttributes.isEmpty()) delete customAttributes.values().takeFirst();
60 }
61 
62 uint
treeLevel() const63 CoreAttributes::treeLevel() const
64 {
65     uint tl = 0;
66     for (CoreAttributes* c = parent; c; c = c->parent)
67         tl++;
68     return tl;
69 }
70 
71 CoreAttributesList
getSubList() const72 CoreAttributes::getSubList() const
73 {
74    return *sub;
75 }
76 
77 CoreAttributesListIterator
getSubListIterator() const78 CoreAttributes::getSubListIterator() const
79 {
80     return CoreAttributesListIterator(*sub);
81 }
82 
83 bool
hasSubs() const84 CoreAttributes::hasSubs() const
85 {
86     return !sub->isEmpty();
87 }
88 
89 void
setHierarchNo(uint no)90 CoreAttributes::setHierarchNo(uint no)
91 {
92     hierarchNo = no;
93     uint hNo = 1;
94     foreach (CoreAttributes *a, *sub) {
95         a->setHierarchNo(hNo++);
96     }
97 }
98 
99 QString
getHierarchNo() const100 CoreAttributes::getHierarchNo() const
101 {
102     QString text;
103     const CoreAttributes* ca = this;
104     do
105     {
106         if (!text.isEmpty())
107             text.prepend(QLatin1Char('.'));
108         text = QString("%1").arg(ca->hierarchNo) + text;
109         ca = ca->getParent();
110     }
111     while (ca);
112     return text;
113 }
114 
115 void
setHierarchIndex(uint no)116 CoreAttributes::setHierarchIndex(uint no)
117 {
118     if (no == 0)
119     {
120         hierarchIndex = 0;
121         return;
122     }
123     /* If there is no parent, we take the passed number. */
124     if (!parent)
125     {
126         hierarchIndex = no;
127         return;
128     }
129 
130     /* Find the highest hierarchIndex of all children of this CAs parent. */
131     uint max = 0;
132     foreach (CoreAttributes *a, (*parent->sub)) {
133         if (a->hierarchIndex > max)
134             max = a->hierarchIndex;
135     }
136     /* The index is then the highest found + 1. */
137     hierarchIndex = max + 1;
138 }
139 
140 QString
getHierarchIndex() const141 CoreAttributes::getHierarchIndex() const
142 {
143     QString text;
144     const CoreAttributes* ca = this;
145     while (ca)
146     {
147         if (!text.isEmpty())
148             text.prepend(QLatin1Char('.'));
149         text = QString("%1").arg(ca->hierarchIndex) + text;
150         ca = ca->getParent();
151     }
152     return text;
153 }
154 
155 QString
getHierarchLevel() const156 CoreAttributes::getHierarchLevel() const
157 {
158     return QString("%1").arg(treeLevel());
159 }
160 
161 void
getFullName(QString & fullName) const162 CoreAttributes::getFullName(QString& fullName) const
163 {
164     fullName.clear();
165     for (const CoreAttributes* c = this; c != 0; c = c->parent)
166         fullName = c->name + QLatin1Char('.') + fullName;
167     // Remove trailing dot.
168     fullName.remove(fullName.length() - 1, 1);
169 }
170 
171 QString
getFullId() const172 CoreAttributes::getFullId() const
173 {
174     QString fullID = id;
175     for (const CoreAttributes* c = parent; c != 0; c = c->parent)
176         fullID = c->id + QLatin1Char('.') + fullID;
177     return fullID;
178 }
179 
180 bool
hasSameAncestor(const CoreAttributes * c) const181 CoreAttributes::hasSameAncestor(const CoreAttributes* c) const
182 {
183     if (c == 0)
184         return false;
185 
186     CoreAttributes const* p1;
187     for (p1 = this; p1->parent; p1 = p1->parent)
188         ;
189     CoreAttributes const* p2;
190     for (p2 = c; p2->parent; p2 = p2->parent)
191         ;
192     return p1 == p2;
193 }
194 
195 bool
isDescendantOf(const CoreAttributes * c) const196 CoreAttributes::isDescendantOf(const CoreAttributes* c) const
197 {
198     if (c == 0)
199         return false;
200 
201     for (CoreAttributes const* p = this->parent; p; p = p->parent)
202         if (p == c)
203             return true;
204 
205     return false;
206 }
207 
208 bool
isParentOf(const CoreAttributes * c) const209 CoreAttributes::isParentOf(const CoreAttributes* c) const
210 {
211     if (!c)
212         return false;
213 
214     for (CoreAttributes const* p = c->parent; p; p = p->parent)
215         if (p == this)
216             return true;
217 
218     return false;
219 }
220 
221 bool
isLeaf() const222 CoreAttributes::isLeaf() const
223 {
224     return sub->isEmpty();
225 }
226 
227 void
addCustomAttribute(const QString & id,CustomAttribute * ca)228 CoreAttributes::addCustomAttribute(const QString& id, CustomAttribute* ca)
229 {
230     customAttributes.insert(id, ca);
231 }
232 
233 const CustomAttribute*
getCustomAttribute(const QString & id) const234 CoreAttributes::getCustomAttribute(const QString& id) const
235 {
236     return customAttributes[id];
237 }
238 
239 void
inheritCustomAttributes(const QMap<QString,CustomAttributeDefinition * > & dict)240 CoreAttributes::inheritCustomAttributes
241 (const QMap<QString, CustomAttributeDefinition*>& dict)
242 {
243     QMap<QString, CustomAttributeDefinition*>::const_iterator cadi = dict.constBegin();
244     for (; cadi != dict.constEnd(); ++cadi)
245     {
246         const CustomAttribute* custAttr;
247         if (cadi.value()->getInherit() &&
248                 (custAttr = parent->getCustomAttribute(cadi.key())))
249         {
250             switch (custAttr->getType())
251             {
252             case CAT_Text:
253 /*                addCustomAttribute(cadi.key(), new TextAttribute
254                                    (*(static_cast<const TextAttribute*>(custAttr))));
255                 break;*/
256             case CAT_Reference:
257 /*                addCustomAttribute(cadi.key(), new ReferenceAttribute
258                                    (*(static_cast<const ReferenceAttribute*>(custAttr))));
259                 break;*/
260             default:
261                 qFatal("CoreAttributes::inheritCustomAttributes: "
262                        "Unknown CAT %d", custAttr->getType());
263                 break;
264             }
265         }
266     }
267 }
268 
269 } // namespace TJ
270 
operator <<(QDebug dbg,const TJ::CoreAttributes * t)271 QDebug operator<<(QDebug dbg, const TJ::CoreAttributes* t)
272 {
273     if (t == 0) {
274         return dbg << (void*)t;
275     }
276     return operator<<(dbg, *t);
277 }
278 
operator <<(QDebug dbg,const TJ::CoreAttributes & t)279 QDebug operator<<(QDebug dbg, const TJ::CoreAttributes& t)
280 {
281     switch (t.getType()) {
282         case CA_Task: dbg << "Task[" << t.getName() << "]"; break;
283         case CA_Resource: dbg << "Resource[" << t.getName() << "]"; break;
284         case CA_Account: dbg << "Account[" << t.getName() << "]"; break;
285         case CA_Shift: dbg << "Shift[" << t.getName() << "]"; break;
286         case CA_Scenario: dbg << "Scenario[" << t.getName() << "]"; break;
287         default: dbg << "CoreAttribute[" << t.getName() << "]"; break;
288     }
289     return dbg;
290 }
291