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.begin(); it != eventList.end(); ++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.begin(); it != periods.end(); ++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 IncidenceBase::shiftTimes( oldSpec, newSpec );
00299 d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
00300 d->mDtEnd.setTimeSpec( newSpec );
00301 for ( int i = 0, end = d->mBusyPeriods.count(); i < end; ++end ) {
00302 d->mBusyPeriods[i].shiftTimes( oldSpec, newSpec );
00303 }
00304 }
00305
00306 FreeBusy &FreeBusy::operator=( const FreeBusy &other )
00307 {
00308 IncidenceBase::operator=( other );
00309 d->init( *other.d );
00310 return *this;
00311 }
00312
00313 bool FreeBusy::operator==( const FreeBusy &freebusy ) const
00314 {
00315 return
00316 static_cast<const IncidenceBase &>( *this ) == static_cast<const IncidenceBase &>( freebusy ) &&
00317 dtEnd() == freebusy.dtEnd() &&
00318 d->mCalendar == freebusy.d->mCalendar &&
00319 d->mBusyPeriods == freebusy.d->mBusyPeriods;
00320 }
00321
00322
00323 bool FreeBusy::Private::addLocalPeriod( FreeBusy *fb,
00324 const KDateTime &eventStart,
00325 const KDateTime &eventEnd )
00326 {
00327 KDateTime tmpStart;
00328 KDateTime tmpEnd;
00329
00330
00331
00332 KDateTime start = fb->dtStart();
00333 if ( !( ( ( start.secsTo(eventStart) >= 0 ) &&
00334 ( eventStart.secsTo(mDtEnd) >= 0 ) ) ||
00335 ( ( start.secsTo(eventEnd) >= 0 ) &&
00336 ( eventEnd.secsTo(mDtEnd) >= 0 ) ) ) ) {
00337 return false;
00338 }
00339
00340 if ( eventStart.secsTo( start ) >= 0 ) {
00341 tmpStart = start;
00342 } else {
00343 tmpStart = eventStart;
00344 }
00345
00346 if ( eventEnd.secsTo( mDtEnd ) <= 0 ) {
00347 tmpEnd = mDtEnd;
00348 } else {
00349 tmpEnd = eventEnd;
00350 }
00351
00352 FreeBusyPeriod p( tmpStart, tmpEnd );
00353 mBusyPeriods.append( p );
00354
00355 return true;
00356 }
00357