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.
22 int Project::debugLevel = 0;
26 taskList.setAutoDelete(TRUE);
27 resourceList.setAutoDelete(TRUE);
28 activeAsap.setSorting(CoreAttributesList::PrioDown);
29 activeAlap.setSorting(CoreAttributesList::PrioDown);
31 dailyWorkingHours = 8.0;
32 scheduleGranularity = ONEHOUR;
47 Project::addId(const QString& id)
49 if (projectIDs.findIndex(id) != -1)
52 projectIDs.append(id);
57 Project::getIdIndex(const QString& i) const
60 if ((idx = projectIDs.findIndex(i)) == -1)
65 idxStr = QChar('A' + idx % ('Z' - 'A')) + idxStr;
67 } while (idx > 'Z' - 'A');
73 Project::addTask(Task* t)
85 taskList.createIndex();
86 resourceList.createIndex();
87 accountList.createIndex();
89 // Create hash to map task IDs to pointers.
90 for (Task* t = taskList.first(); t != 0; t = taskList.next())
92 idHash.insert(t->getId(), t);
95 // Create cross links from dependency lists.
96 for (Task* t = taskList.first(); t != 0; t = taskList.next())
102 bool hasActualValues = FALSE;
103 for (Task* t = taskList.first(); t != 0; t = taskList.next())
105 if (!t->preScheduleOk())
107 if (t->hasActualValues())
108 hasActualValues = TRUE;
115 qWarning("Scheduling plan scenario...");
123 qWarning("Scheduling actual scenario...");
133 Project::preparePlan()
135 for (Task* t = taskList.first(); t != 0; t = taskList.next())
137 for (Task* t = taskList.first(); t != 0; t = taskList.next())
138 t->propagateInitialValues();
139 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
144 Project::finishPlan()
146 for (Task* t = taskList.first(); t != 0; t = taskList.next())
148 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
153 Project::prepareActual()
155 for (Task* t = taskList.first(); t != 0; t = taskList.next())
157 for (Task* t = taskList.first(); t != 0; t = taskList.next())
158 t->propagateInitialValues();
159 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
164 Project::finishActual()
166 for (Task* t = taskList.first(); t != 0; t = taskList.next())
168 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
177 TaskList sortedTasks(taskList);
178 sortedTasks.setSorting(CoreAttributesList::PrioDown);
181 time_t timeDelta = scheduleGranularity;
185 updateActiveTaskList(sortedTasks);
186 for (day = start; !(activeAsap.isEmpty() && activeAlap.isEmpty()) &&
187 day >= start && day < end; day += timeDelta)
189 timeDelta = scheduleGranularity;
193 for (Task* t = activeAlap.first(); t != 0; t = activeAlap.next())
195 if (!t->schedule(day, scheduleGranularity))
198 break; // Start with top priority tasks again.
200 if (t->needsEarlierTimeSlot(day + scheduleGranularity))
201 timeDelta = -scheduleGranularity;
212 for (Task* t = activeAsap.first(); t != 0; t = activeAsap.next())
215 if (!t->schedule(day, scheduleGranularity))
218 break; // Start with top priority tasks again.
222 if (i != activeAsap.count())
223 qFatal("activeAsap list corrupted");
226 if (!activeAsap.isEmpty() || !activeAlap.isEmpty())
228 for (Task* t = activeAsap.first(); t != 0; t = activeAsap.next())
229 qWarning("Task %s does not fit into the project time frame",
230 t->getId().latin1());
231 for (Task* t = activeAlap.first(); t != 0; t = activeAlap.next())
232 qWarning("Task %s does not fit into the project time frame",
233 t->getId().latin1());
237 if (!checkSchedule())
244 Project::updateActiveTaskList(TaskList& sortedTasks)
246 for (Task* t = sortedTasks.first(); t != 0; t = sortedTasks.next())
252 Project::checkSchedule()
254 TaskList tl = taskList;
255 tl.setSorting(CoreAttributesList::StartDown);
258 for (Task* t = tl.first(); t != 0; t = tl.next())
260 if (!t->scheduleOk())
270 Project::setKotrus(Kotrus* k)
278 Project::generateReports()
281 qWarning("Generating reports...");
283 // Generate task reports
284 for (HTMLTaskReport* h = htmlTaskReports.first(); h != 0;
285 h = htmlTaskReports.next())
288 // Generate resource reports
289 for (HTMLResourceReport* r = htmlResourceReports.first(); r != 0;
290 r = htmlResourceReports.next())
293 // Generate account reports
294 for (HTMLAccountReport* r = htmlAccountReports.first(); r != 0;
295 r = htmlAccountReports.next())
298 for (ExportReport* e = exportReports.first(); e != 0;
299 e = exportReports.next())
303 xmlreport->generate();
306 icalReport->generate();
311 Project::needsActualDataForReports()
313 bool needsActual = FALSE;
315 // Generate task reports
316 for (HTMLTaskReport* h = htmlTaskReports.first(); h != 0;
317 h = htmlTaskReports.next())
318 if (h->getShowActual())
320 // Generate resource reports
321 for (HTMLResourceReport* h = htmlResourceReports.first(); h != 0;
322 h = htmlResourceReports.next())
323 if (h->getShowActual())
326 // Generate account reports
327 for (HTMLAccountReport* h = htmlAccountReports.first(); h != 0;
328 h = htmlAccountReports.next())
329 if (h->getShowActual())
336 Project::removeActiveTask(Task* t)
341 qWarning("Deactivating %s", t->getId().latin1());
343 if (t->getScheduling() == Task::ASAP)
344 activeAsap.removeRef(t);
346 activeAlap.removeRef(t);
350 Project::addActiveTask(Task* t)
352 if (t->getScheduling() == Task::ASAP)
354 if (activeAsap.findRef(t) == -1)
357 qWarning("Activating %s", t->getId().latin1());
358 activeAsap.inSort(t);
363 if (activeAlap.findRef(t) == -1)
366 qWarning("Activating %s", t->getId().latin1());
367 activeAlap.inSort(t);
373 Project::readKotrus()
378 for (Resource* r = resourceList.first(); r != 0; r = resourceList.next())
379 r->dbLoadBookings(r->getKotrusId(), 0);
385 Project::updateKotrus()