libkcal

incidencebase.cpp

00001 /*
00002     This file is part of libkcal.
00003 
00004     Copyright (c) 2001,2004 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include <kglobal.h>
00024 #include <klocale.h>
00025 #include <kdebug.h>
00026 
00027 #include "calformat.h"
00028 
00029 #include "incidencebase.h"
00030 
00031 using namespace KCal;
00032 
00033 IncidenceBase::IncidenceBase()
00034   : mReadOnly( false ), mFloats( true ), mDuration( 0 ), mHasDuration( false ),
00035     mPilotId( 0 ), mSyncStatus( SYNCMOD ), mUpdateGroupLevel( 0 )
00036 {
00037   setUid( CalFormat::createUniqueId() );
00038 
00039   mAttendees.setAutoDelete( true );
00040   resetDirtyFields();
00041 }
00042 
00043 IncidenceBase::IncidenceBase(const IncidenceBase &i) :
00044   CustomProperties( i )
00045 {
00046   mUpdateGroupLevel = 0;
00047   mReadOnly = i.mReadOnly;
00048   mDtStart = i.mDtStart;
00049   mDuration = i.mDuration;
00050   mHasDuration = i.mHasDuration;
00051   mOrganizer = i.mOrganizer;
00052   mUid = i.mUid;
00053   Attendee::List attendees = i.attendees();
00054   Attendee::List::ConstIterator it;
00055   for( it = attendees.begin(); it != attendees.end(); ++it ) {
00056     mAttendees.append( new Attendee( *(*it) ) );
00057   }
00058   mFloats = i.mFloats;
00059   mLastModified = i.mLastModified;
00060   mPilotId = i.mPilotId;
00061   mSyncStatus = i.mSyncStatus;
00062   mComments = i.mComments;
00063 
00064   // The copied object is a new one, so it isn't observed by the observer
00065   // of the original object.
00066   mObservers.clear();
00067 
00068   mAttendees.setAutoDelete( true );
00069   resetDirtyFields();
00070 }
00071 
00072 IncidenceBase::~IncidenceBase()
00073 {
00074 }
00075 
00076 IncidenceBase& IncidenceBase::operator=( const IncidenceBase& i )
00077 {
00078   CustomProperties::operator=( i );
00079   mReadOnly = i.mReadOnly;
00080   mDtStart = i.mDtStart;
00081   mDuration = i.mDuration;
00082   mHasDuration = i.mHasDuration;
00083   mOrganizer = i.mOrganizer;
00084   mUid = i.mUid;
00085   mAttendees.clear();
00086   Attendee::List attendees = i.attendees();
00087   Attendee::List::ConstIterator it;
00088   for( it = attendees.begin(); it != attendees.end(); ++it ) {
00089     mAttendees.append( new Attendee( *(*it) ) );
00090   }
00091   mFloats = i.mFloats;
00092   mLastModified = i.mLastModified;
00093   mPilotId = i.mPilotId;
00094   mSyncStatus = i.mSyncStatus;
00095   mComments = i.mComments;
00096 
00097   mDirtyFields.clear();
00098   mDirtyFields.insert( FieldUnknown, true );
00099 
00100   return *this;
00101 }
00102 
00103 bool IncidenceBase::operator==( const IncidenceBase& i2 ) const
00104 {
00105   if( attendees().count() != i2.attendees().count() ) {
00106       return false; // no need to check further
00107   }
00108 
00109   Attendee::List al1 = attendees();
00110   Attendee::List al2 = i2.attendees();
00111   Attendee::List::ConstIterator a1 = al1.begin();
00112   Attendee::List::ConstIterator a2 = al2.begin();
00113   for( ; a1 != al1.end() && a2 != al2.end(); ++a1, ++a2 ) {
00114     if( **a1 == **a2 )
00115         continue;
00116     else {
00117         return false;
00118     }
00119   }
00120 
00121   if ( !CustomProperties::operator==(i2) )
00122     return false;
00123 
00124   // not using one big expression to make it gdb friendly
00125   const bool a = dtStart() == i2.dtStart();
00126   const bool b = organizer() == i2.organizer();
00127   const bool c = uid() == i2.uid();
00128   const bool d = doesFloat() == i2.doesFloat();
00129   const bool e = duration() == i2.duration();
00130   const bool f = hasDuration() == i2.hasDuration();
00131   const bool g = pilotId() == i2.pilotId();
00132   const bool h = syncStatus() == i2.syncStatus();
00133   // no need to compare mObserver and mLastModified
00134 
00135   return a && b && c && d && e && f && g && h;
00136 }
00137 
00138 void IncidenceBase::setUid(const QString &uid)
00139 {
00140   mUid = uid;
00141   updated();
00142 }
00143 
00144 QString IncidenceBase::uid() const
00145 {
00146   return mUid;
00147 }
00148 
00149 void IncidenceBase::setLastModified(const QDateTime &lm)
00150 {
00151   // DON'T! updated() because we call this from
00152   // Calendar::updateEvent().
00153 
00154   // Remove milliseconds part.
00155   QDateTime current = lm;
00156   QTime t = current.time();
00157   t.setHMS( t.hour(), t.minute(), t.second(), 0 );
00158   current.setTime( t );
00159 
00160   mLastModified = current;
00161 }
00162 
00163 QDateTime IncidenceBase::lastModified() const
00164 {
00165   return mLastModified;
00166 }
00167 
00168 void IncidenceBase::setOrganizer( const Person &o )
00169 {
00170   // we don't check for readonly here, because it is
00171   // possible that by setting the organizer we are changing
00172   // the event's readonly status...
00173   mOrganizer = o;
00174 
00175   updated();
00176 }
00177 
00178 void IncidenceBase::setOrganizer(const QString &o)
00179 {
00180   QString mail( o );
00181   if ( mail.startsWith("MAILTO:", false) )
00182     mail = mail.remove( 0, 7 );
00183   // split the string into full name plus email.
00184   Person organizer( mail );
00185   setOrganizer( organizer );
00186 }
00187 
00188 Person IncidenceBase::organizer() const
00189 {
00190   return mOrganizer;
00191 }
00192 
00193 void IncidenceBase::setReadOnly( bool readOnly )
00194 {
00195   mReadOnly = readOnly;
00196 }
00197 
00198 void IncidenceBase::setDtStart(const QDateTime &dtStart)
00199 {
00200 //  if (mReadOnly) return;
00201   mDtStart = dtStart;
00202   updated();
00203 }
00204 
00205 QDateTime IncidenceBase::dtStart() const
00206 {
00207   return mDtStart;
00208 }
00209 
00210 QString IncidenceBase::dtStartTimeStr() const
00211 {
00212   return KGlobal::locale()->formatTime(dtStart().time());
00213 }
00214 
00215 QString IncidenceBase::dtStartDateStr(bool shortfmt) const
00216 {
00217   return KGlobal::locale()->formatDate(dtStart().date(),shortfmt);
00218 }
00219 
00220 QString IncidenceBase::dtStartStr() const
00221 {
00222   return KGlobal::locale()->formatDateTime(dtStart());
00223 }
00224 
00225 
00226 bool IncidenceBase::doesFloat() const
00227 {
00228   return mFloats;
00229 }
00230 
00231 void IncidenceBase::setFloats(bool f)
00232 {
00233   if (mReadOnly) return;
00234   mFloats = f;
00235   updated();
00236 }
00237 
00238 
00239 void IncidenceBase::addComment(const QString& comment)
00240 {
00241   setFieldDirty( FieldComment );
00242   mComments += comment;
00243 }
00244 
00245 bool IncidenceBase::removeComment( const QString& comment)
00246 {
00247   setFieldDirty( FieldComment );
00248   bool found = false;
00249   QStringList::Iterator i;
00250 
00251   for ( i = mComments.begin(); !found && i != mComments.end(); ++i ) {
00252     if ( (*i) == comment ) {
00253       found = true;
00254       mComments.remove(i);
00255     }
00256   }
00257 
00258   return found;
00259 }
00260 
00261 void IncidenceBase::clearComments()
00262 {
00263   setFieldDirty( FieldComment );
00264   mComments.clear();
00265 }
00266 
00267 QStringList IncidenceBase::comments() const
00268 {
00269   return mComments;
00270 }
00271 
00272 
00273 void IncidenceBase::addAttendee(Attendee *a, bool doupdate)
00274 {
00275 //  kdDebug(5800) << "IncidenceBase::addAttendee()" << endl;
00276   if (mReadOnly) return;
00277 //  kdDebug(5800) << "IncidenceBase::addAttendee() weiter" << endl;
00278   if (a->name().left(7).upper() == "MAILTO:")
00279     a->setName(a->name().remove(0,7));
00280 
00281   setFieldDirty( FieldAttendees );
00282   mAttendees.append(a);
00283   if (doupdate) updated();
00284 }
00285 
00286 #if 0
00287 void IncidenceBase::removeAttendee(Attendee *a)
00288 {
00289   if (mReadOnly) return;
00290   mAttendees.removeRef(a);
00291   updated();
00292 }
00293 
00294 void IncidenceBase::removeAttendee(const char *n)
00295 {
00296   Attendee *a;
00297 
00298   if (mReadOnly) return;
00299   for (a = mAttendees.first(); a; a = mAttendees.next())
00300     if (a->getName() == n) {
00301       mAttendees.remove();
00302       break;
00303     }
00304 }
00305 #endif
00306 
00307 void IncidenceBase::clearAttendees()
00308 {
00309   if (mReadOnly) return;
00310   setFieldDirty( FieldAttendees );
00311   mAttendees.clear();
00312 }
00313 
00314 Attendee *IncidenceBase::attendeeByMail( const QString &email ) const
00315 {
00316   Attendee::List::ConstIterator it;
00317   for( it = mAttendees.begin(); it != mAttendees.end(); ++it ) {
00318     if ( (*it)->email() == email ) return *it;
00319   }
00320 
00321   return 0;
00322 }
00323 
00324 Attendee *IncidenceBase::attendeeByMails( const QStringList &emails,
00325                                           const QString &email) const
00326 {
00327   QStringList mails = emails;
00328   if ( !email.isEmpty() ) mails.append( email );
00329 
00330   Attendee::List::ConstIterator itA;
00331   for( itA = mAttendees.begin(); itA != mAttendees.end(); ++itA ) {
00332     for ( QStringList::Iterator it = mails.begin(); it != mails.end(); ++it ) {
00333       if ( (*itA)->email() == (*it) ) return *itA;
00334     }
00335   }
00336 
00337   return 0;
00338 }
00339 
00340 Attendee *IncidenceBase::attendeeByUid( const QString &uid ) const
00341 {
00342   Attendee::List::ConstIterator it;
00343   for( it = mAttendees.begin(); it != mAttendees.end(); ++it ) {
00344     if ( (*it)->uid() == uid ) return *it;
00345   }
00346 
00347   return 0;
00348 }
00349 
00350 
00351 void IncidenceBase::setDuration(int seconds)
00352 {
00353   mDuration = seconds;
00354   setHasDuration(true);
00355   updated();
00356 }
00357 
00358 int IncidenceBase::duration() const
00359 {
00360   return mDuration;
00361 }
00362 
00363 void IncidenceBase::setHasDuration(bool hasDuration)
00364 {
00365   mHasDuration = hasDuration;
00366 }
00367 
00368 bool IncidenceBase::hasDuration() const
00369 {
00370   return mHasDuration;
00371 }
00372 
00373 void IncidenceBase::setSyncStatus(int stat)
00374 {
00375   if (mReadOnly) return;
00376   if ( mSyncStatus == stat ) return;
00377   mSyncStatus = stat;
00378   updatedSilent();
00379 }
00380 void IncidenceBase::setSyncStatusSilent(int stat)
00381 {
00382   if (mReadOnly) return;
00383   mSyncStatus = stat;
00384 }
00385 
00386 int IncidenceBase::syncStatus() const
00387 {
00388   return mSyncStatus;
00389 }
00390 
00391 void IncidenceBase::setPilotId( unsigned long id )
00392 {
00393   if (mReadOnly) return;
00394   if ( mPilotId == id) return;
00395   mPilotId = id;
00396   updatedSilent();
00397 }
00398 
00399 unsigned long IncidenceBase::pilotId() const
00400 {
00401   return mPilotId;
00402 }
00403 
00404 void IncidenceBase::registerObserver( IncidenceBase::Observer *observer )
00405 {
00406   if( !mObservers.contains( observer ) ) mObservers.append( observer );
00407 }
00408 
00409 void IncidenceBase::unRegisterObserver( IncidenceBase::Observer *observer )
00410 {
00411   mObservers.remove( observer );
00412 }
00413 
00414 void IncidenceBase::updated()
00415 {
00416   if ( mUpdateGroupLevel == 0 ) {
00417     QPtrListIterator<Observer> it(mObservers);
00418     while( it.current() ) {
00419       Observer *o = it.current();
00420       ++it;
00421       if ( o ) {
00422         o->incidenceUpdated( this );
00423       }
00424     }
00425   }
00426 }
00427 
00428 void IncidenceBase::customPropertyUpdated()
00429 {
00430   updated();
00431 }
00432 
00433 void IncidenceBase::updatedSilent()
00434 {
00435   QPtrListIterator<Observer> it(mObservers);
00436   while( it.current() ) {
00437     Observer *o = it.current();
00438     ++it;
00439     o->incidenceUpdatedSilent( this );
00440   }
00441 }
00442 
00443 void IncidenceBase::startUpdates()
00444 {
00445   ++mUpdateGroupLevel;
00446 }
00447 
00448 void IncidenceBase::endUpdates()
00449 {
00450   if ( mUpdateGroupLevel > 0 ) {
00451     if ( --mUpdateGroupLevel == 0 ) {
00452       updated();
00453     }
00454   } else {
00455     kdWarning() << "startUpdates() not called() before endUpdates()";
00456   }
00457 }
00458 
00459 void IncidenceBase::cancelUpdates()
00460 {
00461   if ( mUpdateGroupLevel != 0 ) {
00462     mUpdateGroupLevel = 0;
00463   } else {
00464     kdWarning() << "startUpdates() not called() before cancelUpdates()";
00465   }
00466 }
00467 
00468 QPtrList<IncidenceBase::Observer> IncidenceBase::observers() const
00469 {
00470   return mObservers;
00471 }
00472 
00473 
00474 QMap<IncidenceBase::Field,bool> IncidenceBase::dirtyFields() const
00475 {
00476   return mDirtyFields;
00477 }
00478 
00479 void IncidenceBase::resetDirtyFields()
00480 {
00481   mDirtyFields.clear();
00482 }
00483 
00484 void IncidenceBase::setFieldDirty( IncidenceBase::Field field )
00485 {
00486   mDirtyFields.insert( field, true );
00487 }
KDE Home | KDE Accessibility Home | Description of Access Keys