/* This file is part of the KDE project Copyright (C) 2003 - 2006 Dag Andersen 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. */ #include "kptcalendar.h" #include "kptduration.h" #include "kptdatetime.h" #include "kptproject.h" #include #include #include #include namespace KPlato { ///// CalendarDay //// CalendarDay::CalendarDay() : m_date(), m_state(0), m_workingIntervals() { //kdDebug()<(start,end)); } } } } return true; } void CalendarDay::save(TQDomElement &element) const { //kdDebug()< > it = m_workingIntervals; for (; it.current(); ++it) { TQDomElement me = element.ownerDocument().createElement("interval"); element.appendChild(me); me.setAttribute("end", it.current()->second.toString()); me.setAttribute("start", it.current()->first.toString()); } } void CalendarDay::addInterval(TQPair *interval) { m_workingIntervals.append(interval); } TQTime CalendarDay::startOfDay() const { TQTime t; if (!m_workingIntervals.isEmpty()) { TQPtrListIterator > it = m_workingIntervals; t = it.current()->first; for (++it; it.current(); ++it) { if (t > it.current()->first) t = it.current()->first; } } return t; } TQTime CalendarDay::endOfDay() const { TQTime t; if (!m_workingIntervals.isEmpty()) { TQPtrListIterator > it = m_workingIntervals; t = it.current()->second; for (++it; it.current(); ++it) { if (t > it.current()->second) t = it.current()->second; } } return t; } bool CalendarDay::operator==(const CalendarDay *day) const { return operator==(*day); } bool CalendarDay::operator==(const CalendarDay &day) const { //kdDebug()<first.toString()<<"-"<second.toString()< > it = m_workingIntervals; for (; it.current(); ++it) { //kdDebug()<first.toString()<<" - "<second.toString()< it.current()->first && start < it.current()->second) { DateTime dtStart(TQDate::tqcurrentDate(), start); if (start < it.current()->first) { dtStart.setTime(it.current()->first); } DateTime dtEnd(TQDate::tqcurrentDate(), end); if (end > it.current()->second) { dtEnd.setTime(it.current()->second); } eff += dtEnd - dtStart; //kdDebug()<(t1, t2); } } } //kdError()<(t1, t2); } bool CalendarDay::hasInterval() const { return m_state == Map::Working && m_workingIntervals.count() > 0; } bool CalendarDay::hasInterval(const TQTime &start, const TQTime &end) const { //kdDebug()< > it = m_workingIntervals; for (; it.current(); ++it) { if (start < it.current()->second && end > it.current()->first) { //kdDebug()<first.toString()<<" - "<second.toString()< > it = m_workingIntervals; for (; it.current(); ++it) { DateTime start(TQDate::tqcurrentDate(), it.current()->first); DateTime end(TQDate::tqcurrentDate(), it.current()->second); dur += end - start; } return dur; } ///// CalendarWeekdays //// CalendarWeekdays::CalendarWeekdays() : m_weekdays(), m_workHours(40) { //kdDebug()<"<"< it = weekdays.weekdays(); for (; it.current(); ++it) { m_weekdays.append(new CalendarDay(it.current())); } return *this; } bool CalendarWeekdays::load(TQDomElement &element) { //kdDebug()< 6) { kdError()<load(element)) day->setState(Map::None); return true; } void CalendarWeekdays::save(TQDomElement &element) const { //kdDebug()< it = m_weekdays; for (int i=0; it.current(); ++it) { TQDomElement me = element.ownerDocument().createElement("weekday"); element.appendChild(me); me.setAttribute("day", i++); it.current()->save(me); } } IntMap CalendarWeekdays::map() { IntMap days; for (unsigned int i=0; i < m_weekdays.count(); ++i) { if (m_weekdays.at(i)->state() > 0) days.insert(i+1, m_weekdays.at(i)->state()); //Note: day numbers 1..7 } return days; } int CalendarWeekdays::state(const TQDate &date) const { return state(date.dayOfWeek()-1); } int CalendarWeekdays::state(int weekday) const { CalendarDay *day = const_cast(this)->m_weekdays.at(weekday); return day ? day->state() : Map::None; } void CalendarWeekdays::setState(int weekday, int state) { CalendarDay *day = m_weekdays.at(weekday); if (!day) return; day->setState(state); } const TQPtrList > &CalendarWeekdays::intervals(int weekday) const { CalendarDay *day = const_cast(this)->m_weekdays.at(weekday); Q_ASSERT(day); return day->workingIntervals(); } void CalendarWeekdays::setIntervals(int weekday, TQPtrList >intervals) { CalendarDay *day = m_weekdays.at(weekday); if (day) day->setIntervals(intervals); } void CalendarWeekdays::clearIntervals(int weekday) { CalendarDay *day = m_weekdays.at(weekday); if (day) day->clearIntervals(); } bool CalendarWeekdays::operator==(const CalendarWeekdays *wd) const { if (m_weekdays.count() != wd->weekdays().count()) return false; for (unsigned int i=0; i < m_weekdays.count(); ++i) { // is there a better way to get around this const stuff? CalendarDay *day1 = const_cast(this)->m_weekdays.at(i); CalendarDay *day2 = const_cast&>(wd->weekdays()).at(i); if (day1 != day2) return false; } return true; } bool CalendarWeekdays::operator!=(const CalendarWeekdays *wd) const { if (m_weekdays.count() != wd->weekdays().count()) return true; for (unsigned int i=0; i < m_weekdays.count(); ++i) { // is there a better way to get around this const stuff? CalendarDay *day1 = const_cast(this)->m_weekdays.at(i); CalendarDay *day2 = const_cast&>(wd->weekdays()).at(i); if (day1 != day2) return true; } return false; } Duration CalendarWeekdays::effort(const TQDate &date, const TQTime &start, const TQTime &end) { //kdDebug()<hasInterval(start, end); } bool CalendarWeekdays::hasInterval() const { //kdDebug()< it = m_weekdays; for (; it.current(); ++it) { if (it.current()->hasInterval()) return true; } return false; } CalendarDay *CalendarWeekdays::weekday(int day) const { TQPtrListIterator it = m_weekdays; for (int i=0; it.current(); ++it, ++i) { if (i == day) return it.current(); } return 0; } Duration CalendarWeekdays::duration() const { Duration dur; TQPtrListIterator it = m_weekdays; for (; it.current(); ++it) { dur += it.current()->duration(); } return dur; } Duration CalendarWeekdays::duration(int _weekday) const { CalendarDay *day = weekday(_weekday); if (day) return day->duration(); return Duration(); } TQTime CalendarWeekdays::startOfDay(int _weekday) const { CalendarDay *day = weekday(_weekday); if (day) return day->startOfDay(); return TQTime(); } TQTime CalendarWeekdays::endOfDay(int _weekday) const { CalendarDay *day = weekday(_weekday); if (day) return day->endOfDay(); return TQTime(); } ///// Calendar //// Calendar::Calendar() : m_parent(0), m_project(0), m_deleted(false) { init(); } Calendar::Calendar(TQString name, Calendar *parent) : m_name(name), m_parent(parent), m_project(0), m_deleted(false), m_days() { init(); } Calendar::~Calendar() { //kdDebug()< it = calendar.days(); for (; it.current(); ++it) { m_days.append(new CalendarDay(it.current())); } m_weekdays = new CalendarWeekdays(calendar.weekdays()); return *this; } void Calendar::init() { m_days.setAutoDelete(true); m_weekdays = new CalendarWeekdays(); } void Calendar::setProject(Project *project) { m_project = project; generateId(); } void Calendar::setDeleted(bool yes) { if (yes) { removeId(); } else { setId(m_id); } m_deleted = yes; } bool Calendar::setId(TQString id) { //kdDebug()<name()<name()<load(e)) return false; } if (e.tagName() == "day") { CalendarDay *day = new CalendarDay(); if (day->load(e)) { if (!day->date().isValid()) { delete day; kdError()<date()); if (d) { // already exists, keep the new removeDay(d); kdWarning()<isDeleted()) me.setAttribute("parent", m_parent->id()); me.setAttribute("name", m_name); me.setAttribute("id", m_id); m_weekdays->save(me); TQPtrListIterator it = m_days; for (; it.current(); ++it) { TQDomElement e = me.ownerDocument().createElement("day"); me.appendChild(e); it.current()->save(e); } } CalendarDay *Calendar::findDay(const TQDate &date, bool skipNone) const { //kdDebug()< it = m_days; for (; it.current(); ++it) { if (it.current()->date() == date) { if (skipNone && it.current()->state() == Map::None) { continue; // hmmm, break? } return it.current(); } } //kdDebug()<hasParent(cal); } Duration Calendar::effort(const TQDate &date, const TQTime &start, const TQTime &end) const { //kdDebug()< end) { _start = end; _end = start; } // first, check my own day CalendarDay *day = findDay(date, true); if (day) { if (day->state() == Map::Working) { return day->effort(_start, _end); } else if (day->state() == Map::NonWorking) { return Duration::zeroDuration; } else { kdError()<state()<state(date) == Map::Working) { return m_weekdays->effort(date, _start, _end); } if (m_weekdays->state(date) == Map::NonWorking) { return Duration::zeroDuration; } } if (m_parent && !m_parent->isDeleted()) { return m_parent->effort(date, start, end); } // Check default calendar return project()->defaultCalendar()->effort(date, start, end); } Duration Calendar::effort(const DateTime &start, const DateTime &end) const { //kdDebug()< date) { endTime.setHMS(23, 59, 59, 999); } eff = effort(date, startTime, endTime); // first day // Now get all the rest of the days for (date = date.addDays(1); date <= end.date(); date = date.addDays(1)) { if (date < end.date()) eff += effort(date, TQTime(), endTime); // whole days else eff += effort(date, TQTime(), end.time()); // last day //kdDebug()<(DateTime(), DateTime()); } if (!end.isValid()) { kdWarning()<(DateTime(), DateTime()); } TQTime startTime; TQTime endTime; TQDate date = start.date(); int i=0; for (; date <= end.date(); date = date.addDays(1)) { if (date < end.date()) endTime = TQTime(23, 59, 59, 999); else endTime = end.time(); if (date > start.date()) startTime = TQTime(); else startTime = start.time(); TQPair res = firstInterval(date, startTime, endTime); if (res.first < res.second) { return TQPair(DateTime(date,res.first),DateTime(date, res.second)); } } //kdError()<(DateTime(), DateTime()); } bool Calendar::hasInterval(const TQDate &date, const TQTime &startTime, const TQTime &endTime) const { CalendarDay *day = findDay(date, true); if (day) { //kdDebug()<hasInterval(startTime, endTime); } if (m_weekdays) { if (m_weekdays->state(date) == Map::Working) { return m_weekdays->hasInterval(date, startTime, endTime); } else if (m_weekdays->state(date) == Map::NonWorking) { return false; } } if (m_parent && !m_parent->isDeleted()) { return m_parent->hasInterval(date, startTime, endTime); } return project()->defaultCalendar()->hasInterval(date, startTime, endTime); } bool Calendar::hasInterval(const DateTime &start, const DateTime &end) const { //kdDebug()<end?"":"(start<=end)")< start.date()) startTime = TQTime(); else startTime = start.time(); if (hasInterval(date, startTime, endTime)) return true; } return false; } DateTime Calendar::firstAvailableAfter(const DateTime &time, const DateTime &limit) { //kdDebug()<limit?"":"(time>=limit)")<limit?"":"(time<=limit)")<findCalendar(id) : 0); } bool Calendar::removeId(const TQString &id) { return (m_project ? m_project->removeCalendarId(id) : false); } void Calendar::insertId(const TQString &id){ if (m_project) m_project->insertCalendarId(id, this); } ///////////// StandardWorktime::StandardWorktime() { init(); } StandardWorktime::StandardWorktime(StandardWorktime *worktime) { if (worktime) { m_year = worktime->durationYear(); m_month = worktime->durationMonth(); m_week = worktime->durationWeek(); m_day = worktime->durationDay(); m_calendar = new Calendar(*(worktime->calendar())); } else { init(); } } StandardWorktime::~StandardWorktime() { //kdDebug()<setName(i18n("Base")); TQPair t = TQPair(TQTime(8,0,0), TQTime(16,0,0)); for (int i=0; i < 5; ++i) { m_calendar->weekday(i)->addInterval(t); m_calendar->weekday(i)->setState(Map::Working); } m_calendar->weekday(5)->setState(Map::NonWorking); m_calendar->weekday(6)->setState(Map::NonWorking); } bool StandardWorktime::load(TQDomElement &element) { //kdDebug()<load(e); } } } return true; } void StandardWorktime::save(TQDomElement &element) const { //kdDebug()<save(me); } #ifndef NDEBUG void CalendarDay::printDebug(TQCString indent) { TQString s[] = {"None", "Non-working", "Working"}; kdDebug()< > it = m_workingIntervals; for (; it.current(); ++it) { kdDebug()<first<<" to "<second< it = m_weekdays; for (char c='0'; it.current(); ++it) { it.current()->printDebug(indent + " Day " + c++ + ": "); } } void Calendar::printDebug(TQCString indent) { kdDebug()<name() : "No parent")<printDebug(indent + " "); kdDebug()< it = m_days; for (; it.current(); ++it) { it.current()->printDebug(indent + " "); } } void StandardWorktime::printDebug(TQCString indent) { kdDebug()<