You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
402 lines
13 KiB
402 lines
13 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2003 - 2006 Dag Andersen <danders@get2net.dk>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation;
|
|
version 2 of the License.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef KPTCALENDAR_H
|
|
#define KPTCALENDAR_H
|
|
|
|
#include "kptmap.h"
|
|
#include "kptduration.h"
|
|
|
|
#include <qdatetime.h>
|
|
#include <qpair.h>
|
|
#include <qptrlist.h>
|
|
|
|
class QDomElement;
|
|
class QDateTime;
|
|
class QTime;
|
|
class QDate;
|
|
class QString;
|
|
|
|
namespace KPlato
|
|
{
|
|
|
|
class DateTime;
|
|
class Project;
|
|
|
|
class CalendarDay {
|
|
|
|
public:
|
|
CalendarDay();
|
|
CalendarDay(int state);
|
|
CalendarDay(QDate date, int state=0);
|
|
CalendarDay(CalendarDay *day);
|
|
~CalendarDay();
|
|
|
|
bool load(QDomElement &element);
|
|
void save(QDomElement &element) const;
|
|
|
|
const QPtrList<QPair<QTime, QTime> > &workingIntervals() const { return m_workingIntervals; }
|
|
void addInterval(QPair<QTime, QTime> *interval);
|
|
void addInterval(QPair<QTime, QTime> interval) { addInterval(new QPair<QTime, QTime>(interval)); }
|
|
void clearIntervals() { m_workingIntervals.clear(); }
|
|
void setIntervals(QPtrList<QPair<QTime, QTime> > intervals) {
|
|
m_workingIntervals.clear();
|
|
m_workingIntervals = intervals;
|
|
}
|
|
|
|
QTime startOfDay() const;
|
|
QTime endOfDay() const;
|
|
|
|
QDate date() const { return m_date; }
|
|
void setDate(QDate date) { m_date = date; }
|
|
int state() const { return m_state; }
|
|
void setState(int state) { m_state = state; }
|
|
|
|
bool operator==(const CalendarDay *day) const;
|
|
bool operator==(const CalendarDay &day) const;
|
|
bool operator!=(const CalendarDay *day) const;
|
|
bool operator!=(const CalendarDay &day) const;
|
|
|
|
/**
|
|
* Returns the amount of 'worktime' that can be done on
|
|
* this day between the times start and end.
|
|
*/
|
|
Duration effort(const QTime &start, const QTime &end);
|
|
|
|
/**
|
|
* Returns the actual 'work interval' for the interval start to end.
|
|
* If no 'work interval' exists, returns the interval start, end.
|
|
* Use @ref hasInterval() to check if a 'work interval' exists.
|
|
*/
|
|
QPair<QTime, QTime> interval(const QTime &start, const QTime &end) const;
|
|
|
|
bool hasInterval() const;
|
|
|
|
/**
|
|
* Returns true if at least a part of a 'work interval' exists
|
|
* for the interval start to end.
|
|
*/
|
|
bool hasInterval(const QTime &start, const QTime &end) const;
|
|
|
|
Duration duration() const;
|
|
|
|
const CalendarDay ©(const CalendarDay &day);
|
|
|
|
private:
|
|
QDate m_date; //NOTE: inValid if used for weekdays
|
|
int m_state;
|
|
QPtrList<QPair<QTime, QTime> > m_workingIntervals;
|
|
|
|
#ifndef NDEBUG
|
|
public:
|
|
void printDebug(QCString indent="");
|
|
#endif
|
|
};
|
|
|
|
class CalendarWeekdays {
|
|
|
|
public:
|
|
CalendarWeekdays();
|
|
CalendarWeekdays(CalendarWeekdays *weekdays);
|
|
~CalendarWeekdays();
|
|
|
|
bool load(QDomElement &element);
|
|
void save(QDomElement &element) const;
|
|
|
|
void addWeekday(CalendarDay *day) { m_weekdays.append(day); }
|
|
const QPtrList<CalendarDay> &weekdays() const { return m_weekdays; }
|
|
/**
|
|
* Returns the pointer to CalendarDay for day or 0 if not defined.
|
|
* day is 0..6.
|
|
* @param day todo : add a comment
|
|
*/
|
|
CalendarDay *weekday(int day) const;
|
|
CalendarDay *weekday(const QDate &date) const { return weekday(date.dayOfWeek()-1); }
|
|
CalendarDay *replace(int weekday, CalendarDay *day) {
|
|
CalendarDay *d = m_weekdays.at(weekday);
|
|
m_weekdays.replace(weekday, day);
|
|
return d;
|
|
}
|
|
IntMap map();
|
|
|
|
void setWeekday(IntMap::iterator it, int state) { m_weekdays.at(it.key())->setState(state); }
|
|
|
|
int state(const QDate &date) const;
|
|
int state(int weekday) const;
|
|
void setState(int weekday, int state);
|
|
|
|
const QPtrList<QPair<QTime, QTime> > &intervals(int weekday) const;
|
|
void setIntervals(int weekday, QPtrList<QPair<QTime, QTime> >intervals);
|
|
void clearIntervals(int weekday);
|
|
|
|
bool operator==(const CalendarWeekdays *weekdays) const;
|
|
bool operator!=(const CalendarWeekdays *weekdays) const;
|
|
|
|
Duration effort(const QDate &date, const QTime &start, const QTime &end);
|
|
|
|
/**
|
|
* Returns the actual 'work interval' on the weekday defined by date
|
|
* for the interval start to end.
|
|
* If no 'work interval' exists, returns the interval start, end.
|
|
* Use @ref hasInterval() to check if a 'work interval' exists.
|
|
*/
|
|
QPair<QTime, QTime> interval(const QDate date, const QTime &start, const QTime &end) const;
|
|
/**
|
|
* Returns true if at least a part of a 'work interval' exists
|
|
* on the weekday defined by date for the interval start to end.
|
|
*/
|
|
bool hasInterval(const QDate date, const QTime &start, const QTime &end) const;
|
|
bool hasInterval() const;
|
|
|
|
Duration duration() const;
|
|
Duration duration(int weekday) const;
|
|
|
|
/// Returns the time when the weekday starts
|
|
QTime startOfDay(int weekday) const;
|
|
/// Returns the time when the weekday ends
|
|
QTime endOfDay(int weekday) const;
|
|
|
|
const CalendarWeekdays ©(const CalendarWeekdays &weekdays);
|
|
|
|
private:
|
|
QPtrList<CalendarDay> m_weekdays;
|
|
double m_workHours;
|
|
|
|
#ifndef NDEBUG
|
|
public:
|
|
void printDebug(QCString indent="");
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* Calendar defines the working and nonworking days and hours.
|
|
* A day can have the three states None (Undefined), NonWorking, or Working.
|
|
* A calendar can have a parent calendar that defines the days that are
|
|
* undefined in this calendar. If a day is still undefined, it defaults
|
|
* to Nonworking.
|
|
* A Working day has one or more work intervals to define the work hours.
|
|
*
|
|
* The definition can consist of two parts: Weekdays and Day.
|
|
* Day has highest priority.
|
|
*
|
|
* A typical calendar hierarchy could include calendars on three levels:
|
|
* 1. Definition of normal weekdays and national holidays/vacation days.
|
|
* 2. Definition of the company's special workdays/-time and vacation days.
|
|
* 3. Definitions for groups of resources/individual resources.
|
|
*
|
|
*/
|
|
class Calendar {
|
|
|
|
public:
|
|
Calendar();
|
|
Calendar(QString name, Calendar *parent=0);
|
|
Calendar(Calendar *calendar);
|
|
~Calendar();
|
|
|
|
QString name() const { return m_name; }
|
|
void setName(QString name) { m_name = name; }
|
|
|
|
Calendar *parent() const { return m_parent; }
|
|
void setParent(Calendar *parent) { m_parent = parent; }
|
|
|
|
Project *project() const { return m_project; }
|
|
void setProject(Project *project);
|
|
|
|
bool isDeleted() const { return m_deleted; }
|
|
void setDeleted(bool yes);
|
|
|
|
QString id() const { return m_id; }
|
|
bool setId(QString id);
|
|
void generateId();
|
|
|
|
bool load(QDomElement &element);
|
|
void save(QDomElement &element) const;
|
|
|
|
/**
|
|
* Find the definition for the day date.
|
|
* If skipUndefined=true the day is NOT returned if it has state None (Undefined).
|
|
*/
|
|
CalendarDay *findDay(const QDate &date, bool skipUndefined=false) const;
|
|
bool addDay(CalendarDay *day) { return m_days.insert(0, day); }
|
|
bool removeDay(CalendarDay *day) { return m_days.removeRef(day); }
|
|
CalendarDay *takeDay(CalendarDay *day) { return m_days.take(m_days.find(day)); }
|
|
const QPtrList<CalendarDay> &days() const { return m_days; }
|
|
|
|
/**
|
|
* Returns the state of definition for parents day date in it.
|
|
* Also checks the parents recursively.
|
|
*/
|
|
int parentDayState(const QDate &date) const;
|
|
|
|
IntMap weekdaysMap() { return m_weekdays->map(); }
|
|
void setWeekday(IntMap::iterator it, int state) { m_weekdays->setWeekday(it, state); }
|
|
CalendarWeekdays *weekdays() { return m_weekdays; }
|
|
CalendarDay *weekday(int day) const { return m_weekdays->weekday(day); }
|
|
|
|
QString parentId() const { return m_parentId; }
|
|
void setParentId(QString id) { m_parentId = id; }
|
|
|
|
bool hasParent(Calendar *cal);
|
|
|
|
/**
|
|
* Returns the amount of 'worktime' that can be done on
|
|
* the date date between the times start and end.
|
|
*/
|
|
Duration effort(const QDate &date, const QTime &start, const QTime &end) const;
|
|
/**
|
|
* Returns the amount of 'worktime' that can be done in the
|
|
* interval from start to end
|
|
*/
|
|
Duration effort(const DateTime &start, const DateTime &end) const;
|
|
|
|
/**
|
|
* Returns the first 'work interval' for the interval
|
|
* starting at start and ending at end.
|
|
* If no 'work interval' exists, returns an interval with invalid DateTime.
|
|
* You can also use @ref hasInterval() to check if a 'work interval' exists.
|
|
*/
|
|
QPair<DateTime, DateTime> firstInterval(const DateTime &start, const DateTime &end) const;
|
|
|
|
/**
|
|
* Returns the first 'work interval' on date for the interval
|
|
* starting at start and ending at end.
|
|
* If no 'work interval' exists, returns an interval with first==second.
|
|
* You can also use @ref hasInterval() to check if a 'work interval' exists.
|
|
*/
|
|
QPair<QTime, QTime> firstInterval(const QDate &date, const QTime &start, const QTime &end) const;
|
|
|
|
/**
|
|
* Returns true if at least a part of a 'work interval' exists
|
|
* for the interval starting at start and ending at end.
|
|
*/
|
|
bool hasInterval(const DateTime &start, const DateTime &end) const;
|
|
|
|
/**
|
|
* Returns true if at least a part of a 'work interval' exists
|
|
* for the interval on date, starting at start and ending at end.
|
|
*/
|
|
bool hasInterval(const QDate &date, const QTime &start, const QTime &end) const;
|
|
|
|
/**
|
|
* Find the first available time after time before limit.
|
|
* Return invalid datetime if not available.
|
|
*/
|
|
DateTime firstAvailableAfter(const DateTime &time, const DateTime &limit);
|
|
/**
|
|
* Find the first available time backwards from time. Search until limit.
|
|
* Return invalid datetime if not available.
|
|
*/
|
|
DateTime firstAvailableBefore(const DateTime &time, const DateTime &limit);
|
|
|
|
Calendar *findCalendar() const { return findCalendar(m_id); }
|
|
Calendar *findCalendar(const QString &id) const;
|
|
bool removeId() { return removeId(m_id); }
|
|
bool removeId(const QString &id);
|
|
void insertId(const QString &id);
|
|
|
|
protected:
|
|
const Calendar ©(Calendar &calendar);
|
|
void init();
|
|
|
|
private:
|
|
QString m_name;
|
|
Calendar *m_parent;
|
|
Project *m_project;
|
|
bool m_deleted;
|
|
QString m_id;
|
|
QString m_parentId;
|
|
|
|
QPtrList<CalendarDay> m_days;
|
|
CalendarWeekdays *m_weekdays;
|
|
|
|
#ifndef NDEBUG
|
|
public:
|
|
void printDebug(QCString indent="");
|
|
#endif
|
|
};
|
|
|
|
class StandardWorktime
|
|
{
|
|
public:
|
|
StandardWorktime();
|
|
StandardWorktime(StandardWorktime* worktime);
|
|
~StandardWorktime();
|
|
|
|
/// The work time of a normal year.
|
|
Duration durationYear() const { return m_year; }
|
|
/// The work time of a normal year.
|
|
double year() const { return m_year.toDouble(Duration::Unit_h); }
|
|
/// Set the work time of a normal year.
|
|
void setYear(const Duration year) { m_year = year; }
|
|
/// Set the work time of a normal year.
|
|
void setYear(double hours) { m_year = Duration((Q_INT64)(hours*60.0*60.0)); }
|
|
|
|
/// The work time of a normal month
|
|
Duration durationMonth() const { return m_month; }
|
|
/// The work time of a normal month
|
|
double month() const { return m_month.toDouble(Duration::Unit_h); }
|
|
/// Set the work time of a normal month
|
|
void setMonth(const Duration month) { m_month = month; }
|
|
/// Set the work time of a normal month
|
|
void setMonth(double hours) { m_month = Duration((Q_INT64)(hours*60.0*60.0)); }
|
|
|
|
/// The work time of a normal week
|
|
Duration durationWeek() const { return m_week; }
|
|
/// The work time of a normal week
|
|
double week() const { return m_week.toDouble(Duration::Unit_h); }
|
|
/// Set the work time of a normal week
|
|
void setWeek(const Duration week) { m_week = week; }
|
|
/// Set the work time of a normal week
|
|
void setWeek(double hours) { m_week = Duration((Q_INT64)(hours*60.0*60.0)); }
|
|
|
|
/// The work time of a normal day
|
|
Duration durationDay() const { return m_day; }
|
|
/// The work time of a normal day
|
|
double day() const { return m_day.toDouble(Duration::Unit_h); }
|
|
/// Set the work time of a normal day
|
|
void setDay(const Duration day) { m_day = day; }
|
|
/// Set the work time of a normal day
|
|
void setDay(double hours) { m_day = Duration((Q_INT64)(hours*60.0*60.0)); }
|
|
|
|
bool load(QDomElement &element);
|
|
void save(QDomElement &element) const;
|
|
|
|
Calendar *calendar() const { return m_calendar; }
|
|
|
|
protected:
|
|
void init();
|
|
|
|
private:
|
|
Duration m_year;
|
|
Duration m_month;
|
|
Duration m_week;
|
|
Duration m_day;
|
|
|
|
Calendar *m_calendar;
|
|
|
|
#ifndef NDEBUG
|
|
public:
|
|
void printDebug(QCString indent="");
|
|
#endif
|
|
};
|
|
|
|
} //KPlato namespace
|
|
|
|
#endif
|