2 * Project.cpp - TaskJuggler
4 * Copyright (c) 2001, 2002 by Chris Schlaeger <cs@suse.de>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
21 int Project::debugLevel = 0;
25 taskList.setAutoDelete(TRUE);
26 resourceList.setAutoDelete(TRUE);
27 activeAsap.setSorting(CoreAttributesList::PrioDown);
28 activeAlap.setSorting(CoreAttributesList::PrioDown);
30 dailyWorkingHours = 8.0;
31 scheduleGranularity = ONEHOUR;
45 Project::addId(const QString& id)
47 if (projectIDs.findIndex(id) != -1)
50 projectIDs.append(id);
55 Project::getIdIndex(const QString& i) const
58 if ((idx = projectIDs.findIndex(i)) == -1)
63 idxStr = QChar('A' + idx % ('Z' - 'A')) + idxStr;
65 } while (idx > 'Z' - 'A');
71 Project::addTask(Task* t)
83 taskList.createIndex();
84 resourceList.createIndex();
85 accountList.createIndex();
87 // Create hash to map task IDs to pointers.
88 for (Task* t = taskList.first(); t != 0; t = taskList.next())
90 idHash.insert(t->getId(), t);
93 // Create cross links from dependency lists.
94 for (Task* t = taskList.first(); t != 0; t = taskList.next())
100 bool hasActualValues = FALSE;
101 for (Task* t = taskList.first(); t != 0; t = taskList.next())
103 if (!t->preScheduleOk())
105 if (t->hasActualValues())
106 hasActualValues = TRUE;
113 qWarning("Scheduling plan scenario...");
121 qWarning("Scheduling actual scenario...");
131 Project::preparePlan()
133 for (Task* t = taskList.first(); t != 0; t = taskList.next())
135 for (Task* t = taskList.first(); t != 0; t = taskList.next())
136 t->propagateInitialValues();
137 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
142 Project::finishPlan()
144 for (Task* t = taskList.first(); t != 0; t = taskList.next())
146 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
151 Project::prepareActual()
153 for (Task* t = taskList.first(); t != 0; t = taskList.next())
155 for (Task* t = taskList.first(); t != 0; t = taskList.next())
156 t->propagateInitialValues();
157 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
162 Project::finishActual()
164 for (Task* t = taskList.first(); t != 0; t = taskList.next())
166 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
175 TaskList sortedTasks(taskList);
176 sortedTasks.setSorting(CoreAttributesList::PrioDown);
179 time_t timeDelta = scheduleGranularity;
183 updateActiveTaskList(sortedTasks);
184 for (day = start; !(activeAsap.isEmpty() && activeAlap.isEmpty()) &&
185 day >= start && day < end; day += timeDelta)
187 timeDelta = scheduleGranularity;
191 for (Task* t = activeAlap.first(); t != 0; t = activeAlap.next())
193 if (!t->schedule(day, scheduleGranularity))
196 break; // Start with top priority tasks again.
198 if (t->needsEarlierTimeSlot(day + scheduleGranularity))
199 timeDelta = -scheduleGranularity;
210 for (Task* t = activeAsap.first(); t != 0; t = activeAsap.next())
213 if (!t->schedule(day, scheduleGranularity))
216 break; // Start with top priority tasks again.
220 if (i != activeAsap.count())
221 qFatal("activeAsap list corrupted");
224 if (!activeAsap.isEmpty() || !activeAlap.isEmpty())
226 for (Task* t = activeAsap.first(); t != 0; t = activeAsap.next())
227 qWarning("Task %s does not fit into the project time frame",
228 t->getId().latin1());
229 for (Task* t = activeAlap.first(); t != 0; t = activeAlap.next())
230 qWarning("Task %s does not fit into the project time frame",
231 t->getId().latin1());
235 if (!checkSchedule())
242 Project::updateActiveTaskList(TaskList& sortedTasks)
244 for (Task* t = sortedTasks.first(); t != 0; t = sortedTasks.next())
250 Project::checkSchedule()
252 TaskList tl = taskList;
253 tl.setSorting(CoreAttributesList::StartDown);
256 for (Task* t = tl.first(); t != 0; t = tl.next())
258 if (!t->scheduleOk())
268 Project::generateReports()
271 qWarning("Generating reports...");
273 // Generate task reports
274 for (HTMLTaskReport* h = htmlTaskReports.first(); h != 0;
275 h = htmlTaskReports.next())
278 // Generate resource reports
279 for (HTMLResourceReport* r = htmlResourceReports.first(); r != 0;
280 r = htmlResourceReports.next())
283 // Generate account reports
284 for (HTMLAccountReport* r = htmlAccountReports.first(); r != 0;
285 r = htmlAccountReports.next())
288 for (ExportReport* e = exportReports.first(); e != 0;
289 e = exportReports.next())
293 xmlreport->generate();
297 Project::needsActualDataForReports()
299 bool needsActual = FALSE;
301 // Generate task reports
302 for (HTMLTaskReport* h = htmlTaskReports.first(); h != 0;
303 h = htmlTaskReports.next())
304 if (h->getShowActual())
306 // Generate resource reports
307 for (HTMLResourceReport* h = htmlResourceReports.first(); h != 0;
308 h = htmlResourceReports.next())
309 if (h->getShowActual())
312 // Generate account reports
313 for (HTMLAccountReport* h = htmlAccountReports.first(); h != 0;
314 h = htmlAccountReports.next())
315 if (h->getShowActual())
322 Project::removeActiveTask(Task* t)
327 qWarning("Deactivating %s", t->getId().latin1());
329 if (t->getScheduling() == Task::ASAP)
330 activeAsap.removeRef(t);
332 activeAlap.removeRef(t);
336 Project::addActiveTask(Task* t)
338 if (t->getScheduling() == Task::ASAP)
340 if (activeAsap.findRef(t) == -1)
343 qWarning("Activating %s", t->getId().latin1());
344 activeAsap.inSort(t);
349 if (activeAlap.findRef(t) == -1)
352 qWarning("Activating %s", t->getId().latin1());
353 activeAlap.inSort(t);