KCal Library
freebusy.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00034 #include "freebusy.h"
00035 #include "calendar.h"
00036 #include "event.h"
00037
00038 #include <kdebug.h>
00039
00040 #include <QtCore/QList>
00041
00042 using namespace KCal;
00043
00044
00045 class FreeBusy::Private
00046 {
00047 public:
00048
00049 bool addLocalPeriod( FreeBusy *fb, const KDateTime &start, const KDateTime &end );
00050 KDateTime mDtEnd;
00051 Period::List mBusyPeriods;
00052 Calendar *mCalendar;
00053 };
00054
00055
00056 FreeBusy::FreeBusy()
00057 : d( new Private )
00058 {
00059 }
00060
00061 FreeBusy::FreeBusy( const KDateTime &start, const KDateTime &end )
00062 : d( new Private )
00063 {
00064 setDtStart( start );
00065 setDtEnd( end );
00066 }
00067
00068 FreeBusy::FreeBusy( Calendar *calendar, const KDateTime &start,
00069 const KDateTime &end )
00070 : d( new Private )
00071 {
00072 kDebug(5800) << "FreeBusy::FreeBusy";
00073 d->mCalendar = calendar;
00074
00075 setDtStart( start );
00076 setDtEnd( end );
00077
00078
00079 Event::List eventList = d->mCalendar->rawEvents( start.date(), end.date() );
00080
00081 int extraDays, i, x, duration;
00082 duration = start.daysTo( end );
00083 QDate day;
00084 KDateTime tmpStart;
00085 KDateTime tmpEnd;
00086
00087
00088 Event::List::ConstIterator it;
00089 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
00090 Event *event = *it;
00091
00092
00093
00094
00095
00096 Event *allDayEvent = 0;
00097 if ( event->allDay() ) {
00098
00099 kDebug(5800) << "All-day event";
00100 allDayEvent = new Event( *event );
00101
00102
00103 KDateTime st = allDayEvent->dtStart();
00104 st.setTime( QTime( 0, 0 ) );
00105 KDateTime nd = allDayEvent->dtEnd();
00106 nd.setTime( QTime( 23, 59, 59, 999 ) );
00107 allDayEvent->setAllDay( false );
00108 allDayEvent->setDtStart( st );
00109 allDayEvent->setDtEnd( nd );
00110
00111 kDebug(5800) << "Use:" << st.toString() << "to" << nd.toString();
00112
00113 event = allDayEvent;
00114 }
00115
00116
00117
00118
00119
00120 if ( event->transparency() == Event::Transparent ) {
00121 continue;
00122 }
00123
00124 for ( i = 0; i <= duration; ++i ) {
00125 day = start.addDays(i).date();
00126 tmpStart.setDate( day );
00127 tmpEnd.setDate( day );
00128
00129 if ( event->recurs() ) {
00130 if ( event->isMultiDay() ) {
00131
00132
00133 extraDays = event->dtStart().daysTo( event->dtEnd() );
00134 for ( x = 0; x <= extraDays; ++x ) {
00135 if ( event->recursOn( day.addDays(-x), start.timeSpec() ) ) {
00136 tmpStart.setDate( day.addDays(-x) );
00137 tmpStart.setTime( event->dtStart().time() );
00138 tmpEnd = event->duration().end( tmpStart );
00139
00140 d->addLocalPeriod( this, tmpStart, tmpEnd );
00141 break;
00142 }
00143 }
00144 } else {
00145 if ( event->recursOn( day, start.timeSpec() ) ) {
00146 tmpStart.setTime( event->dtStart().time() );
00147 tmpEnd.setTime( event->dtEnd().time() );
00148
00149 d->addLocalPeriod ( this, tmpStart, tmpEnd );
00150 }
00151 }
00152 }
00153
00154 }
00155
00156 d->addLocalPeriod( this, event->dtStart(), event->dtEnd() );
00157
00158
00159 delete allDayEvent;
00160 }
00161
00162 sortList();
00163 }
00164
00165 FreeBusy::FreeBusy( const Period::List &busyPeriods )
00166 : d( new Private )
00167 {
00168 d->mBusyPeriods = busyPeriods;
00169 }
00170
00171 FreeBusy::~FreeBusy()
00172 {
00173 delete d;
00174 }
00175
00176 QByteArray FreeBusy::type() const
00177 {
00178 return "FreeBusy";
00179 }
00180
00181 void FreeBusy::setDtStart( const KDateTime &start )
00182 {
00183 IncidenceBase::setDtStart( start.toUtc() );
00184 updated();
00185 }
00186
00187 void FreeBusy::setDtEnd( const KDateTime &end )
00188 {
00189 d->mDtEnd = end;
00190 }
00191
00192 KDateTime FreeBusy::dtEnd() const
00193 {
00194 return d->mDtEnd;
00195 }
00196
00197 Period::List FreeBusy::busyPeriods() const
00198 {
00199 return d->mBusyPeriods;
00200 }
00201
00202 void FreeBusy::sortList()
00203 {
00204 qSort( d->mBusyPeriods );
00205 return;
00206 }
00207
00208 void FreeBusy::addPeriods( const Period::List &list )
00209 {
00210 d->mBusyPeriods += list;
00211 sortList();
00212 }
00213
00214 void FreeBusy::addPeriod( const KDateTime &start, const KDateTime &end )
00215 {
00216 d->mBusyPeriods.append( Period( start, end ) );
00217 sortList();
00218 }
00219
00220 void FreeBusy::addPeriod( const KDateTime &start, const Duration &duration )
00221 {
00222 d->mBusyPeriods.append( Period( start, duration ) );
00223 sortList();
00224 }
00225
00226 void FreeBusy::merge( FreeBusy *freeBusy )
00227 {
00228 if ( freeBusy->dtStart() < dtStart() ) {
00229 setDtStart( freeBusy->dtStart() );
00230 }
00231
00232 if ( freeBusy->dtEnd() > dtEnd() ) {
00233 setDtEnd( freeBusy->dtEnd() );
00234 }
00235
00236 Period::List periods = freeBusy->busyPeriods();
00237 Period::List::ConstIterator it;
00238 for ( it = periods.begin(); it != periods.end(); ++it ) {
00239 addPeriod( (*it).start(), (*it).end() );
00240 }
00241 }
00242
00243 void FreeBusy::shiftTimes( const KDateTime::Spec &oldSpec,
00244 const KDateTime::Spec &newSpec )
00245 {
00246 IncidenceBase::shiftTimes( oldSpec, newSpec );
00247 d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
00248 d->mDtEnd.setTimeSpec( newSpec );
00249 for ( int i = 0, end = d->mBusyPeriods.count(); i < end; ++end ) {
00250 d->mBusyPeriods[i].shiftTimes( oldSpec, newSpec );
00251 }
00252 }
00253
00254
00255 bool FreeBusy::Private::addLocalPeriod( FreeBusy *fb,
00256 const KDateTime &eventStart,
00257 const KDateTime &eventEnd )
00258 {
00259 KDateTime tmpStart;
00260 KDateTime tmpEnd;
00261
00262
00263
00264 KDateTime start = fb->dtStart();
00265 if ( !( ( ( start.secsTo(eventStart) >= 0 ) &&
00266 ( eventStart.secsTo(mDtEnd) >= 0 ) ) ||
00267 ( ( start.secsTo(eventEnd) >= 0 ) &&
00268 ( eventEnd.secsTo(mDtEnd) >= 0 ) ) ) ) {
00269 return false;
00270 }
00271
00272 if ( eventStart.secsTo( start ) >= 0 ) {
00273 tmpStart = start;
00274 } else {
00275 tmpStart = eventStart;
00276 }
00277
00278 if ( eventEnd.secsTo( mDtEnd ) <= 0 ) {
00279 tmpEnd = mDtEnd;
00280 } else {
00281 tmpEnd = eventEnd;
00282 }
00283
00284 Period p( tmpStart, tmpEnd );
00285 mBusyPeriods.append( p );
00286
00287 return true;
00288 }
00289