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