1 | /* This file is part of the KDE project |
2 | Copyright (C) 2001 Thomas Zander zander@kde.org |
3 | Copyright (C) 2004 - 2010 Dag Andersen <danders@get2net.dk> |
4 | Copyright (C) 2007 Florian Piquemal <flotueur@yahoo.fr> |
5 | Copyright (C) 2007 Alexis Ménard <darktears31@gmail.com> |
6 | |
7 | This library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public |
9 | License as published by the Free Software Foundation; either |
10 | version 2 of the License, or (at your option) any later version. |
11 | |
12 | This library is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | Library General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU Library General Public License |
18 | along with this library; see the file COPYING.LIB. If not, write to |
19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | * Boston, MA 02110-1301, USA. |
21 | */ |
22 | |
23 | #ifndef KPTPROJECT_H |
24 | #define KPTPROJECT_H |
25 | |
26 | #include "kplatokernel_export.h" |
27 | |
28 | #include "kptnode.h" |
29 | |
30 | #include "kptglobal.h" |
31 | #include "kptaccount.h" |
32 | #include "kptcalendar.h" |
33 | #include "kptdatetime.h" |
34 | #include "kptduration.h" |
35 | #include "kptresource.h" |
36 | #include "kptwbsdefinition.h" |
37 | #include "kptconfigbase.h" |
38 | |
39 | #include <QMap> |
40 | #include <QList> |
41 | #include <QHash> |
42 | #include <QPointer> |
43 | |
44 | #include <klocale.h> |
45 | #include <ktimezone.h> |
46 | |
47 | |
48 | /// The main namespace. |
49 | namespace KPlato |
50 | { |
51 | |
52 | class Schedule; |
53 | class StandardWorktime; |
54 | class ScheduleManager; |
55 | class XMLLoaderObject; |
56 | class Task; |
57 | class SchedulerPlugin; |
58 | class KPlatoXmlLoaderBase; |
59 | |
60 | /** |
61 | * Project is the main node in a project, it contains child nodes and |
62 | * possibly sub-projects. A sub-project is just another instantion of this |
63 | * node however. |
64 | * |
65 | * A note on timezones: |
66 | * To be able to handle resources working in diffierent timezones and |
67 | * to facilitate data exchange with other applications like PIMs or |
68 | * and groupware servers, the project has a timezone that is used for |
69 | * all datetimes in nodes and schedules. |
70 | * By default the local timezone is used. |
71 | * |
72 | * A resources timezone is defined by the associated calendar. |
73 | * |
74 | * Note that a projects datetimes are always displayed/modified in the timezone |
75 | * it was originally created, not necessarly in your current local timezone. |
76 | */ |
77 | class KPLATOKERNEL_EXPORT Project : public Node |
78 | { |
79 | Q_OBJECT |
80 | public: |
81 | explicit Project( Node *parent = 0 ); |
82 | explicit Project( ConfigBase &config, Node *parent = 0 ); |
83 | ~Project(); |
84 | |
85 | /// Reference this project. |
86 | void ref() { ++m_refCount; } |
87 | /// De-reference this project. Deletes project of ref count <= 0 |
88 | void deref(); |
89 | |
90 | /// Returns the node type. Can be Type_Project or Type_Subproject. |
91 | virtual int type() const; |
92 | |
93 | /** |
94 | * Calculate the schedules managed by the schedule manager |
95 | * |
96 | * @param sm Schedule manager |
97 | */ |
98 | void calculate( ScheduleManager &sm ); |
99 | |
100 | /** |
101 | * Re-calculate the schedules managed by the schedule manager |
102 | * |
103 | * @param sm Schedule manager |
104 | * @param dt The datetime from when the schedule shall be re-calculated |
105 | */ |
106 | void calculate( ScheduleManager &sm, const DateTime &dt ); |
107 | |
108 | virtual DateTime startTime( long id = -1 ) const; |
109 | virtual DateTime endTime( long id = -1 ) const; |
110 | |
111 | /// Returns the calculated duration for schedule @p id |
112 | Duration duration( long id = -1 ) const; |
113 | using Node::duration; |
114 | /** |
115 | * Instead of using the expected duration, generate a random value using |
116 | * the Distribution of each Task. This can be used for Monte-Carlo |
117 | * estimation of Project duration. |
118 | */ |
119 | Duration *getRandomDuration(); |
120 | |
121 | virtual bool load( KoXmlElement &element, XMLLoaderObject &status ); |
122 | virtual void save( QDomElement &element ) const; |
123 | |
124 | using Node::saveWorkPackageXML; |
125 | /// Save a workpackage document containing @node with schedule identity @p id |
126 | void saveWorkPackageXML( QDomElement &element, const Node *node, long id ) const; |
127 | |
128 | /** |
129 | * Add the node @p task to the project, after node @p position |
130 | * If @p postition is zero or the project node, it will be added to this project. |
131 | */ |
132 | bool addTask( Node* task, Node* position ); |
133 | /** |
134 | * Add the node @p task to the @p parent |
135 | */ |
136 | bool addSubTask( Node* task, Node* parent ); |
137 | /** |
138 | * Add the node @p task to @p parent, in position @p index |
139 | * If @p parent is zero, it will be added to this project. |
140 | */ |
141 | bool addSubTask( Node* task, int index, Node* parent, bool emitSignal = true ); |
142 | /** |
143 | * Remove the @p node. |
144 | * The node is not deleted. |
145 | */ |
146 | void takeTask( Node *node, bool emitSignal = true ); |
147 | bool canMoveTask( Node* node, Node *newParent ); |
148 | bool moveTask( Node* node, Node *newParent, int newPos ); |
149 | bool canIndentTask( Node* node ); |
150 | bool indentTask( Node* node, int index = -1 ); |
151 | bool canUnindentTask( Node* node ); |
152 | bool unindentTask( Node* node ); |
153 | bool canMoveTaskUp( Node* node ); |
154 | bool moveTaskUp( Node* node ); |
155 | bool canMoveTaskDown( Node* node ); |
156 | bool moveTaskDown( Node* node ); |
157 | /** |
158 | * Create a task with a unique id. |
159 | * The task is not added to the project. Do this with addSubTask(). |
160 | */ |
161 | Task *createTask(); |
162 | /** |
163 | * Create a copy of @p def with a unique id. |
164 | * The task is not added to the project. Do this with addSubTask(). |
165 | */ |
166 | Task *createTask( const Task &def ); |
167 | |
168 | int resourceGroupCount() const { return m_resourceGroups.count(); } |
169 | QList<ResourceGroup*> &resourceGroups(); |
170 | /// Adds the resource group to the project. |
171 | virtual void addResourceGroup( ResourceGroup *resource, int index = -1 ); |
172 | /** |
173 | * Removes the resource group @p resource from the project. |
174 | * The resource group is not deleted. |
175 | */ |
176 | ResourceGroup *takeResourceGroup( ResourceGroup *resource ); |
177 | int indexOf( ResourceGroup *resource ) const { return m_resourceGroups.indexOf( resource ); } |
178 | ResourceGroup *resourceGroupAt( int pos ) const { return m_resourceGroups.value( pos ); } |
179 | int numResourceGroups() const { return m_resourceGroups.count(); } |
180 | |
181 | /// Returns the resourcegroup with identity id. |
182 | ResourceGroup *group( const QString& id ); |
183 | /// Returns the resource group with the matching name, 0 if no match is found. |
184 | ResourceGroup *groupByName( const QString& name ) const; |
185 | |
186 | /** |
187 | * Adds the resource to the project and resource group. |
188 | * Always use this to add resources. |
189 | */ |
190 | void addResource( ResourceGroup *group, Resource *resource, int index = -1 ); |
191 | /** |
192 | * Removes the resource from the project and resource group. |
193 | * The resource is not deleted. |
194 | * Always use this to remove resources. |
195 | */ |
196 | Resource *takeResource( ResourceGroup *group, Resource *resource ); |
197 | /// Move @p resource to the new @p group. Requests are removed. |
198 | void moveResource( ResourceGroup *group, Resource *resource ); |
199 | /// Returns the resource with identity id. |
200 | Resource *resource( const QString& id ); |
201 | /// Returns the resource with matching name, 0 if no match is found. |
202 | Resource *resourceByName( const QString& name ) const; |
203 | QStringList resourceNameList() const; |
204 | /// Returns a list of all resources |
205 | QList<Resource*> resourceList() const { return resourceIdDict.values(); } |
206 | |
207 | virtual EffortCostMap plannedEffortCostPrDay( const QDate &start, const QDate &end, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All ) const; |
208 | virtual EffortCostMap plannedEffortCostPrDay(const Resource *resource, const QDate &start, const QDate &end, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All ) const; |
209 | |
210 | using Node::plannedEffort; |
211 | /// Returns the total planned effort for this project (or subproject) |
212 | virtual Duration plannedEffort( long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All ) const; |
213 | /// Returns the total planned effort for this project (or subproject) on date |
214 | virtual Duration plannedEffort( const QDate &date, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All ) const; |
215 | using Node::plannedEffortTo; |
216 | /// Returns the planned effort up to and including date |
217 | virtual Duration plannedEffortTo( const QDate &date, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All ) const; |
218 | |
219 | /// Returns the actual effort up to and including @p date |
220 | virtual Duration actualEffortTo( const QDate &date ) const; |
221 | /** |
222 | * Planned cost up to and including date |
223 | * @param date The cost is calculated from the start of the project upto including date. |
224 | * @param id Identity of the schedule to be used. |
225 | */ |
226 | virtual double plannedCostTo( const QDate &date, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All ) const; |
227 | |
228 | /** |
229 | * Actual cost up to and including @p date |
230 | * @param date The cost is calculated from the start of the project upto including date. |
231 | */ |
232 | virtual EffortCost actualCostTo( long int id, const QDate &date ) const; |
233 | |
234 | virtual EffortCostMap actualEffortCostPrDay( const QDate &start, const QDate &end, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All ) const; |
235 | |
236 | virtual EffortCostMap actualEffortCostPrDay( const Resource *resource, const QDate &start, const QDate &end, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All ) const; |
237 | |
238 | double effortPerformanceIndex( const QDate &date, long id ) const; |
239 | |
240 | double schedulePerformanceIndex( const QDate &date, long id ) const; |
241 | |
242 | /// Returns the effort planned to be used to reach the actual percent finished |
243 | virtual Duration budgetedWorkPerformed( const QDate &date, long id = CURRENTSCHEDULE ) const; |
244 | /// Returns the cost planned to be used to reach the actual percent finished |
245 | virtual double budgetedCostPerformed( const QDate &date, long id = CURRENTSCHEDULE ) const; |
246 | |
247 | /// Budgeted Cost of Work Scheduled ( up to @p date ) |
248 | virtual double bcws( const QDate &date, long id = BASELINESCHEDULE ) const; |
249 | /// Budgeted Cost of Work Performed |
250 | virtual double bcwp( long id = BASELINESCHEDULE ) const; |
251 | /// Budgeted Cost of Work Performed ( up to @p date ) |
252 | virtual double bcwp( const QDate &date, long id = BASELINESCHEDULE ) const; |
253 | |
254 | Calendar *defaultCalendar() const { return m_defaultCalendar; } |
255 | void setDefaultCalendar( Calendar *cal ); |
256 | const QList<Calendar*> &calendars() const; |
257 | void addCalendar( Calendar *calendar, Calendar *parent = 0, int index = -1 ); |
258 | void takeCalendar( Calendar *calendar ); |
259 | int indexOf( const Calendar *calendar ) const; |
260 | /// Returns the calendar with identity id. |
261 | Calendar *calendar( const QString& id ) const; |
262 | /// Returns a list of all calendars |
263 | QStringList calendarNames() const; |
264 | /// Find calendar by name |
265 | Calendar *calendarByName( const QString &name ) const; |
266 | void changed( Calendar *cal ); |
267 | QList<Calendar*> allCalendars() const; |
268 | /// Return number of calendars |
269 | int calendarCount() const { return m_calendars.count(); } |
270 | /// Return the calendar at @p index, 0 if index out of bounds |
271 | Calendar *calendarAt( int index ) const { return m_calendars.value( index ); } |
272 | /** |
273 | * Defines the length of days, weeks, months and years |
274 | * and the standard working week. |
275 | * Used for estimation and calculation of effort, |
276 | * and presentation in gantt chart. |
277 | */ |
278 | StandardWorktime *standardWorktime() { return m_standardWorktime; } |
279 | void setStandardWorktime( StandardWorktime * worktime ); |
280 | void changed( StandardWorktime* ); |
281 | |
282 | /// Check if a link exists between node @p par and @p child. |
283 | bool linkExists( const Node *par, const Node *child ) const; |
284 | /// Check if node @p par can be linked to node @p child. |
285 | bool legalToLink( const Node *par, const Node *child ) const; |
286 | using Node::legalToLink; |
287 | |
288 | virtual const QHash<QString, Node*> &nodeDict() { return nodeIdDict; } |
289 | /// Return a list of all nodes in the project (exluding myself) |
290 | QList<Node*> allNodes() const; |
291 | /// Return the number of all nodes in the project (exluding myself) |
292 | int nodeCount() const { return nodeIdDict.count() - 1; } |
293 | |
294 | /// Return a list of all tasks and milestones int the wbs order |
295 | QList<Task*> allTasks( const Node *parent = 0 ) const; |
296 | |
297 | using Node::findNode; |
298 | /// Find the node with identity id |
299 | virtual Node *findNode( const QString &id ) const; |
300 | |
301 | using Node::removeId; |
302 | /// Remove the node with identity id from the registers |
303 | virtual bool removeId( const QString &id ); |
304 | |
305 | /// Reserve @p id for the @p node |
306 | virtual void reserveId( const QString &id, Node *node ); |
307 | /// Register @p node. The nodes id must be unique and non-empty. |
308 | bool registerNodeId( Node *node ); |
309 | /// Create a unique id. |
310 | QString uniqueNodeId( int seed = 1 ) const; |
311 | /// Check if node @p id is used |
312 | bool nodeIdentExists( const QString &id ) const; |
313 | |
314 | /// Create a unique id. |
315 | QString uniqueNodeId( const QList<QString> &existingIds, int seed = 1 ); |
316 | |
317 | ResourceGroup *findResourceGroup( const QString &id ) const |
318 | { |
319 | if ( resourceGroupIdDict.contains( id ) ) |
320 | return resourceGroupIdDict[ id ]; |
321 | return 0; |
322 | } |
323 | /// Remove the resourcegroup with identity id from the register |
324 | bool removeResourceGroupId( const QString &id ) |
325 | { |
326 | if ( resourceGroupIdDict.contains( id ) ) |
327 | return resourceGroupIdDict.remove( id ); |
328 | return false; |
329 | } |
330 | /// Insert the resourcegroup with identity id |
331 | void insertResourceGroupId( const QString &id, ResourceGroup* group ) |
332 | { |
333 | resourceGroupIdDict.insert( id, group ); |
334 | } |
335 | /// Generate, set and insert unique id |
336 | bool setResourceGroupId( ResourceGroup *group); |
337 | /// returns a unique resourcegroup id |
338 | QString uniqueResourceGroupId() const; |
339 | |
340 | /// Return a list of resources that will be allocated to new tasks |
341 | QList<Resource*> autoAllocateResources() const; |
342 | |
343 | Resource *findResource( const QString &id ) const |
344 | { |
345 | if ( resourceIdDict.contains( id ) ) |
346 | return resourceIdDict[ id ]; |
347 | return 0; |
348 | } |
349 | /// Remove the resource with identity id from the register |
350 | bool removeResourceId( const QString &id ); |
351 | /// Insert the resource with identity id |
352 | void insertResourceId( const QString &id, Resource *resource ); |
353 | /// Generate, set and insert unique id |
354 | bool setResourceId( Resource *resource ); |
355 | /// returns a unique resource id |
356 | QString uniqueResourceId() const; |
357 | |
358 | /// Find the calendar with identity id |
359 | virtual Calendar *findCalendar( const QString &id ) const |
360 | { |
361 | if ( id.isEmpty() || !calendarIdDict.contains( id ) ) |
362 | return 0; |
363 | return calendarIdDict[ id ]; |
364 | } |
365 | /// Remove the calendar with identity id from the register |
366 | virtual bool removeCalendarId( const QString &id ); |
367 | /// Insert the calendar with identity id |
368 | virtual void insertCalendarId( const QString &id, Calendar *calendar ); |
369 | /// Set and insert a unique id for calendar |
370 | bool setCalendarId( Calendar *calendar ); |
371 | /// returns a unique calendar id |
372 | QString uniqueCalendarId() const; |
373 | /// Return reference to WBS Definition |
374 | WBSDefinition &wbsDefinition(); |
375 | /// Set WBS Definition to @p def |
376 | void setWbsDefinition( const WBSDefinition &def ); |
377 | /// Generate WBS Code |
378 | virtual QString generateWBSCode( QList<int> &indexes ) const; |
379 | |
380 | Accounts &accounts() { return m_accounts; } |
381 | const Accounts &accounts() const { return m_accounts; } |
382 | |
383 | /** |
384 | * Set current schedule to the schedule with identity @p id, for me and my children |
385 | * Note that this is used (and may be changed) when calculating schedules |
386 | */ |
387 | virtual void setCurrentSchedule( long id ); |
388 | /// Create new schedule with unique name and id of type Expected. |
389 | MainSchedule *createSchedule(); |
390 | /// Create new schedule with unique id. |
391 | MainSchedule *createSchedule( const QString& name, Schedule::Type type ); |
392 | /// Add the schedule to the project. A fresh id will be generated for the schedule. |
393 | void addMainSchedule( MainSchedule *schedule ); |
394 | /// Set parent schedule for my children |
395 | virtual void setParentSchedule( Schedule *sch ); |
396 | |
397 | /// Find the schedule manager that manages the Schedule with @p id |
398 | ScheduleManager *scheduleManager( long id ) const; |
399 | /// Find the schedule manager with @p id |
400 | ScheduleManager *scheduleManager( const QString &id ) const; |
401 | /// Create a unique schedule name (This may later be changed by the user) |
402 | QString uniqueScheduleName() const; |
403 | /// Create a unique schedule manager identity |
404 | QString uniqueScheduleManagerId() const; |
405 | ScheduleManager *createScheduleManager(); |
406 | ScheduleManager *createScheduleManager( const QString &name ); |
407 | /// Returns a list of all top level schedule managers |
408 | QList<ScheduleManager*> scheduleManagers() const { return m_managers; } |
409 | int numScheduleManagers() const { return m_managers.count(); } |
410 | int indexOf( const ScheduleManager *sm ) const { return m_managers.indexOf( const_cast<ScheduleManager*>(sm) ); } |
411 | bool isScheduleManager( void* ptr ) const; |
412 | void addScheduleManager( ScheduleManager *sm, ScheduleManager *parent = 0, int index = -1 ); |
413 | int takeScheduleManager( ScheduleManager *sm ); |
414 | void moveScheduleManager( ScheduleManager *sm, ScheduleManager *newparent = 0, int newindex = -1 ); |
415 | ScheduleManager *findScheduleManagerByName( const QString &name ) const; |
416 | /// Returns a list of all schedule managers |
417 | QList<ScheduleManager*> allScheduleManagers() const; |
418 | /// Return true if schedule with identity @p id is baselined |
419 | bool isBaselined( long id = ANYSCHEDULED ) const; |
420 | |
421 | void changed( ResourceGroup *group ); |
422 | void changed( Resource *resource ); |
423 | |
424 | void changed( ScheduleManager *sm ); |
425 | void changed( MainSchedule *sch ); |
426 | void sendScheduleAdded( const MainSchedule *sch ); |
427 | void sendScheduleToBeAdded( const ScheduleManager *manager, int row ); |
428 | void sendScheduleRemoved( const MainSchedule *sch ); |
429 | void sendScheduleToBeRemoved( const MainSchedule *sch ); |
430 | |
431 | /// Return the time spec used in this project |
432 | const KDateTime::Spec &timeSpec() const { return m_spec; } |
433 | /// Return the time zone used in this project |
434 | KTimeZone timeZone() const { return m_spec.timeZone(); } |
435 | /// Set the time zone to be used in this project |
436 | void setTimeZone( const KTimeZone &tz ) { m_spec = KDateTime::Spec( tz ); } |
437 | |
438 | /** |
439 | * Add a relation between the nodes specified in the relation rel. |
440 | * Emits signals relationToBeAdded() before the relation is added, |
441 | * and relationAdded() after it has been added. |
442 | * @param rel The relation to be added. |
443 | * @param check If true, the relation is checked for validity |
444 | * @return true if successful. |
445 | */ |
446 | bool addRelation( Relation *rel, bool check=true ); |
447 | /** |
448 | * Removes the relation @p rel without deleting it. |
449 | * Emits signals relationToBeRemoved() before the relation is removed, |
450 | * and relationRemoved() after it has been removed. |
451 | */ |
452 | void takeRelation( Relation *rel ); |
453 | |
454 | /** |
455 | * Modify the @p type of the @p relation. |
456 | */ |
457 | void setRelationType( Relation *relation, Relation::Type type ); |
458 | /** |
459 | * Modify the @p lag of the @p relation. |
460 | */ |
461 | void setRelationLag( Relation *relation, const Duration &lag ); |
462 | |
463 | void calcCriticalPathList( MainSchedule *cs ); |
464 | void calcCriticalPathList( MainSchedule *cs, Node *node ); |
465 | /** |
466 | * Returns the list of critical paths for schedule @p id |
467 | */ |
468 | const QList< QList<Node*> > *criticalPathList( long id = CURRENTSCHEDULE ); |
469 | QList<Node*> criticalPath( long id = CURRENTSCHEDULE, int index = 0 ); |
470 | |
471 | /// Returns a flat list af all nodes |
472 | QList<Node*> flatNodeList( Node *parent = 0 ); |
473 | |
474 | void generateUniqueNodeIds(); |
475 | void generateUniqueIds(); |
476 | |
477 | const ConfigBase &config() const { return m_config ? *m_config : emptyConfig; } |
478 | /// Set configuration data |
479 | void setConfig( ConfigBase *config ) { m_config = config; } |
480 | |
481 | const Task &taskDefaults() const { return config().taskDefaults(); } |
482 | |
483 | /// Return locale. (Used for currency, everything else is from KGlobal::locale) |
484 | KLocale *locale() { return const_cast<ConfigBase&>(config()).locale(); } |
485 | /// Return locale. (Used for currency, everything else is from KGlobal::locale) |
486 | const KLocale *locale() const { return config().locale(); } |
487 | /// Signal that locale data has changed |
488 | void emitLocaleChanged(); |
489 | |
490 | void setSchedulerPlugins( const QMap<QString, SchedulerPlugin*> &plugins ); |
491 | const QMap<QString, SchedulerPlugin*> &schedulerPlugins() const { return m_schedulerPlugins; } |
492 | |
493 | void initiateCalculation( MainSchedule &sch ); |
494 | void initiateCalculationLists( MainSchedule &sch ); |
495 | |
496 | void finishCalculation( ScheduleManager &sm ); |
497 | void adjustSummarytask(); |
498 | |
499 | /// Increments progress and emits signal sigProgress() |
500 | void incProgress(); |
501 | /// Emits signal maxProgress() |
502 | void emitMaxProgress( int value ); |
503 | |
504 | bool stopcalculation; |
505 | |
506 | /// return a <id, name> map of all external projects |
507 | QMap<QString, QString> externalProjects() const; |
508 | |
509 | void emitDocumentAdded( Node*, Document*, int index ); |
510 | void emitDocumentRemoved( Node*, Document*, int index ); |
511 | void emitDocumentChanged( Node*, Document*, int index ); |
512 | |
513 | public slots: |
514 | /// Sets m_progress to @p progress and emits signal sigProgress() |
515 | /// If @p sm is not 0, progress is also set for the schedule manager |
516 | void setProgress( int progress, ScheduleManager *sm = 0 ); |
517 | /// Sets m_maxprogress to @p max and emits signal maxProgress() |
518 | /// If @p sm is not 0, max progress is also set for the schedule manager |
519 | void setMaxProgress( int max, ScheduleManager *sm = 0 ); |
520 | |
521 | signals: |
522 | /// Emitted when anything in the project is changed (use with care) |
523 | void projectChanged(); |
524 | /// Emitted when the WBS code definition has changed. This may change all nodes. |
525 | void wbsDefinitionChanged(); |
526 | /// Emitted when a schedule has been calculated |
527 | void projectCalculated( ScheduleManager *sm ); |
528 | /// Emitted when the pointer to the current schedule has been changed |
529 | void currentScheduleChanged(); |
530 | /// Use to show progress during calculation |
531 | void sigProgress( int ); |
532 | /// Use to set the maximum progress (minimum always 0) |
533 | void maxProgress( int ); |
534 | /// Emitted when calculation starts |
535 | void sigCalculationStarted( Project *project, ScheduleManager *sm ); |
536 | /// Emitted when calculation is finished |
537 | void sigCalculationFinished( Project *project, ScheduleManager *sm ); |
538 | /// This signal is emitted when one of the nodes members is changed. |
539 | void nodeChanged( Node* ); |
540 | /// This signal is emitted when the node is to be added to the project. |
541 | void nodeToBeAdded( Node*, int ); |
542 | /// This signal is emitted when the node has been added to the project. |
543 | void nodeAdded( Node* ); |
544 | /// This signal is emitted when the node is to be removed from the project. |
545 | void nodeToBeRemoved( Node* ); |
546 | /// This signal is emitted when the node has been removed from the project. |
547 | void nodeRemoved( Node* ); |
548 | /// This signal is emitted when the node is to be moved up, moved down, indented or unindented. |
549 | void nodeToBeMoved( Node* node, int pos, Node* newParent, int newPos ); |
550 | /// This signal is emitted when the node has been moved up, moved down, indented or unindented. |
551 | void nodeMoved( Node* ); |
552 | |
553 | /// This signal is emitted when a document is added |
554 | void documentAdded( Node*, Document*, int index ); |
555 | /// This signal is emitted when a document is removed |
556 | void documentRemoved( Node*, Document*, int index ); |
557 | /// This signal is emitted when a document is changed |
558 | void documentChanged( Node*, Document*, int index ); |
559 | |
560 | void resourceGroupChanged( ResourceGroup *group ); |
561 | void resourceGroupAdded( const ResourceGroup *group ); |
562 | void resourceGroupToBeAdded( const ResourceGroup *group, int row ); |
563 | void resourceGroupRemoved( const ResourceGroup *group ); |
564 | void resourceGroupToBeRemoved( const ResourceGroup *group ); |
565 | |
566 | void resourceChanged( Resource *resource ); |
567 | void resourceAdded( const Resource *resource ); |
568 | void resourceToBeAdded( const ResourceGroup *group, int row ); |
569 | void resourceRemoved( const Resource *resource ); |
570 | void resourceToBeRemoved( const Resource *resource ); |
571 | |
572 | void scheduleManagerChanged( ScheduleManager *sch ); |
573 | void scheduleManagerAdded( const ScheduleManager *sch ); |
574 | void scheduleManagerToBeAdded( const ScheduleManager *sch, int row ); |
575 | void scheduleManagerRemoved( const ScheduleManager *sch ); |
576 | void scheduleManagerToBeRemoved( const ScheduleManager *sch ); |
577 | void scheduleManagerMoved( const ScheduleManager *sch, int row ); |
578 | void scheduleManagerToBeMoved( const ScheduleManager *sch ); |
579 | |
580 | void scheduleChanged( MainSchedule *sch ); |
581 | void scheduleToBeAdded( const ScheduleManager *manager, int row ); |
582 | void scheduleAdded( const MainSchedule *sch ); |
583 | void scheduleToBeRemoved( const MainSchedule *sch ); |
584 | void scheduleRemoved( const MainSchedule *sch ); |
585 | |
586 | // void currentViewScheduleIdChanged( long id ); |
587 | |
588 | void calendarChanged( Calendar *cal ); |
589 | void calendarToBeAdded( const Calendar *cal, int row ); |
590 | void calendarAdded( const Calendar *cal ); |
591 | void calendarToBeRemoved( const Calendar *cal ); |
592 | void calendarRemoved( const Calendar *cal ); |
593 | |
594 | /** |
595 | * Emitted when the default calendar pointer has changed |
596 | * @parem cal The new default calendar. May be 0. |
597 | */ |
598 | void defaultCalendarChanged( Calendar *cal ); |
599 | /** |
600 | * Emitted when the standard worktime has been changed. |
601 | */ |
602 | void standardWorktimeChanged( StandardWorktime* ); |
603 | |
604 | /// Emitted when the relation @p rel is about to be added. |
605 | void relationToBeAdded( Relation *rel, int parentIndex, int childIndex ); |
606 | /// Emitted when the relation @p rel has been added. |
607 | void relationAdded( Relation *rel ); |
608 | /// Emitted when the relation @p rel is about to be removed. |
609 | void relationToBeRemoved( Relation *rel ); |
610 | /// Emitted when the relation @p rel has been removed. |
611 | void relationRemoved( Relation *rel ); |
612 | /// Emitted when the relation @p rel shall be modified. |
613 | void relationToBeModified( Relation *rel ); |
614 | /// Emitted when the relation @p rel has been modified. |
615 | void relationModified( Relation *rel ); |
616 | |
617 | /// Emitted when locale data has changed |
618 | void localeChanged(); |
619 | |
620 | protected: |
621 | /// Calculate the schedule. |
622 | void calculate( Schedule *scedule ); |
623 | /// Calculate current schedule |
624 | void calculate(); |
625 | |
626 | /// Re-calculate the schedule from @p dt |
627 | void calculate( Schedule *scedule, const DateTime &dt ); |
628 | /// Calculate current schedule from @p dt (Always calculates forward) |
629 | void calculate( const DateTime &dt ); |
630 | |
631 | /// Calculate critical path |
632 | virtual bool calcCriticalPath( bool fromEnd ); |
633 | |
634 | /// Prepare task lists for scheduling |
635 | void tasksForward(); |
636 | /// Prepare task lists for scheduling |
637 | void tasksBackward(); |
638 | |
639 | protected: |
640 | friend class KPlatoXmlLoaderBase; |
641 | using Node::changed; |
642 | virtual void changed(Node *node, int property = -1); |
643 | |
644 | Accounts m_accounts; |
645 | QList<ResourceGroup*> m_resourceGroups; |
646 | |
647 | QList<Calendar*> m_calendars; |
648 | Calendar * m_defaultCalendar; |
649 | |
650 | StandardWorktime *m_standardWorktime; |
651 | |
652 | DateTime calculateForward( int use ); |
653 | DateTime calculateBackward( int use ); |
654 | DateTime scheduleForward( const DateTime &earliest, int use ); |
655 | DateTime scheduleBackward( const DateTime &latest, int use ); |
656 | DateTime checkStartConstraints( const DateTime &dt ) const; |
657 | DateTime checkEndConstraints( const DateTime &dt ) const; |
658 | |
659 | bool legalParents( const Node *par, const Node *child ) const; |
660 | bool legalChildren( const Node *par, const Node *child ) const; |
661 | |
662 | #ifndef PLAN_NLOGDEBUG |
663 | private: |
664 | static bool checkParent( Node *n, QList<Node*> list, QList<Relation*> &checked ); |
665 | static bool checkChildren( Node *n, QList<Node*> list, QList<Relation*> &checked ); |
666 | #endif |
667 | private: |
668 | void init(); |
669 | |
670 | QHash<QString, ResourceGroup*> resourceGroupIdDict; |
671 | QHash<QString, Resource*> resourceIdDict; |
672 | QHash<QString, Node*> nodeIdDict; |
673 | QMap<QString, Node*> nodeIdReserved; |
674 | QMap<QString, Calendar*> calendarIdDict; |
675 | QMap<QString, ScheduleManager*> m_managerIdMap; |
676 | |
677 | QList<ScheduleManager*> m_managers; |
678 | KDateTime::Spec m_spec; |
679 | |
680 | WBSDefinition m_wbsDefinition; |
681 | |
682 | ConfigBase emptyConfig; |
683 | QPointer<ConfigBase> m_config; // this one is not owned by me, don't delete |
684 | |
685 | int m_progress; |
686 | |
687 | QMap<QString, SchedulerPlugin*> m_schedulerPlugins; |
688 | |
689 | int m_refCount; // make it possible to use the project by different threads |
690 | |
691 | QList<Task*> m_hardConstraints; |
692 | QList<Task*> m_softConstraints; |
693 | QList<Task*> m_terminalNodes; |
694 | |
695 | }; |
696 | |
697 | |
698 | } //KPlato namespace |
699 | |
700 | #endif |
701 | |