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 KCal::FreeBusy::Private
00046 {
00047 public:
00048 Private()
00049 : mCalendar( 0 )
00050 {}
00051
00052 Private( const KCal::FreeBusy::Private &other )
00053 { init( other ); }
00054
00055 Private( const FreeBusyPeriod::List &busyPeriods )
00056 : mBusyPeriods( busyPeriods ),
00057 mCalendar( 0 )
00058 {}
00059
00060 void init( const KCal::FreeBusy::Private &other );
00061
00062 KDateTime mDtEnd;
00063 FreeBusyPeriod::List mBusyPeriods;
00064 Calendar *mCalendar;
00065
00066
00067 bool addLocalPeriod( FreeBusy *fb, const KDateTime &start, const KDateTime &end );
00068 };
00069
00070 void KCal::FreeBusy::Private::init( const KCal::FreeBusy::Private &other )
00071 {
00072 mDtEnd = other.mDtEnd;
00073 mBusyPeriods = other.mBusyPeriods;
00074 mCalendar = other.mCalendar;
00075 }
00076
00077
00078
00079 FreeBusy::FreeBusy()
00080 : d( new KCal::FreeBusy::Private() )
00081 {
00082 }
00083
00084 FreeBusy::FreeBusy( const FreeBusy &other )
00085 : IncidenceBase( other ),
00086 d( new KCal::FreeBusy::Private( *other.d ) )
00087 {
00088 }
00089
00090 FreeBusy::FreeBusy( const KDateTime &start, const KDateTime &end )
00091 : d( new KCal::FreeBusy::Private() )
00092 {
00093 setDtStart( start );
00094 setDtEnd( end );
00095 }
00096
00097 FreeBusy::FreeBusy( Calendar *calendar, const KDateTime &start, const KDateTime &end )
00098 : d( new KCal::FreeBusy::Private() )
00099 {
00100 kDebug();
00101 d->mCalendar = calendar;
00102
00103 setDtStart( start );
00104 setDtEnd( end );
00105
00106
00107 Event::List eventList = d->mCalendar->rawEvents( start.date(), end.date() );
00108
00109 int extraDays, i, x, duration;
00110 duration = start.daysTo( end );
00111 QDate day;
00112 KDateTime tmpStart;
00113 KDateTime tmpEnd;
00114
00115
00116 Event::List::ConstIterator it;
00117 for ( it = eventList.constBegin(); it != eventList.constEnd(); ++it ) {
00118 Event *event = *it;
00119
00120
00121
00122
00123
00124 Event *allDayEvent = 0;
00125 if ( event->allDay() ) {
00126
00127 kDebug() << "All-day event";
00128 allDayEvent = new Event( *event );
00129
00130
00131 KDateTime st = allDayEvent->dtStart();
00132 st.setTime( QTime( 0, 0 ) );
00133 KDateTime nd = allDayEvent->dtEnd();
00134 nd.setTime( QTime( 23, 59, 59, 999 ) );
00135 allDayEvent->setAllDay( false );
00136 allDayEvent->setDtStart( st );
00137 allDayEvent->setDtEnd( nd );
00138
00139 kDebug() << "Use:" << st.toString() << "to" << nd.toString();
00140
00141 event = allDayEvent;
00142 }
00143
00144
00145
00146
00147
00148 if ( event->transparency() == Event::Transparent ) {
00149 continue;
00150 }
00151
00152 for ( i = 0; i <= duration; ++i ) {
00153 day = start.addDays(i).date();
00154 tmpStart.setDate( day );
00155 tmpEnd.setDate( day );
00156
00157 if ( event->recurs() ) {
00158 if ( event->isMultiDay() ) {
00159
00160
00161 extraDays = event->dtStart().daysTo( event->dtEnd() );
00162 for ( x = 0; x <= extraDays; ++x ) {
00163 if ( event->recursOn( day.addDays(-x), start.timeSpec() ) ) {
00164 tmpStart.setDate( day.addDays(-x) );
00165 tmpStart.setTime( event->dtStart().time() );
00166 tmpEnd = event->duration().end( tmpStart );
00167
00168 d->addLocalPeriod( this, tmpStart, tmpEnd );
00169 break;
00170 }
00171 }
00172 } else {
00173 if ( event->recursOn( day, start.timeSpec() ) ) {
00174 tmpStart.setTime( event->dtStart().time() );
00175 tmpEnd.setTime( event->dtEnd().time() );
00176
00177 d->addLocalPeriod ( this, tmpStart, tmpEnd );
00178 }
00179 }
00180 }
00181
00182 }
00183
00184 d->addLocalPeriod( this, event->dtStart(), event->dtEnd() );
00185
00186
00187 delete allDayEvent;
00188 }
00189
00190 sortList();
00191 }
00192
00193 FreeBusy::FreeBusy( const Period::List &busyPeriods )
00194 : d( new KCal::FreeBusy::Private() )
00195 {
00196 addPeriods(busyPeriods);
00197 }
00198
00199 FreeBusy::FreeBusy( const FreeBusyPeriod::List &busyPeriods )
00200 : d( new KCal::FreeBusy::Private( busyPeriods ) )
00201 {
00202 }
00203
00204 FreeBusy::~FreeBusy()
00205 {
00206 delete d;
00207 }
00208
00209 QByteArray FreeBusy::type() const
00210 {
00211 return "FreeBusy";
00212 }
00213
00214 void FreeBusy::setDtStart( const KDateTime &start )
00215 {
00216 IncidenceBase::setDtStart( start.toUtc() );
00217 updated();
00218 }
00219
00220 void FreeBusy::setDtEnd( const KDateTime &end )
00221 {
00222 d->mDtEnd = end;
00223 }
00224
00225 KDateTime FreeBusy::dtEnd() const
00226 {
00227 return d->mDtEnd;
00228 }
00229
00230 Period::List FreeBusy::busyPeriods() const
00231 {
00232 Period::List res;
00233
00234 foreach ( const FreeBusyPeriod &p, d->mBusyPeriods ) {
00235 res << p;
00236 }
00237
00238 return res;
00239 }
00240
00241 FreeBusyPeriod::List FreeBusy::fullBusyPeriods() const
00242 {
00243 return d->mBusyPeriods;
00244 }
00245
00246 void FreeBusy::sortList()
00247 {
00248 qSort( d->mBusyPeriods );
00249 return;
00250 }
00251
00252 void FreeBusy::addPeriods( const Period::List &list )
00253 {
00254 foreach ( const Period &p, list ) {
00255 d->mBusyPeriods << FreeBusyPeriod( p );
00256 }
00257 sortList();
00258 }
00259
00260 void FreeBusy::addPeriods( const FreeBusyPeriod::List &list )
00261 {
00262 d->mBusyPeriods += list;
00263 sortList();
00264 }
00265
00266 void FreeBusy::addPeriod( const KDateTime &start, const KDateTime &end )
00267 {
00268 d->mBusyPeriods.append( FreeBusyPeriod( start, end ) );
00269 sortList();
00270 }
00271
00272 void FreeBusy::addPeriod( const KDateTime &start, const Duration &duration )
00273 {
00274 d->mBusyPeriods.append( FreeBusyPeriod( start, duration ) );
00275 sortList();
00276 }
00277
00278 void FreeBusy::merge( FreeBusy *freeBusy )
00279 {
00280 if ( freeBusy->dtStart() < dtStart() ) {
00281 setDtStart( freeBusy->dtStart() );
00282 }
00283
00284 if ( freeBusy->dtEnd() > dtEnd() ) {
00285 setDtEnd( freeBusy->dtEnd() );
00286 }
00287
00288 Period::List periods = freeBusy->busyPeriods();
00289 Period::List::ConstIterator it;
00290 for ( it = periods.constBegin(); it != periods.constEnd(); ++it ) {
00291 addPeriod( (*it).start(), (*it).end() );
00292 }
00293 }
00294
00295 void FreeBusy::shiftTimes( const KDateTime::Spec &oldSpec,
00296 const KDateTime::Spec &newSpec )
00297 {
00298 if ( oldSpec.isValid() && newSpec.isValid() && oldSpec != newSpec ) {
00299 IncidenceBase::shiftTimes( oldSpec, newSpec );
00300 d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
00301 d->mDtEnd.setTimeSpec( newSpec );
00302 foreach ( FreeBusyPeriod p, d->mBusyPeriods ) {
00303 p.shiftTimes( oldSpec, newSpec );
00304 }
00305 }
00306 }
00307
00308 FreeBusy &FreeBusy::operator=( const FreeBusy &other )
00309 {
00310 IncidenceBase::operator=( other );
00311 d->init( *other.d );
00312 return *this;
00313 }
00314
00315 bool FreeBusy::operator==( const FreeBusy &freebusy ) const
00316 {
00317 return
00318 static_cast<const IncidenceBase &>( *this ) == static_cast<const IncidenceBase &>( freebusy ) &&
00319 dtEnd() == freebusy.dtEnd() &&
00320 d->mCalendar == freebusy.d->mCalendar &&
00321 d->mBusyPeriods == freebusy.d->mBusyPeriods;
00322 }
00323
00324
00325 bool FreeBusy::Private::addLocalPeriod( FreeBusy *fb,
00326 const KDateTime &eventStart,
00327 const KDateTime &eventEnd )
00328 {
00329 KDateTime tmpStart;
00330 KDateTime tmpEnd;
00331
00332
00333
00334 KDateTime start = fb->dtStart();
00335 if ( !( ( ( start.secsTo(eventStart) >= 0 ) &&
00336 ( eventStart.secsTo(mDtEnd) >= 0 ) ) ||
00337 ( ( start.secsTo(eventEnd) >= 0 ) &&
00338 ( eventEnd.secsTo(mDtEnd) >= 0 ) ) ) ) {
00339 return false;
00340 }
00341
00342 if ( eventStart.secsTo( start ) >= 0 ) {
00343 tmpStart = start;
00344 } else {
00345 tmpStart = eventStart;
00346 }
00347
00348 if ( eventEnd.secsTo( mDtEnd ) <= 0 ) {
00349 tmpEnd = mDtEnd;
00350 } else {
00351 tmpEnd = eventEnd;
00352 }
00353
00354 FreeBusyPeriod p( tmpStart, tmpEnd );
00355 mBusyPeriods.append( p );
00356
00357 return true;
00358 }
00359