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.
koffice/kplato/kptcalendar.h

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 &copy(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 &copy(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 &copy(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