KCal Library
incidencebase.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
00035 #include "incidencebase.h"
00036 #include "calformat.h"
00037
00038 #include <kglobal.h>
00039 #include <klocale.h>
00040 #include <kdebug.h>
00041 #include <kurl.h>
00042 #include <ksystemtimezone.h>
00043
00044 #include <QtCore/QList>
00045
00046 using namespace KCal;
00047
00052
00053 class KCal::IncidenceBase::Private
00054 {
00055 public:
00056 Private()
00057 : mUpdateGroupLevel( 0 ),
00058 mUpdatedPending( false ),
00059 mAllDay( true ),
00060 mHasDuration( false )
00061 { mAttendees.setAutoDelete( true ); }
00062
00063 Private( const Private &other )
00064 : mUpdateGroupLevel( 0 ),
00065 mUpdatedPending( false ),
00066 mAllDay( true ),
00067 mHasDuration( false )
00068 {
00069 mAttendees.setAutoDelete( true );
00070 init( other );
00071 }
00072
00073 void init( const Private &other );
00074
00075 KDateTime mLastModified;
00076 KDateTime mDtStart;
00077 Person mOrganizer;
00078 QString mUid;
00079 Duration mDuration;
00080 int mUpdateGroupLevel;
00081 bool mUpdatedPending;
00082 bool mAllDay;
00083 bool mHasDuration;
00084
00085 Attendee::List mAttendees;
00086 QStringList mComments;
00087 QList<IncidenceObserver*> mObservers;
00088 };
00089
00090 void IncidenceBase::Private::init( const Private &other )
00091 {
00092 mLastModified = other.mLastModified;
00093 mDtStart = other.mDtStart;
00094 mOrganizer = other.mOrganizer;
00095 mUid = other.mUid;
00096 mDuration = other.mDuration;
00097 mAllDay = other.mAllDay;
00098 mHasDuration = other.mHasDuration;
00099 mComments = other.mComments;
00100
00101 mAttendees.clearAll();
00102 Attendee::List::ConstIterator it;
00103 for ( it = other.mAttendees.begin(); it != other.mAttendees.end(); ++it ) {
00104 mAttendees.append( new Attendee( *(*it) ) );
00105 }
00106 }
00107
00108
00109 IncidenceBase::IncidenceBase()
00110 : d( new KCal::IncidenceBase::Private )
00111 {
00112 mReadOnly = false;
00113
00114 setUid( CalFormat::createUniqueId() );
00115 }
00116
00117 IncidenceBase::IncidenceBase( const IncidenceBase &i )
00118 : CustomProperties( i ),
00119 d( new KCal::IncidenceBase::Private( *i.d ) )
00120 {
00121 mReadOnly = i.mReadOnly;
00122 }
00123
00124 IncidenceBase::~IncidenceBase()
00125 {
00126 delete d;
00127 }
00128
00129 IncidenceBase &IncidenceBase::operator=( const IncidenceBase &other )
00130 {
00131 CustomProperties::operator=( other );
00132 d->init( *other.d );
00133 mReadOnly = other.mReadOnly;
00134 return *this;
00135 }
00136
00137 bool IncidenceBase::operator==( const IncidenceBase &i2 ) const
00138 {
00139 if ( attendees().count() != i2.attendees().count() ) {
00140 return false;
00141 }
00142
00143 Attendee::List al1 = attendees();
00144 Attendee::List al2 = i2.attendees();
00145 Attendee::List::ConstIterator a1 = al1.constBegin();
00146 Attendee::List::ConstIterator a2 = al2.constBegin();
00147
00148
00149 for ( ; a1 != al1.constEnd() && a2 != al2.constEnd(); ++a1, ++a2 ) {
00150 if ( !( **a1 == **a2 ) ) {
00151 return false;
00152 }
00153 }
00154
00155 if ( !CustomProperties::operator == (i2) ) {
00156 return false;
00157 }
00158
00159 return
00160 dtStart() == i2.dtStart() &&
00161 organizer() == i2.organizer() &&
00162 uid() == i2.uid() &&
00163
00164
00165 allDay() == i2.allDay() &&
00166 duration() == i2.duration() &&
00167 hasDuration() == i2.hasDuration();
00168
00169 }
00170
00171 void IncidenceBase::setUid( const QString &uid )
00172 {
00173 d->mUid = uid;
00174 updated();
00175 }
00176
00177 QString IncidenceBase::uid() const
00178 {
00179 return d->mUid;
00180 }
00181
00182 void IncidenceBase::setLastModified( const KDateTime &lm )
00183 {
00184
00185
00186
00187
00188 KDateTime current = lm.toUtc();
00189 QTime t = current.time();
00190 t.setHMS( t.hour(), t.minute(), t.second(), 0 );
00191 current.setTime( t );
00192
00193 d->mLastModified = current;
00194 }
00195
00196 KDateTime IncidenceBase::lastModified() const
00197 {
00198 return d->mLastModified;
00199 }
00200
00201 void IncidenceBase::setOrganizer( const Person &o )
00202 {
00203
00204
00205
00206 d->mOrganizer = o;
00207
00208 updated();
00209 }
00210
00211 void IncidenceBase::setOrganizer( const QString &o )
00212 {
00213 QString mail( o );
00214 if ( mail.startsWith( "MAILTO:", Qt::CaseInsensitive ) ) {
00215 mail = mail.remove( 0, 7 );
00216 }
00217
00218
00219 const Person organizer = Person::fromFullName( mail );
00220 setOrganizer( organizer );
00221 }
00222
00223 Person IncidenceBase::organizer() const
00224 {
00225 return d->mOrganizer;
00226 }
00227
00228 void IncidenceBase::setReadOnly( bool readOnly )
00229 {
00230 mReadOnly = readOnly;
00231 }
00232
00233 void IncidenceBase::setDtStart( const KDateTime &dtStart )
00234 {
00235
00236 d->mDtStart = dtStart;
00237 d->mAllDay = dtStart.isDateOnly();
00238 updated();
00239 }
00240
00241 KDateTime IncidenceBase::dtStart() const
00242 {
00243 return d->mDtStart;
00244 }
00245
00246 QString IncidenceBase::dtStartTimeStr( bool shortfmt, const KDateTime::Spec &spec ) const
00247 {
00248 if ( spec.isValid() ) {
00249
00250 QString timeZone;
00251 if ( spec.timeZone() != KSystemTimeZones::local() ) {
00252 timeZone = ' ' + spec.timeZone().name();
00253 }
00254
00255 return KGlobal::locale()->formatTime( dtStart().toTimeSpec( spec ).time(), shortfmt )
00256 + timeZone;
00257 } else {
00258 return KGlobal::locale()->formatTime( dtStart().time(), shortfmt );
00259 }
00260 }
00261
00262 QString IncidenceBase::dtStartDateStr( bool shortfmt, const KDateTime::Spec &spec ) const
00263 {
00264 if ( spec.isValid() ) {
00265
00266 QString timeZone;
00267 if ( spec.timeZone() != KSystemTimeZones::local() ) {
00268 timeZone = ' ' + spec.timeZone().name();
00269 }
00270
00271 return KGlobal::locale()->formatDate(
00272 dtStart().toTimeSpec( spec ).date(), ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) )
00273 + timeZone;
00274 } else {
00275 return KGlobal::locale()->formatDate(
00276 dtStart().date(), ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00277 }
00278 }
00279
00280 QString IncidenceBase::dtStartStr( bool shortfmt, const KDateTime::Spec &spec ) const
00281 {
00282 if ( allDay() ) {
00283 return dtStartDateStr( shortfmt, spec );
00284 }
00285
00286 if ( spec.isValid() ) {
00287
00288 QString timeZone;
00289 if ( spec.timeZone() != KSystemTimeZones::local() ) {
00290 timeZone = ' ' + spec.timeZone().name();
00291 }
00292
00293 return KGlobal::locale()->formatDateTime(
00294 dtStart().toTimeSpec( spec ).dateTime(),
00295 ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) ) + timeZone;
00296 } else {
00297 return KGlobal::locale()->formatDateTime(
00298 dtStart().dateTime(),
00299 ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00300 }
00301 }
00302
00303 bool IncidenceBase::allDay() const
00304 {
00305 return d->mAllDay;
00306 }
00307
00308 void IncidenceBase::setAllDay( bool f )
00309 {
00310 if ( mReadOnly || f == d->mAllDay ) {
00311 return;
00312 }
00313 d->mAllDay = f;
00314 updated();
00315 }
00316
00317 void IncidenceBase::shiftTimes( const KDateTime::Spec &oldSpec,
00318 const KDateTime::Spec &newSpec )
00319 {
00320 d->mDtStart = d->mDtStart.toTimeSpec( oldSpec );
00321 d->mDtStart.setTimeSpec( newSpec );
00322 updated();
00323 }
00324
00325 void IncidenceBase::addComment( const QString &comment )
00326 {
00327 d->mComments += comment;
00328 }
00329
00330 bool IncidenceBase::removeComment( const QString &comment )
00331 {
00332 bool found = false;
00333 QStringList::Iterator i;
00334
00335 for ( i = d->mComments.begin(); !found && i != d->mComments.end(); ++i ) {
00336 if ( (*i) == comment ) {
00337 found = true;
00338 d->mComments.erase( i );
00339 }
00340 }
00341
00342 return found;
00343 }
00344
00345 void IncidenceBase::clearComments()
00346 {
00347 d->mComments.clear();
00348 }
00349
00350 QStringList IncidenceBase::comments() const
00351 {
00352 return d->mComments;
00353 }
00354
00355 void IncidenceBase::addAttendee( Attendee *a, bool doupdate )
00356 {
00357 if ( !a || mReadOnly ) {
00358 return;
00359 }
00360
00361 if ( a->name().left(7).toUpper() == "MAILTO:" ) {
00362 a->setName( a->name().remove( 0, 7 ) );
00363 }
00364
00365 d->mAttendees.append( a );
00366 if ( doupdate ) {
00367 updated();
00368 }
00369 }
00370
00371 const Attendee::List &IncidenceBase::attendees() const
00372 {
00373 return d->mAttendees;
00374 }
00375
00376 int IncidenceBase::attendeeCount() const
00377 {
00378 return d->mAttendees.count();
00379 }
00380
00381 void IncidenceBase::clearAttendees()
00382 {
00383 if ( mReadOnly ) {
00384 return;
00385 }
00386 qDeleteAll( d->mAttendees );
00387 d->mAttendees.clear();
00388 }
00389
00390 Attendee *IncidenceBase::attendeeByMail( const QString &email ) const
00391 {
00392 Attendee::List::ConstIterator it;
00393 for ( it = d->mAttendees.constBegin(); it != d->mAttendees.constEnd(); ++it ) {
00394 if ( (*it)->email() == email ) {
00395 return *it;
00396 }
00397 }
00398
00399 return 0;
00400 }
00401
00402 Attendee *IncidenceBase::attendeeByMails( const QStringList &emails,
00403 const QString &email ) const
00404 {
00405 QStringList mails = emails;
00406 if ( !email.isEmpty() ) {
00407 mails.append( email );
00408 }
00409
00410 Attendee::List::ConstIterator itA;
00411 for ( itA = d->mAttendees.constBegin(); itA != d->mAttendees.constEnd(); ++itA ) {
00412 for ( QStringList::const_iterator it = mails.constBegin(); it != mails.constEnd(); ++it ) {
00413 if ( (*itA)->email() == (*it) ) {
00414 return *itA;
00415 }
00416 }
00417 }
00418
00419 return 0;
00420 }
00421
00422 Attendee *IncidenceBase::attendeeByUid( const QString &uid ) const
00423 {
00424 Attendee::List::ConstIterator it;
00425 for ( it = d->mAttendees.constBegin(); it != d->mAttendees.constEnd(); ++it ) {
00426 if ( (*it)->uid() == uid ) {
00427 return *it;
00428 }
00429 }
00430
00431 return 0;
00432 }
00433
00434 void IncidenceBase::setDuration( const Duration &duration )
00435 {
00436 d->mDuration = duration;
00437 setHasDuration( true );
00438 updated();
00439 }
00440
00441 Duration IncidenceBase::duration() const
00442 {
00443 return d->mDuration;
00444 }
00445
00446 void IncidenceBase::setHasDuration( bool hasDuration )
00447 {
00448 d->mHasDuration = hasDuration;
00449 }
00450
00451 bool IncidenceBase::hasDuration() const
00452 {
00453 return d->mHasDuration;
00454 }
00455
00456 void IncidenceBase::registerObserver( IncidenceBase::IncidenceObserver *observer )
00457 {
00458 if ( !d->mObservers.contains( observer ) ) {
00459 d->mObservers.append( observer );
00460 }
00461 }
00462
00463 void IncidenceBase::unRegisterObserver( IncidenceBase::IncidenceObserver *observer )
00464 {
00465 d->mObservers.removeAll( observer );
00466 }
00467
00468 void IncidenceBase::updated()
00469 {
00470 if ( d->mUpdateGroupLevel ) {
00471 d->mUpdatedPending = true;
00472 } else {
00473 foreach ( IncidenceObserver *o, d->mObservers ) {
00474 o->incidenceUpdated( this );
00475 }
00476 }
00477 }
00478
00479 void IncidenceBase::startUpdates()
00480 {
00481 ++d->mUpdateGroupLevel;
00482 }
00483
00484 void IncidenceBase::endUpdates()
00485 {
00486 if ( d->mUpdateGroupLevel > 0 ) {
00487 if ( --d->mUpdateGroupLevel == 0 && d->mUpdatedPending ) {
00488 d->mUpdatedPending = false;
00489 updated();
00490 }
00491 }
00492 }
00493
00494 void IncidenceBase::customPropertyUpdated()
00495 {
00496 updated();
00497 }
00498
00499 KUrl IncidenceBase::uri() const
00500 {
00501 return KUrl( QString( "urn:x-ical:" ) + uid() );
00502 }
00503
00504 bool IncidenceBase::Visitor::visit( Event *event )
00505 {
00506 Q_UNUSED( event );
00507 return false;
00508 }
00509
00510 bool IncidenceBase::Visitor::visit( Todo *todo )
00511 {
00512 Q_UNUSED( todo );
00513 return false;
00514 }
00515
00516 bool IncidenceBase::Visitor::visit( Journal *journal )
00517 {
00518 Q_UNUSED( journal );
00519 return false;
00520 }
00521
00522 bool IncidenceBase::Visitor::visit( FreeBusy *freebusy )
00523 {
00524 Q_UNUSED( freebusy );
00525 return false;
00526 }