1 | /* This file is part of the KDE project |
2 | Copyright (C) 2003 - 2007 Dag Andersen <danders@get2net.dk> |
3 | Copyright (C) 2011 Dag Andersen <danders@get2net.dk> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | * Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #ifndef KPTCALENDAR_H |
22 | #define KPTCALENDAR_H |
23 | |
24 | #include <kptdatetime.h> |
25 | #include "kptduration.h" |
26 | #include "kplatokernel_export.h" |
27 | |
28 | #include <QPair> |
29 | #include <QList> |
30 | #include <QMap> |
31 | #include <QStringList> |
32 | |
33 | #include <kglobal.h> |
34 | #include <klocale.h> |
35 | #include <ktimezone.h> |
36 | #include <kdebug.h> |
37 | |
38 | #include <KoXmlReader.h> |
39 | |
40 | class QDomElement; |
41 | class QTime; |
42 | class QDate; |
43 | class QString; |
44 | |
45 | /// The main namespace. |
46 | namespace KPlato |
47 | { |
48 | |
49 | class Calendar; |
50 | class Project; |
51 | class IntMap; |
52 | class DateTime; |
53 | class Project; |
54 | class Schedule; |
55 | class XMLLoaderObject; |
56 | class AppointmentIntervalList; |
57 | |
58 | class KPLATOKERNEL_EXPORT DateTimeInterval : public QPair<DateTime, DateTime> |
59 | { |
60 | public: |
61 | DateTimeInterval() |
62 | : QPair<DateTime, DateTime>() |
63 | {} |
64 | DateTimeInterval( const DateTime &t1, const DateTime &t2 ) |
65 | : QPair<DateTime, DateTime>( t1, t2 ) |
66 | {} |
67 | DateTimeInterval &operator=( const DateTimeInterval &other ) { |
68 | first = other.first; second = other.second; |
69 | return *this; |
70 | } |
71 | bool isValid() const { return first.isValid() && second.isValid(); } |
72 | void limitTo( const DateTime &start, const DateTime &end ) { |
73 | if ( ! first.isValid() || ( start.isValid() && start > first ) ) { |
74 | first = start; |
75 | } |
76 | if ( ! second.isValid() || ( end.isValid() && end < second ) ) { |
77 | second = end; |
78 | } |
79 | if ( isValid() && first > second ) { |
80 | first = second = DateTime(); |
81 | } |
82 | } |
83 | void limitTo( const DateTimeInterval &interval ) { |
84 | limitTo( interval.first, interval.second ); |
85 | } |
86 | |
87 | DateTimeInterval limitedTo( const DateTime &start, const DateTime &end ) const { |
88 | DateTimeInterval i = *this; |
89 | i.limitTo( start, end ); |
90 | return i; |
91 | } |
92 | DateTimeInterval limitedTo( const DateTimeInterval &interval ) const { |
93 | return limitedTo( interval.first, interval.second ); |
94 | } |
95 | QString toString() const { |
96 | return QString( "%1 to %2" ) |
97 | .arg( first.isValid()?first.toString():"''" ) |
98 | .arg( second.isValid()?second.toString():"''" ); |
99 | } |
100 | }; |
101 | |
102 | /// TimeInterval is defined as a start time and a length. |
103 | /// The end time (start + length) must not exceed midnight |
104 | class KPLATOKERNEL_EXPORT TimeInterval : public QPair<QTime, int> |
105 | { |
106 | public: |
107 | TimeInterval() |
108 | : QPair<QTime, int>( QTime(), -1 ) |
109 | {} |
110 | explicit TimeInterval( const QPair<QTime, int> &value ) |
111 | : QPair<QTime, int>( value ) |
112 | { |
113 | init(); |
114 | } |
115 | TimeInterval( const QTime &start, int length ) |
116 | : QPair<QTime, int>( start, length ) |
117 | { |
118 | init(); |
119 | } |
120 | TimeInterval( const TimeInterval &value ) |
121 | : QPair<QTime, int>( value.first, value.second ) |
122 | { |
123 | init(); |
124 | } |
125 | /// Return the intervals start time |
126 | QTime startTime() const { return first; } |
127 | /// Return the intervals calculated end time. Note: It may return QTime(0,0,0) |
128 | QTime endTime() const { return first.addMSecs( second ); } |
129 | double hours() const { return (double)(second) / ( 1000. * 60. * 60. ); } |
130 | /// Returns true if this interval ends at midnight, and thus endTime() returns QTime(0,0,0) |
131 | bool endsMidnight() const { return endTime() == QTime( 0, 0, 0 ); } |
132 | |
133 | bool isValid() const { return first.isValid() && second > 0; } |
134 | bool isNull() const { return first.isNull() || second < 0; } |
135 | |
136 | TimeInterval &operator=( const TimeInterval &ti ) { |
137 | first = ti.first; |
138 | second = ti.second; |
139 | return *this; |
140 | } |
141 | /// Returns true if the intervals overlap in any way |
142 | bool intersects( const TimeInterval &ti ) const { |
143 | if ( ! isValid() || ! ti.isValid() ) { |
144 | return false; |
145 | } |
146 | if ( endsMidnight() && ti.endsMidnight() ) { |
147 | return true; |
148 | } |
149 | if ( endsMidnight() ) { |
150 | return first < ti.endTime(); |
151 | } |
152 | if ( ti.endsMidnight() ) { |
153 | return ti.first < endTime(); |
154 | } |
155 | return ( first < ti.endTime() && endTime() > ti.first ) || ( ti.first < endTime() && ti.endTime() > first ); |
156 | } |
157 | protected: |
158 | void init() |
159 | { |
160 | int s = QTime( 0, 0, 0 ).msecsTo( first ); |
161 | if ( ( s + second ) > 86400000 ) { |
162 | second = 86400000 - s; |
163 | kError()<<"Overflow, limiting length to" <<second; |
164 | } |
165 | } |
166 | }; |
167 | |
168 | |
169 | class KPLATOKERNEL_EXPORT CalendarDay { |
170 | |
171 | public: |
172 | enum State { Undefined = 0, |
173 | None=Undefined, // depreciated |
174 | NonWorking=1, Working=2 }; |
175 | |
176 | CalendarDay(); |
177 | explicit CalendarDay(int state); |
178 | explicit CalendarDay(const QDate& date, int state=Undefined); |
179 | explicit CalendarDay(CalendarDay *day); |
180 | ~CalendarDay(); |
181 | |
182 | bool load( KoXmlElement &element, XMLLoaderObject &status ); |
183 | void save(QDomElement &element) const; |
184 | |
185 | QList<TimeInterval*> timeIntervals() const { return m_timeIntervals; } |
186 | void addInterval( const QTime &t1, int length ) { addInterval( new TimeInterval( t1, length ) ); } |
187 | void addInterval(TimeInterval *interval); |
188 | void addInterval(TimeInterval interval) { addInterval(new TimeInterval(interval)); } |
189 | void clearIntervals() { m_timeIntervals.clear(); } |
190 | void setIntervals(QList<TimeInterval*> intervals) { |
191 | m_timeIntervals.clear(); |
192 | m_timeIntervals = intervals; |
193 | } |
194 | void removeInterval( TimeInterval *interval ); |
195 | TimeInterval *intervalAt( int index ) const; |
196 | int indexOf( const TimeInterval *ti ) const; |
197 | int numIntervals() const; |
198 | |
199 | DateTime start() const; |
200 | DateTime end() const; |
201 | |
202 | QDate date() const { return m_date; } |
203 | void setDate(const QDate& date) { m_date = date; } |
204 | int state() const { return m_state; } |
205 | void setState(int state) { m_state = state; } |
206 | |
207 | bool operator==(const CalendarDay *day) const; |
208 | bool operator==(const CalendarDay &day) const; |
209 | bool operator!=(const CalendarDay *day) const; |
210 | bool operator!=(const CalendarDay &day) const; |
211 | |
212 | Duration workDuration() const; |
213 | /** |
214 | * Returns the amount of 'worktime' that can be done on |
215 | * this day between the times start and end. |
216 | */ |
217 | Duration effort(const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch=0); |
218 | /** |
219 | * Returns the amount of 'worktime' that can be done on |
220 | * this day between the times start and end. |
221 | */ |
222 | Duration effort(const QDate &date, const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch=0); |
223 | |
224 | /** |
225 | * Returns the actual 'work interval' for the interval start to end. |
226 | * If no 'work interval' exists, returns the interval start, end. |
227 | * Use @ref hasInterval() to check if a 'work interval' exists. |
228 | */ |
229 | TimeInterval interval(const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch=0) const; |
230 | |
231 | /** |
232 | * Returns the actual 'work interval' for the interval start to end. |
233 | * If no 'work interval' exists, returns the interval start, end. |
234 | * Use @ref hasInterval() to check if a 'work interval' exists. |
235 | */ |
236 | TimeInterval interval(const QDate &date, const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch=0) const; |
237 | |
238 | bool hasInterval() const; |
239 | |
240 | /** |
241 | * Returns true if at least a part of a 'work interval' exists |
242 | * for the interval start to end. |
243 | */ |
244 | bool hasInterval(const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch=0) const; |
245 | |
246 | /** |
247 | * Returns true if at least a part of a 'work interval' exists |
248 | * for the interval @p start to @p start + @p length. |
249 | * Assumes this day is date. (Used by weekday hasInterval().) |
250 | * If @p sch is not 0, the schedule is checked for availability. |
251 | */ |
252 | bool hasInterval(const QDate &date, const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch=0) const; |
253 | |
254 | Duration duration() const; |
255 | |
256 | const CalendarDay ©(const CalendarDay &day); |
257 | |
258 | static QString stateToString( int st, bool trans = false ) { |
259 | if ( st == None ) { |
260 | return trans ? i18n( "Undefined" ) : "Undefined" ; |
261 | } else if ( st == NonWorking ) { |
262 | return trans ? i18n( "Non-working" ) : "Non-working" ; |
263 | } else if ( st == Working ) { |
264 | return trans ? i18n( "Working" ) : "Working" ; |
265 | } |
266 | return QString(); |
267 | } |
268 | static QStringList stateList( bool trans = false ) { |
269 | QStringList lst; |
270 | return trans |
271 | ? lst << i18n( "Undefined" ) << i18n( "Non-working" ) << i18n( "Working" ) |
272 | : lst << "Undefined" << "Non-working" << "Working" ; |
273 | } |
274 | |
275 | private: |
276 | QDate m_date; //NOTE: inValid if used for weekdays |
277 | int m_state; |
278 | Calendar *m_calendar; |
279 | QList<TimeInterval*> m_timeIntervals; |
280 | |
281 | #ifndef NDEBUG |
282 | public: |
283 | void printDebug(const QString& indent=QString()); |
284 | #endif |
285 | }; |
286 | |
287 | class KPLATOKERNEL_EXPORT CalendarWeekdays { |
288 | |
289 | public: |
290 | CalendarWeekdays(); |
291 | explicit CalendarWeekdays( const CalendarWeekdays *weekdays ); |
292 | ~CalendarWeekdays(); |
293 | |
294 | bool load( KoXmlElement &element, XMLLoaderObject &status ); |
295 | void save(QDomElement &element) const; |
296 | |
297 | const QList<CalendarDay*> weekdays() const |
298 | { QList<CalendarDay*> lst = m_weekdays.values(); return lst; } |
299 | /** |
300 | * Returns the pointer to CalendarDay for day. |
301 | * @param day The weekday number, must be between 1 (monday) and 7 (sunday) |
302 | */ |
303 | CalendarDay *weekday(int day) const; |
304 | CalendarDay *weekday(const QDate &date) const { return weekday(date.dayOfWeek()); } |
305 | |
306 | static int dayOfWeek( const QString &name ); |
307 | |
308 | const QMap<int, CalendarDay*> &weekdayMap() const; |
309 | |
310 | IntMap stateMap() const; |
311 | |
312 | // void setWeekday(IntMap::iterator it, int state) { m_weekdays.at(it.key())->setState(state); } |
313 | |
314 | int state(const QDate &date) const; |
315 | int state(int weekday) const; |
316 | void setState(int weekday, int state); |
317 | |
318 | QList<TimeInterval*> intervals(int weekday) const; |
319 | void setIntervals(int weekday, QList<TimeInterval*>intervals); |
320 | void clearIntervals(int weekday); |
321 | |
322 | bool operator==(const CalendarWeekdays *weekdays) const; |
323 | bool operator!=(const CalendarWeekdays *weekdays) const; |
324 | |
325 | Duration effort(const QDate &date, const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch=0); |
326 | |
327 | /** |
328 | * Returns the actual 'work interval' on the weekday defined by date |
329 | * for the interval @p start to @p start + @p length. |
330 | * If no 'work interval' exists, returns the interval start, end. |
331 | * Use @ref hasInterval() to check if a 'work interval' exists. |
332 | * If @p sch is not 0, the schedule is checked for availability. |
333 | */ |
334 | TimeInterval interval(const QDate &date, const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch) const; |
335 | /** |
336 | * Returns true if at least a part of a 'work interval' exists |
337 | * on the weekday defined by date for the interval start to end. |
338 | */ |
339 | bool hasInterval(const QDate &date, const QTime &start, int length, const KDateTime::Spec &spec, Schedule *sch) const; |
340 | bool hasInterval() const; |
341 | |
342 | Duration duration() const; |
343 | Duration duration(int weekday) const; |
344 | |
345 | const CalendarWeekdays ©(const CalendarWeekdays &weekdays); |
346 | |
347 | int indexOf( const CalendarDay *day ) const; |
348 | |
349 | private: |
350 | Calendar *m_calendar; |
351 | QMap<int, CalendarDay*> m_weekdays; |
352 | |
353 | #ifndef NDEBUG |
354 | public: |
355 | void printDebug(const QString& indent=QString()); |
356 | #endif |
357 | }; |
358 | |
359 | /** |
360 | * Calendar defines the working and nonworking days and hours. |
361 | * A day can have the three states Undefined, NonWorking, or Working. |
362 | * A calendar can have a parent calendar that defines the days that are |
363 | * undefined in this calendar. |
364 | * If a calendar have no parent, an undefined day defaults to Nonworking. |
365 | * A Working day has one or more work intervals to define the work hours. |
366 | * |
367 | * The definition can consist of two parts: Weekdays and Day. |
368 | * Day has highest priority. |
369 | * |
370 | * A typical calendar hierarchy could include calendars on 4 levels: |
371 | * 1. Definition of normal weekdays and national holidays/vacation days. |
372 | * 2. Definition of the company's special workdays/-time and vacation days. |
373 | * 3. Definitions for groups of resources. |
374 | * 4. Definitions for individual resources. |
375 | * |
376 | * A calendar can define a timezone different from the projects. |
377 | * This enables planning with resources that does not recide in the same place. |
378 | * |
379 | */ |
380 | class KPLATOKERNEL_EXPORT Calendar : public QObject |
381 | { |
382 | Q_OBJECT |
383 | public: |
384 | Calendar(); |
385 | explicit Calendar(const QString& name, Calendar *parent=0); |
386 | //Calendar( const Calendar &c ); QObject doesn't allow a copy constructor |
387 | ~Calendar(); |
388 | |
389 | const Calendar &operator=(const Calendar &calendar ) { return copy( calendar ); } |
390 | |
391 | QString name() const { return m_name; } |
392 | void setName(const QString& name); |
393 | |
394 | Calendar *parentCal() const { return m_parent; } |
395 | /** |
396 | * Set parent calendar to @p parent. |
397 | * Removes myself from current parent and |
398 | * inserts myself as child to new parent. |
399 | */ |
400 | void setParentCal( Calendar *parent, int pos = -1 ); |
401 | |
402 | bool isChildOf( const Calendar *cal ) const; |
403 | |
404 | Project *project() const { return m_project; } |
405 | void setProject(Project *project); |
406 | |
407 | QString id() const { return m_id; } |
408 | void setId(const QString& id); |
409 | |
410 | const QList<Calendar*> &calendars() const { return m_calendars; } |
411 | void addCalendar( Calendar *calendar, int pos = -1 ); |
412 | void takeCalendar( Calendar *calendar ); |
413 | int indexOf( const Calendar *calendar ) const; |
414 | /// Return number of children |
415 | int childCount() const { return m_calendars.count(); } |
416 | /// Return child calendar at @p index, 0 if index out of bounds |
417 | Calendar *childAt( int index ) const { return m_calendars.value( index ); } |
418 | |
419 | bool load( KoXmlElement &element, XMLLoaderObject &status ); |
420 | void save(QDomElement &element) const; |
421 | |
422 | int state(const QDate &date) const; |
423 | void setState( CalendarDay *day, CalendarDay::State state ); |
424 | void addWorkInterval( CalendarDay *day, TimeInterval *ti ); |
425 | void takeWorkInterval( CalendarDay *day, TimeInterval *ti ); |
426 | void setWorkInterval( TimeInterval *ti, const TimeInterval &value ); |
427 | |
428 | /** |
429 | * Find the definition for the day @p date. |
430 | * If @p skipUndefined = true the day is NOT returned if it has state Undefined. |
431 | */ |
432 | CalendarDay *findDay(const QDate &date, bool skipUndefined=false) const; |
433 | void addDay(CalendarDay *day); |
434 | CalendarDay *takeDay(CalendarDay *day); |
435 | const QList<CalendarDay*> &days() const { return m_days; } |
436 | QList<QPair<CalendarDay*, CalendarDay*> > consecutiveVacationDays() const; |
437 | QList<CalendarDay*> workingDays() const; |
438 | int indexOf( const CalendarDay *day ) const { return m_days.indexOf( const_cast<CalendarDay*>( day ) ); } |
439 | CalendarDay *dayAt( int index ) { return m_days.value( index ); } |
440 | int numDays() const { return m_days.count(); } |
441 | void setDate( CalendarDay *day, const QDate &date ); |
442 | CalendarDay *day( const QDate &date ) const; |
443 | |
444 | IntMap weekdayStateMap() const; |
445 | |
446 | CalendarWeekdays *weekdays() const { return m_weekdays; } |
447 | CalendarDay *weekday(int day) const { return m_weekdays->weekday(day); } |
448 | int indexOfWeekday( const CalendarDay *day ) const { return m_weekdays->indexOf( day ); } |
449 | const QList<CalendarDay*> weekdayList() const { return m_weekdays->weekdays(); } |
450 | int numWeekdays() const { return weekdayList().count(); } |
451 | |
452 | /// Sets the @p weekday data to the data in @p day |
453 | void setWeekday( int weekday, const CalendarDay &day ); |
454 | |
455 | QString parentId() const { return m_parentId; } |
456 | void setParentId(const QString& id) { m_parentId = id; } |
457 | bool hasParent(Calendar *cal); |
458 | |
459 | /** |
460 | * Returns the work intervals in the interval from @p start to @p end |
461 | * Sets the load of each interval to @p load |
462 | */ |
463 | AppointmentIntervalList workIntervals(const DateTime &start, const DateTime &end, double load) const; |
464 | |
465 | /** |
466 | * Returns the amount of 'worktime' that can be done in the |
467 | * interval from @p start to @p end |
468 | * If @p sch is not 0, the schedule is checked for availability. |
469 | */ |
470 | Duration effort(const DateTime &start, const DateTime &end, Schedule *sch=0) const; |
471 | |
472 | /** |
473 | * Returns the first 'work interval' for the interval |
474 | * starting at @p start and ending at @p end. |
475 | * If no 'work interval' exists, returns an interval with invalid DateTime. |
476 | * You can also use @ref hasInterval() to check if a 'work interval' exists. |
477 | * If @p sch is not 0, the schedule is checked for availability. |
478 | */ |
479 | DateTimeInterval firstInterval(const DateTime &start, const DateTime &end, Schedule *sch=0) const; |
480 | |
481 | /** |
482 | * Returns true if at least a part of a 'work interval' exists |
483 | * for the interval starting at @p start and ending at @p end. |
484 | * If @p sch is not 0, the schedule is checked for availability. |
485 | */ |
486 | bool hasInterval(const DateTime &start, const DateTime &end, Schedule *sch=0) const; |
487 | |
488 | /** |
489 | * Find the first available time after @p time before @p limit. |
490 | * Return invalid datetime if not available. |
491 | * If @p sch is not 0, the schedule is checked for availability. |
492 | */ |
493 | DateTime firstAvailableAfter(const DateTime &time, const DateTime &limit, Schedule *sch = 0); |
494 | /** |
495 | * Find the first available time backwards from @p time. Search until @p limit. |
496 | * Return invalid datetime if not available. |
497 | * If @p sch is not 0, the schedule is checked for availability. |
498 | */ |
499 | DateTime firstAvailableBefore(const DateTime &time, const DateTime &limit, Schedule *sch = 0); |
500 | |
501 | Calendar *findCalendar() const { return findCalendar(m_id); } |
502 | Calendar *findCalendar(const QString &id) const; |
503 | bool removeId() { return removeId(m_id); } |
504 | bool removeId(const QString &id); |
505 | void insertId(const QString &id); |
506 | |
507 | const KDateTime::Spec &timeSpec() const { return m_spec; } |
508 | KTimeZone timeZone() const { return m_spec.timeZone(); } |
509 | void setTimeZone( const KTimeZone &tz ); |
510 | |
511 | void setDefault( bool on ); |
512 | bool isDefault() const { return m_default; } |
513 | |
514 | int cacheVersion() const; |
515 | void incCacheVersion(); |
516 | void setCacheVersion( int version ); |
517 | bool loadCacheVersion( KoXmlElement &element, XMLLoaderObject &status ); |
518 | void saveCacheVersion( QDomElement &element ) const; |
519 | |
520 | signals: |
521 | void changed( Calendar* ); |
522 | void changed( CalendarDay* ); |
523 | void changed( TimeInterval* ); |
524 | |
525 | void weekdayToBeAdded( CalendarDay *day, int index ); |
526 | void weekdayAdded( CalendarDay *day ); |
527 | void weekdayToBeRemoved( CalendarDay *day ); |
528 | void weekdayRemoved( CalendarDay *day ); |
529 | |
530 | void dayToBeAdded( CalendarDay *day, int index ); |
531 | void dayAdded( CalendarDay *day ); |
532 | void dayToBeRemoved( CalendarDay *day ); |
533 | void dayRemoved( CalendarDay *day ); |
534 | |
535 | void workIntervalToBeAdded( CalendarDay*, TimeInterval*, int index ); |
536 | void workIntervalAdded( CalendarDay*, TimeInterval* ); |
537 | void workIntervalToBeRemoved( CalendarDay*, TimeInterval* ); |
538 | void workIntervalRemoved( CalendarDay*, TimeInterval* ); |
539 | |
540 | protected: |
541 | void init(); |
542 | const Calendar ©(const Calendar &calendar); |
543 | |
544 | /** |
545 | * Returns the amount of 'worktime' that can be done on |
546 | * the @p date between the times @p start and @p start + @p length. |
547 | * The date and times are in timespecification @p spec. |
548 | * If @p sch is not 0, the schedule is checked for availability. |
549 | */ |
550 | Duration effort(const QDate &date, const QTime &start, int length, Schedule *sch=0) const; |
551 | /** |
552 | * Returns the amount of 'worktime' that can be done in the |
553 | * interval from @p start to @p end |
554 | * If @p sch is not 0, the schedule is checked for availability. |
555 | */ |
556 | Duration effort(const KDateTime &start, const KDateTime &end, Schedule *sch=0) const; |
557 | /** |
558 | * Returns the first 'work interval' on date for the interval |
559 | * starting at @p start and ending at @p start + @p length. |
560 | * If no 'work interval' exists, returns a null interval. |
561 | * You can also use @ref hasInterval() to check if a 'work interval' exists. |
562 | * The date and times are in timespecification spec. |
563 | * If @p sch is not 0, the schedule is checked for availability. |
564 | */ |
565 | TimeInterval firstInterval(const QDate &date, const QTime &start, int length, Schedule *sch=0) const; |
566 | /** |
567 | * Returns the first 'work interval' for the interval |
568 | * starting at @p start and ending at @p end. |
569 | * If no 'work interval' exists, returns an interval with invalid DateTime. |
570 | */ |
571 | DateTimeInterval firstInterval( const KDateTime &start, const KDateTime &end, Schedule *sch=0) const; |
572 | |
573 | /** |
574 | * Returns true if at least a part of a 'work interval' exists |
575 | * for the interval on date, starting at @p start and ending at @p start + @p length. |
576 | * If @p sch is not 0, the schedule is checked for availability. |
577 | */ |
578 | bool hasInterval(const QDate &date, const QTime &start, int length, Schedule *sch=0) const; |
579 | |
580 | /** |
581 | * Returns the work intervals in the interval from @p start to @p end |
582 | * Sets the load of each interval to @p load |
583 | */ |
584 | AppointmentIntervalList workIntervals(const KDateTime &start, const KDateTime &end, double load) const; |
585 | |
586 | /** |
587 | * Find the first available time backwards from @p time. Search until @p limit. |
588 | * Return invalid datetime if not available. |
589 | * If @p sch is not 0, the schedule is checked for availability. |
590 | */ |
591 | DateTime firstAvailableBefore(const KDateTime &time, const KDateTime &limit, Schedule *sch = 0); |
592 | |
593 | private: |
594 | QString m_name; |
595 | Calendar *m_parent; |
596 | Project *m_project; |
597 | bool m_deleted; |
598 | QString m_id; |
599 | QString m_parentId; |
600 | |
601 | QList<CalendarDay*> m_days; |
602 | CalendarWeekdays *m_weekdays; |
603 | |
604 | QList<Calendar*> m_calendars; |
605 | |
606 | KDateTime::Spec m_spec; |
607 | bool m_default; // this is the default calendar, only used for save/load |
608 | int m_cacheversion; // incremented every time a calendar is changed |
609 | friend class Project; |
610 | int m_blockversion; // don't update if true |
611 | #ifndef NDEBUG |
612 | public: |
613 | void printDebug(const QString& indent=QString()); |
614 | #endif |
615 | }; |
616 | |
617 | class KPLATOKERNEL_EXPORT StandardWorktime |
618 | { |
619 | public: |
620 | explicit StandardWorktime( Project *project = 0 ); |
621 | explicit StandardWorktime(StandardWorktime* worktime); |
622 | ~StandardWorktime(); |
623 | |
624 | /// Set Project |
625 | void setProject( Project *project ) { m_project = project; } |
626 | /// The work time of a normal year. |
627 | Duration durationYear() const { return m_year; } |
628 | /// The work time of a normal year. |
629 | double year() const { return m_year.toDouble(Duration::Unit_h); } |
630 | /// Set the work time of a normal year. |
631 | void setYear(const Duration year) { m_year = year; } |
632 | /// Set the work time of a normal year. |
633 | void setYear(double hours) { m_year = Duration((qint64)(hours*60.0*60.0*1000.0)); } |
634 | |
635 | /// The work time of a normal month |
636 | Duration durationMonth() const { return m_month; } |
637 | /// The work time of a normal month |
638 | double month() const { return m_month.toDouble(Duration::Unit_h); } |
639 | /// Set the work time of a normal month |
640 | void setMonth(const Duration month) { m_month = month; } |
641 | /// Set the work time of a normal month |
642 | void setMonth(double hours) { m_month = Duration((qint64)(hours*60.0*60.0*1000.0)); } |
643 | |
644 | /// The work time of a normal week |
645 | Duration durationWeek() const { return m_week; } |
646 | /// The work time of a normal week |
647 | double week() const { return m_week.toDouble(Duration::Unit_h); } |
648 | /// Set the work time of a normal week |
649 | void setWeek(const Duration week) { m_week = week; } |
650 | /// Set the work time of a normal week |
651 | void setWeek(double hours) { m_week = Duration((qint64)(hours*60.0*60.0*1000.0)); } |
652 | |
653 | /// The work time of a normal day |
654 | Duration durationDay() const { return m_day; } |
655 | /// The work time of a normal day |
656 | double day() const { return m_day.toDouble(Duration::Unit_h); } |
657 | /// Set the work time of a normal day |
658 | void setDay(const Duration day) { m_day = day; changed(); } |
659 | /// Set the work time of a normal day |
660 | void setDay(double hours) { m_day = Duration(hours, Duration::Unit_h); changed(); } |
661 | |
662 | QList<qint64> scales() const; |
663 | |
664 | bool load( KoXmlElement &element, XMLLoaderObject &status ); |
665 | void save(QDomElement &element) const; |
666 | |
667 | void changed(); |
668 | |
669 | protected: |
670 | void init(); |
671 | |
672 | private: |
673 | Project *m_project; |
674 | Duration m_year; |
675 | Duration m_month; |
676 | Duration m_week; |
677 | Duration m_day; |
678 | }; |
679 | |
680 | } //KPlato namespace |
681 | |
682 | #endif |
683 | |