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