2 * Project.h - TaskJuggler
4 * Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006
5 * by Chris Schlaeger <cs@kde.org>
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.
19 #include "VacationList.h"
20 #include "ScenarioList.h"
22 #include "ShiftList.h"
23 #include "ResourceList.h"
24 #include "AccountList.h"
33 class CustomAttributeDefinition;
34 class VacationInterval;
38 * The Project class is the root of the data tree of the application.
39 * Applications can use multiple Project objects. This is e. g. needed when
40 * the application needs to preserve the state prior to a scheduler run. The
41 * scheduler calculates the data in place, adding the calculated values to the
42 * existing data structures. Since the original data cannot be identified
43 * anymore the applications needs to make a copy of the project before calling
44 * the scheduler. For that purpose Project and all related sub-classes provide
47 * @short The root class of all project related information.
48 * @author Chris Schlaeger <cs@kde.org>
50 class Project : public QObject
57 void addSourceFile(const QString& f);
58 QStringList getSourceFiles() const;
59 // Called to emit a signal with the currently processed file.
60 void setProgressInfo(const QString& i);
61 // Called to emit a signal with the current process of the scheduler.
62 void setProgressBar(int i, int of);
64 * Projects have at least one ID, but can have multiple IDs. This usually
65 * happens when projects are composed of serveral sub-projects. Each sub
66 * projects brings its own unique ID. Each ID must be registered with the
67 * project by calling addId(). The most recently added ID is also the
68 * current ID. All subsequently added tasks are associtated with this
69 * project ID. So, you have to add at least one ID before you add any
72 bool addId(const QString& i, bool changeCurrentId = true);
75 * Returns the first (default) ID of the project.
79 return projectIDs.isEmpty() ? QString::null : projectIDs.first();
82 * Returns the current project ID. If the project ID list is empty
83 * QString::null is returned.
85 QString getCurrentId() const
90 * Returns a list of all registered project IDs.
92 QStringList getProjectIdList() const { return projectIDs; }
94 * Returns true if the passed ID is a registered project ID.
96 bool isValidId(const QString& i) const
98 return projectIDs.findIndex(i) != -1;
101 * Returns a string ID of the index of the passed ID in the project ID.
102 * The first ID in the list is returned as "A", the second as "B". The
103 * 27th is "AA" and so on.
105 QString getIdIndex(const QString& i) const;
108 * Returns the number of supported scenarios.
110 int getMaxScenarios() const { return scenarioList.count(); }
112 * Returns a pointer to the scenario.
113 * @param sc Index of the scenario in the project scenario list.
115 Scenario* getScenario(int sc) const;
117 * Returns a pointer to the scenario with index sc.
118 * @param sc Index of the scenario in the project scenario list.
120 const QString& getScenarioId(int sc) const;
122 * Returns the name of a scenario.
123 * @param sc Index of the scenario in the project scenario list.
125 const QString& getScenarioName(int sc) const;
127 * Returns the index of the scenario. The index of the first item in the
128 * list is 1, not 0! If the scenario is unknown -1 is returned.
129 * @param id the ID of the scenario.
131 int getScenarioIndex(const QString& id) const;
133 * Returns an interator for the list of defined scenarios.
135 ScenarioListIterator getScenarioIterator() const
137 return ScenarioListIterator(scenarioList);
141 * Set the name of the project. The project name is mainly used for the
144 void setName(const QString& n) { name = n; }
146 * Returns the name of the project.
148 const QString& getName() const { return name; }
151 * Set the version number of the project. This version is mainly used for
154 void setVersion(const QString& v) { version = v; }
156 * Returns the version number of the project.
158 const QString& getVersion() const { return version; }
161 * Set the copyright information. This is a default text used for all
164 void setCopyright(const QString& c) { copyright = c; }
166 * Returns the copyright information of the project.
168 const QString& getCopyright() const { return copyright; }
171 * Set the customer information for this project.
173 void setCustomer(const QString& c) { customer = c; }
175 * Returns the customer information of the project.
177 const QString& getCustomer() const { return customer; }
180 * Set the default priority for all top-level tasks. Normally this value
183 void setPriority(int p) { priority = p; }
185 * Returns the default priority for all top-level tasks.
187 int getPriority() const { return priority; }
190 * Set the start time of the project.
192 void setStart(time_t s) { start = s; }
194 * Get the start time of the project.
196 time_t getStart() const { return start; }
199 * Set the end time of the project. The specified second is still
200 * considered as within the project time frame.
202 void setEnd(time_t e) { end = e; }
204 * Get the end time of the project.
206 time_t getEnd() const { return end; }
209 * Set the date that TaskJuggler uses as current date for all
210 * computations. This mainly affects status reporting and the computation
211 * of the completion degree of tasks. */
212 void setNow(time_t n);
214 * Get the date that TaskJuggler uses as current date.
216 time_t getNow() const { return now; }
219 * Specifies whether TaskJuggler uses Sunday or Monday as first day of the
220 * week. Besides the calendar views this mainly affects the numbering of
221 * weeks. ISO 8601:1988 requires the week to start on Monday as most
222 * European countries use, but other Countries like the US use Sunday as
223 * first day of the week.
225 void setWeekStartsMonday(bool wsm) { weekStartsMonday = wsm; }
227 * Get the setting for the first day of the week.
228 * @return true of weeks should start on Monday.
230 bool getWeekStartsMonday() const { return weekStartsMonday; }
232 * Decides if containers which subtasks are all hidden should be
233 * drawn as normal tasks or not.
235 void setDrawEmptyContainersAsTasks(bool decat)
237 drawEmptyContainerAsTasks = decat;
240 * @return true if containers which subtasks are all hidden should be
241 * drawn as normal tasks
243 bool getDrawEmptyContainersAsTasks() const
245 return drawEmptyContainerAsTasks;
248 * Set the working hours of the specified weekday.
249 * @param day The day of the week. Independently of the weekStartsMonday
250 * setting TaskJuggler uses 0 for Sunday, 1 for Monday and so on.
251 * @param l The list of working intervals. The interval use seconds since
252 * midnight. As with all TaskJuggler intervals, the specified end value is
253 * not part of the interval. The interval ends one seconds earlier.
255 void setWorkingHours(int day, const QPtrList<Interval>& l);
257 * Returns a constant list of working intervals for all week days.
259 const QPtrList<Interval>* const * getWorkingHours() const
264 * Returns the list of working intervals for the specified weekday.
265 * @param day Day of the week. 0 for Sunday, 1 for Monday and so on.
267 QPtrList<Interval>* getWorkingHours(int day) const
269 if (day < 0 || day > 6)
270 qFatal("day out of range");
271 return workingHours[day];
274 * Returns an interator for the list of working intervals for the
276 * @param day Day of the week. 0 for Sunday, 1 for Monday and so on.
278 QPtrListIterator<Interval> getWorkingHoursIterator(int day) const
280 return QPtrListIterator<Interval>(*workingHours[day]);
283 * If there is a working interval defined for this weekday and the
284 * day is not registered as a vacation day then it is a workday.
286 bool isWorkingDay(time_t d) const;
289 * If date is contained in a vacation day or the date is outside
290 * of the defined working hours, false is returned. Otherwise true.
292 bool isWorkingTime(time_t d) const;
295 * If the interval overlaps with a vacation day or the interval is outside
296 * of the defined working hours, false is returned. Otherwise true.
298 bool isWorkingTime(const Interval& iv) const;
301 * Returns the number of working days that overlap with the specified
304 int calcWorkingDays(const Interval& iv) const;
307 * The daily working hours value is used to convert working hours into
308 * working days. It should be an avarage value of the specified
309 * workingHours for each week day. With this function you can set the
310 * value for the project.
312 void setDailyWorkingHours(double h) { dailyWorkingHours = h; }
314 * Returns the specified daily working hours.
316 double getDailyWorkingHours() const { return dailyWorkingHours; }
319 * The weekly working days value is used to convert working days into
320 * working weeks. It should match the number of working days specified
321 * with the workingHours. The value is derived from the yearlyWorkingDays
322 * setting. This function returns the value.
324 double getWeeklyWorkingDays() const
326 return yearlyWorkingDays / 52.1429;
330 * The monthly working days value is used to convert working days into
331 * working month. It should reflect the workingHours settings and the
332 * vacation settings. The value is derived from the yearlyWorkingDays
333 * setting. This function returns the value.
335 double getMonthlyWorkingDays() const
337 return yearlyWorkingDays / 12;
341 * The yearly working days value is used to convert working days into
342 * working years. The value should reflect the workingHours settings and
343 * the vacation settings. This function sets the value which also affects
344 * the monthly working days and the weekly working days.
346 void setYearlyWorkingDays(double wd) { yearlyWorkingDays = wd; }
348 * Returns the specified number of working days per year.
350 double getYearlyWorkingDays() const { return yearlyWorkingDays; }
352 void setScheduleGranularity(ulong s) { scheduleGranularity = s; }
353 ulong getScheduleGranularity() const { return scheduleGranularity; }
355 void setAllowRedefinitions(bool ar) { allowRedefinitions = ar; }
356 bool getAllowRedefinitions() const { return allowRedefinitions; }
359 * Add a vacation interval to the vacation list. These global vacations
360 * are meant for events like Christmas, Eastern or corporate hollidays.
361 * A day that overlaps any of the intervals in the list is considered to
362 * not be a working day. Vacation intervals may not overlap.
363 * @param n Name of the vacation.
364 * @param i The time interval the vacation lasts.
366 void addVacation(const QString& n, const Interval& i)
368 vacationList.add(n, i);
370 void addVacation(VacationInterval* vi)
372 vacationList.add(vi);
375 * Returns true if the passed moment falls within any of the vacation
378 bool isVacation(time_t vd) const { return vacationList.isVacation(vd); }
381 * Returns the name of the first vacation that the given date falls into.
382 * If no vacation is found QString::Null is returned.
384 const QString& vacationName(time_t vd) const
386 return vacationList.vacationName(vd);
390 * Returns an iterator for the vacation list.
392 VacationList::Iterator getVacationListIterator() const
394 return VacationList::Iterator(vacationList);
398 * This function is for library internal use only. Creating a Scenario
399 * object with the project as parameter will automatically add it to the
400 * scenario list of the project.
402 void addScenario(Scenario* r);
404 * This function is for library internal use only. Deleting a Scenario
405 * will automatically delete it from the respective list of the
408 void deleteScenario(Scenario* s);
411 * This function is for library internal use only. Creating a Task object
412 * with the project as parameter will automatically add it to the Task
413 * list of the project.
415 void addTask(Task* t);
417 * This function is for library internal use only. Deleting a Task
418 * will automatically delete it from the respective list of the
421 void deleteTask(Task* t);
423 * Returns a pointer to the Task with the specified ID. The ID must be an
424 * absolute ID of the form "foo.bar". If no Task with the ID exists 0 is
427 Task* getTask(const QString& id) const
429 return taskList.getTask(id);
432 * Returns the number of tasks of the project.
434 uint taskCount() const { return taskList.count(); }
436 * Returns a copy of the Task list of the project.
438 TaskList getTaskList() const { return taskList; }
440 * Returns an iterator that can be used to traverse the Task list. The
441 * Task list is a flat list of all tasks.
443 TaskListIterator getTaskListIterator() const
445 return TaskListIterator(taskList);
448 * This function adds a new, user-defined attribute to the Task
449 * attributes. The @param id must be unique within the Task attributes
450 * namespace. @param cad is a pointer to the CustomAttributeDefinition
453 bool addTaskAttribute(const QString& id, CustomAttributeDefinition* cad);
455 * Returns a pointer to the custom attribute object identified by @param id.
456 * If no attributes with the id exists, 0 is returned.
458 const CustomAttributeDefinition* getTaskAttribute(const QString& id) const;
460 * Returns a read-only pointer to the dictionary that holds the pointers
461 * to user-defined attributes of Tasks.
463 const QDict<CustomAttributeDefinition>&
464 getTaskAttributeDict() const
466 return taskAttributes;
470 * This function is for library internal use only. Creating a Resource
471 * object with the project as parameter will automatically add it to the
472 * resource list of the project.
474 void addResource(Resource* r);
476 * This function is for library internal use only. Deleting a Resource
477 * will automatically delete it from the respective list of the
480 void deleteResource(Resource* r);
482 * Returns a pointer to the Resource with the specified ID. The ID must
483 * not be an absolute ID since the Resource list has a flat namespace. If
484 * no Resource with the ID exists 0 is returned.
486 Resource* getResource(const QString& id) const
488 return resourceList.getResource(id);
491 * Returns the number of resources in the Resource list.
493 uint resourceCount() const { return resourceList.count(); }
495 * Returns a copy of the Resource list.
497 ResourceList getResourceList() const { return resourceList; }
499 * Returns an iterator that can be used to traverse the Resource list. The
500 * Resource list is a flat list of all resources.
502 ResourceListIterator getResourceListIterator() const
504 return ResourceListIterator(resourceList);
507 * This function adds a new, user-defined attribute to the Resource
508 * attributes. The @param id must be unique within the Resource attributes
509 * namespace. @param cad is a pointer to the CustomAttributeDefinition
512 bool addResourceAttribute(const QString& name,
513 CustomAttributeDefinition* cad);
515 * Returns a pointer to the custom attribute object identified by @param id.
516 * If no attributes with the id exists, 0 is returned.
518 const CustomAttributeDefinition* getResourceAttribute(const QString& id)
521 * Returns a read-only pointer to the dictionary that holds the pointers
522 * to user-defined attributes of Resources.
524 const QDict<CustomAttributeDefinition>&
525 getResourceAttributeDict() const
527 return resourceAttributes;
531 * This function is for library internal use only. Creating an Account
532 * object with the project as parameter will automatically add it to the
533 * Account list of the project.
535 void addAccount(Account* a);
537 * This function is for library internal use only. Deleting a Account
538 * will automatically delete it from the respective list of the
541 void deleteAccount(Account* a);
543 * Returns a pointer to the Account with the specified ID. The ID may
544 * not be an absolute ID since the account list has a flat namespace. If
545 * no Account with the ID exists 0 is returned.
547 Account* getAccount(const QString& id) const
549 return accountList.getAccount(id);
552 * Returns the number of accounts in the Account list.
554 uint accountCount() const { return accountList.count(); }
556 * Returns a copy of the Account list.
558 AccountList getAccountList() const { return accountList; }
560 * Returns an iterator that can be used to traverse the Account list. The
561 * Account list is a flat list of all accounts.
563 AccountListIterator getAccountListIterator() const
565 return AccountListIterator(accountList);
568 * This function adds a new, user-defined attribute to the Account
569 * attributes. The @param id must be unique within the Account attributes
570 * namespace. @param cad is a pointer to the CustomAttributeDefinition
573 bool addAccountAttribute(const QString& name,
574 CustomAttributeDefinition* cad);
576 * Returns a pointer to the custom attribute object identified by @param id.
577 * If no attributes with the id exists, 0 is returned.
579 const CustomAttributeDefinition* getAccountAttribute(const QString& id)
582 * Returns a read-only pointer to the dictionary that holds the pointers
583 * to user-defined attributes of Accounts.
585 const QDict<CustomAttributeDefinition>&
586 getAccountAttributeDict() const
588 return accountAttributes;
592 * This function is for library internal use only. Creating a Shift
593 * object with the project as parameter will automatically add it to the
594 * Shift list of the project.
596 void addShift(Shift* s);
598 * This function is for library internal use only. Deleting a Shift
599 * will automatically delete it from the respective list of the
602 void deleteShift(Shift* s);
604 * Returns a pointer to the Shift with the specified ID. The ID may
605 * not be an absolute ID since the Shift list has a flat namespace. If
606 * no Shift with the ID exists 0 is returned.
608 Shift* getShift(const QString& id) const
610 return shiftList.getShift(id);
613 * Returns the number of shifts in the shift list.
615 uint shiftCount() const { return shiftList.count(); }
617 * Returns a copy of the Shift list.
619 ShiftList getShiftList() const { return shiftList; }
621 * Returns an iterator that can be used to traverse the Shift list. The
622 * Shift list is a flat list of all accounts.
624 ShiftListIterator getShiftListIterator() const
626 return ShiftListIterator(shiftList);
630 * Set the minimum daily effort for resources. This value is not used for
631 * resource allocation. It is currently not used at all. In future
632 * versions TaskJuggler might spit out warnings for all resources that are
633 * not loaded to at least this value each day. The value is inherited by
634 * all resources that are created subsequent to this function call.
636 void setMinEffort(double m) { minEffort = m; }
638 * Returns the default minimum effort value.
640 double getMinEffort() const { return minEffort; }
643 * Set the maximum efforts for resources. This is the default value
644 * inherited by all resources created subsequent to this function call. A
645 * resource is never loaded more each day, week, month etc. than the
646 * maximum effort value specified for the resource.
648 void setResourceLimits(UsageLimits* l);
651 * Returns the default effort limits for resources.
653 const UsageLimits* getResourceLimits() const { return resourceLimits; }
656 * Set the default daily cost rate for resources. This value is inherited
657 * by all resources created subsequent to this function call.
659 void setRate(double r) { rate = r; }
661 * Return the default daily cost rate for resources.
663 double getRate() const { return rate; }
666 * Set the currency unit for the project.
668 void setCurrency(const QString& s) { currency = s; }
670 * Returns the currency unit setting.
672 const QString& getCurrency() const { return currency; }
675 * Sets the number of decimal digits used for all currency values of the
678 void setCurrencyDigits(uint cd) { currencyFormat.setFracDigits(cd); }
681 * Sets the default number format for load and other values.
683 void setNumberFormat(const RealFormat& rf) { numberFormat = rf; }
685 * Returns the current default number format.
687 const RealFormat& getNumberFormat() const { return numberFormat; }
690 * Sets the default currency format.
692 void setCurrencyFormat(const RealFormat& rf) { currencyFormat = rf; }
694 * Returns the default currency format.
696 const RealFormat& getCurrencyFormat() const { return currencyFormat; }
699 * Set the default time zone for the project.
701 bool setTimeZone(const QString& tz);
703 * Returns the default time zone of the project;
705 const QString& getTimeZone() const { return timeZone; }
708 * Sets the format used for timestamps in reports. It will be used as
709 * default for all subsequent report definitions. See the TaskJuggler
710 * manual for the format details.
712 void setShortTimeFormat(const QString& tf) { shortTimeFormat = tf; }
714 * Returns the format for timestamps in reports.
716 const QString& getShortTimeFormat() const { return shortTimeFormat; }
719 * Sets the format used for date stamps in reports. It will be used as
720 * default for all subsequent report definitions. See the TaskJuggler
721 * manual for the format details.
723 void setTimeFormat(const QString& tf) { timeFormat = tf; }
725 * Returns the format for date stamps in reports.
727 const QString& getTimeFormat() const { return timeFormat; }
729 void addXMLReport(ReportXML *r ) { xmlreport = r; }
731 void addReport(Report* r)
735 Report* getReport(uint idx) const;
736 QPtrListIterator<Report> getReportListIterator() const;
738 void addAllowedFlag(QString flag)
740 if (!isAllowedFlag(flag))
741 allowedFlags.append(flag);
743 bool isAllowedFlag(const QString& flag) const
745 return allowedFlags.contains(flag) > 0;
748 const QStringList getAllowedFlags() const
754 * Converts working seconds to working days.
756 double convertToDailyLoad(long secs) const;
759 * Adjust load for rounding errors.
761 double quantizeLoad(double load) const;
764 * Converts load values (effort) to time slots.
766 long int convertToSlots(double effort) const;
768 void setMaxErrors(int me) { maxErrors = me; }
770 void addJournalEntry(JournalEntry* entry);
772 bool hasJournal() const { return !journal.isEmpty(); }
774 Journal::Iterator getJournalIterator() const;
777 * Generate cross references between all data structures and run a
778 * consistency check. This function must be called after the project data
779 * tree has been contructed.
780 * @return Only if all tests were successful true is returned.
782 bool pass2(bool noDepCheck);
784 bool scheduleScenario(Scenario* sc);
785 void breakScheduling();
786 void completeBuffersAndIndices();
787 bool scheduleAllScenarios();
788 bool generateReports() const;
790 bool generateXMLReport() const;
793 void updateProgressInfo(const QString& i);
794 void updateProgressBar(int i, int of);
797 void overlayScenario(int base, int sc);
798 void prepareScenario(int sc);
799 void finishScenario(int sc);
801 bool schedule(int sc);
803 bool checkSchedule(int sc) const;
805 /// The start date of the project
807 /// The end date of the project
809 /// The current date used in status calculations and reports.
812 bool allowRedefinitions;
814 /// True if week based calculations use Monday as first day of week.
815 bool weekStartsMonday;
817 /// True if containers w/o visible subtask should be drawn as normal tasks
818 bool drawEmptyContainerAsTasks;
820 /// The name of the Project
822 /// The revision of the project description.
824 /// Some legal words to please the boss.
827 /// Some information about the customer of this project.
830 /// The default timezone of the project.
833 * A format string in strftime(3) format that specifies the default time
834 * format for all time values TaskJuggler generates.
838 * A format string in strftime(3) format that specifies the time format
839 * for all daytime values (e. g. HH:MM).
841 QString shortTimeFormat;
843 /// The currency of used for all money values.
845 /// The number of fraction digits of all money values.
848 // The default format used for printing load values and the like.
849 RealFormat numberFormat;
850 // The default format used for printing currency values.
851 RealFormat currencyFormat;
854 * The default priority that will be inherited by all tasks. Sub tasks
855 * will inherit the priority of its parent task. */
858 /// Default values for Resource variables (TODO: should be obsoleted!)
862 * The default resource usage limits.
864 UsageLimits* resourceLimits;
867 * The default daily cost of a resource. The value is inherited to all
868 * resources but can be overridden.
872 /* The average number of working hours per day. This factor is used
873 * when converting hours in working days. It should match the workingHours
875 double dailyWorkingHours;
877 /* The average number of working days per year. This factor is used when
878 * converting working days into years. It should match the defined working
879 * hours and vacation days. */
880 double yearlyWorkingDays;
882 /* The list of standard working or opening hours. These values will be
883 * inherited by the resources as default working hours. */
884 QPtrList<Interval>* workingHours[7];
887 * The granularity of the scheduler in seconds. No intervals
888 * shorter than this time will be scheduled. */
889 ulong scheduleGranularity;
892 * To avoid difficult to find typos in flag names all flags must
893 * be registered before they can be used. This variable contains
894 * the list of all registered flags. It is legal to declare a flag
895 * twice, so we can merge projects to a larger project. */
896 QStringList allowedFlags;
899 * Each project has a unique ID but can have multiple other IDs as
900 * well. This happens usually when small projects are merged to a
901 * create a big project. Each task can be assigned to a different
902 * project ID but all IDs must be declared before they can be
904 QStringList projectIDs;
912 VacationList vacationList;
914 ScenarioList scenarioList;
916 ResourceList resourceList;
917 AccountList accountList;
921 * The following lists contain a deep copy of their unscheduled
922 * counterpart. They will be used to initialize the working lists before
925 TaskList originalTaskList;
926 ResourceList originalResourceList;
927 AccountList originalAccountList;
929 QDict<CustomAttributeDefinition> taskAttributes;
930 QDict<CustomAttributeDefinition> resourceAttributes;
931 QDict<CustomAttributeDefinition> accountAttributes;
933 /* This is for version 1.0 XML reports and should be removed before the
934 * next major release. */
935 ReportXML* xmlreport;
937 QPtrList<Report> reports;
938 QStringList sourceFiles;
940 // This flag is raised to abort the scheduling.