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   return ( dtStart() == i2.dtStart() &&
00125            organizer() == i2.organizer() &&
00126            uid() == i2.uid() &&
00127            // Don't compare lastModified, otherwise the operator is not
00128            // of much use. We are not comparing for identity, after all.
00129            doesFloat() == i2.doesFloat() &&
00130            duration() == i2.duration() &&
00131            hasDuration() == i2.hasDuration() &&
00132            pilotId() == i2.pilotId() &&
00133            syncStatus() == i2.syncStatus() );
00134   // no need to compare mObserver
00135 }
00136 
00137 void IncidenceBase::setUid(const QString &uid)
00138 {
00139   mUid = uid;
00140   updated();
00141 }
00142 
00143 QString IncidenceBase::uid() const
00144 {
00145   return mUid;
00146 }
00147 
00148 void IncidenceBase::setLastModified(const QDateTime &lm)
00149 {
00150   // DON'T! updated() because we call this from
00151   // Calendar::updateEvent().
00152 
00153   // Remove milliseconds part.
00154   QDateTime current = lm;
00155   QTime t = current.time();
00156   t.setHMS( t.hour(), t.minute(), t.second(), 0 );
00157   current.setTime( t );
00158 
00159   mLastModified = current;
00160 }
00161 
00162 QDateTime IncidenceBase::lastModified() const
00163 {
00164   return mLastModified;
00165 }
00166 
00167 void IncidenceBase::setOrganizer( const Person &o )
00168 {
00169   // we don't check for readonly here, because it is
00170   // possible that by setting the organizer we are changing
00171   // the event's readonly status...
00172   mOrganizer = o;
00173 
00174   updated();
00175 }
00176 
00177 void IncidenceBase::setOrganizer(const QString &o)
00178 {
00179   QString mail( o );
00180   if ( mail.startsWith("MAILTO:", false) )
00181     mail = mail.remove( 0, 7 );
00182   // split the string into full name plus email.
00183   Person organizer( mail );
00184   setOrganizer( organizer );
00185 }
00186 
00187 Person IncidenceBase::organizer() const
00188 {
00189   return mOrganizer;
00190 }
00191 
00192 void IncidenceBase::setReadOnly( bool readOnly )
00193 {
00194   mReadOnly = readOnly;
00195 }
00196 
00197 void IncidenceBase::setDtStart(const QDateTime &dtStart)
00198 {
00199 //  if (mReadOnly) return;
00200   mDtStart = dtStart;
00201   updated();
00202 }
00203 
00204 QDateTime IncidenceBase::dtStart() const
00205 {
00206   return mDtStart;
00207 }
00208 
00209 QString IncidenceBase::dtStartTimeStr() const
00210 {
00211   return KGlobal::locale()->formatTime(dtStart().time());
00212 }
00213 
00214 QString IncidenceBase::dtStartDateStr(bool shortfmt) const
00215 {
00216   return KGlobal::locale()->formatDate(dtStart().date(),shortfmt);
00217 }
00218 
00219 QString IncidenceBase::dtStartStr() const
00220 {
00221   return KGlobal::locale()->formatDateTime(dtStart());
00222 }
00223 
00224 
00225 bool IncidenceBase::doesFloat() const
00226 {
00227   return mFloats;
00228 }
00229 
00230 void IncidenceBase::setFloats(bool f)
00231 {
00232   if (mReadOnly) return;
00233   mFloats = f;
00234   updated();
00235 }
00236 
00237 
00238 void IncidenceBase::addComment(const QString& comment)
00239 {
00240   setFieldDirty( FieldComment );
00241   mComments += comment;
00242 }
00243 
00244 bool IncidenceBase::removeComment( const QString& comment)
00245 {
00246   setFieldDirty( FieldComment );
00247   bool found = false;
00248   QStringList::Iterator i;
00249 
00250   for ( i = mComments.begin(); !found && i != mComments.end(); ++i ) {
00251     if ( (*i) == comment ) {
00252       found = true;
00253       mComments.remove(i);
00254     }
00255   }
00256 
00257   return found;
00258 }
00259 
00260 void IncidenceBase::clearComments()
00261 {
00262   setFieldDirty( FieldComment );
00263   mComments.clear();
00264 }
00265 
00266 QStringList IncidenceBase::comments() const
00267 {
00268   return mComments;
00269 }
00270 
00271 
00272 void IncidenceBase::addAttendee(Attendee *a, bool doupdate)
00273 {
00274 //  kdDebug(5800) << "IncidenceBase::addAttendee()" << endl;
00275   if (mReadOnly) return;
00276 //  kdDebug(5800) << "IncidenceBase::addAttendee() weiter" << endl;
00277   if (a->name().left(7).upper() == "MAILTO:")
00278     a->setName(a->name().remove(0,7));
00279 
00280   setFieldDirty( FieldAttendees );
00281   mAttendees.append(a);
00282   if (doupdate) updated();
00283 }
00284 
00285 #if 0
00286 void IncidenceBase::removeAttendee(Attendee *a)
00287 {
00288   if (mReadOnly) return;
00289   mAttendees.removeRef(a);
00290   updated();
00291 }
00292 
00293 void IncidenceBase::removeAttendee(const char *n)
00294 {
00295   Attendee *a;
00296 
00297   if (mReadOnly) return;
00298   for (a = mAttendees.first(); a; a = mAttendees.next())
00299     if (a->getName() == n) {
00300       mAttendees.remove();
00301       break;
00302     }
00303 }
00304 #endif
00305 
00306 void IncidenceBase::clearAttendees()
00307 {
00308   if (mReadOnly) return;
00309   setFieldDirty( FieldAttendees );
00310   mAttendees.clear();
00311 }
00312 
00313 Attendee *IncidenceBase::attendeeByMail( const QString &email ) const
00314 {
00315   Attendee::List::ConstIterator it;
00316   for( it = mAttendees.begin(); it != mAttendees.end(); ++it ) {
00317     if ( (*it)->email() == email ) return *it;
00318   }
00319 
00320   return 0;
00321 }
00322 
00323 Attendee *IncidenceBase::attendeeByMails( const QStringList &emails,
00324                                           const QString &email) const
00325 {
00326   QStringList mails = emails;
00327   if ( !email.isEmpty() ) mails.append( email );
00328 
00329   Attendee::List::ConstIterator itA;
00330   for( itA = mAttendees.begin(); itA != mAttendees.end(); ++itA ) {
00331     for ( QStringList::Iterator it = mails.begin(); it != mails.end(); ++it ) {
00332       if ( (*itA)->email() == (*it) ) return *itA;
00333     }
00334   }
00335 
00336   return 0;
00337 }
00338 
00339 Attendee *IncidenceBase::attendeeByUid( const QString &uid ) const
00340 {
00341   Attendee::List::ConstIterator it;
00342   for( it = mAttendees.begin(); it != mAttendees.end(); ++it ) {
00343     if ( (*it)->uid() == uid ) return *it;
00344   }
00345 
00346   return 0;
00347 }
00348 
00349 
00350 void IncidenceBase::setDuration(int seconds)
00351 {
00352   mDuration = seconds;
00353   setHasDuration(true);
00354   updated();
00355 }
00356 
00357 int IncidenceBase::duration() const
00358 {
00359   return mDuration;
00360 }
00361 
00362 void IncidenceBase::setHasDuration(bool hasDuration)
00363 {
00364   mHasDuration = hasDuration;
00365 }
00366 
00367 bool IncidenceBase::hasDuration() const
00368 {
00369   return mHasDuration;
00370 }
00371 
00372 void IncidenceBase::setSyncStatus(int stat)
00373 {
00374   if (mReadOnly) return;
00375   if ( mSyncStatus == stat ) return;
00376   mSyncStatus = stat;
00377   updatedSilent();
00378 }
00379 void IncidenceBase::setSyncStatusSilent(int stat)
00380 {
00381   if (mReadOnly) return;
00382   mSyncStatus = stat;
00383 }
00384 
00385 int IncidenceBase::syncStatus() const
00386 {
00387   return mSyncStatus;
00388 }
00389 
00390 void IncidenceBase::setPilotId( unsigned long id )
00391 {
00392   if (mReadOnly) return;
00393   if ( mPilotId == id) return;
00394   mPilotId = id;
00395   updatedSilent();
00396 }
00397 
00398 unsigned long IncidenceBase::pilotId() const
00399 {
00400   return mPilotId;
00401 }
00402 
00403 void IncidenceBase::registerObserver( IncidenceBase::Observer *observer )
00404 {
00405   if( !mObservers.contains( observer ) ) mObservers.append( observer );
00406 }
00407 
00408 void IncidenceBase::unRegisterObserver( IncidenceBase::Observer *observer )
00409 {
00410   mObservers.remove( observer );
00411 }
00412 
00413 void IncidenceBase::updated()
00414 {
00415   if ( mUpdateGroupLevel == 0 ) {
00416     QPtrListIterator<Observer> it(mObservers);
00417     while( it.current() ) {
00418       Observer *o = it.current();
00419       ++it;
00420       if ( o ) {
00421         o->incidenceUpdated( this );
00422       }
00423     }
00424   }
00425 }
00426 
00427 void IncidenceBase::customPropertyUpdated()
00428 {
00429   updated();
00430 }
00431 
00432 void IncidenceBase::updatedSilent()
00433 {
00434   QPtrListIterator<Observer> it(mObservers);
00435   while( it.current() ) {
00436     Observer *o = it.current();
00437     ++it;
00438     o->incidenceUpdatedSilent( this );
00439   }
00440 }
00441 
00442 void IncidenceBase::startUpdates()
00443 {
00444   ++mUpdateGroupLevel;
00445 }
00446 
00447 void IncidenceBase::endUpdates()
00448 {
00449   if ( mUpdateGroupLevel > 0 ) {
00450     if ( --mUpdateGroupLevel == 0 ) {
00451       updated();
00452     }
00453   } else {
00454     kdWarning() << "startUpdates() not called() before endUpdates()";
00455   }
00456 }
00457 
00458 void IncidenceBase::cancelUpdates()
00459 {
00460   if ( mUpdateGroupLevel != 0 ) {
00461     mUpdateGroupLevel = 0;
00462   } else {
00463     kdWarning() << "startUpdates() not called() before cancelUpdates()";
00464   }
00465 }
00466 
00467 QPtrList<IncidenceBase::Observer> IncidenceBase::observers() const
00468 {
00469   return mObservers;
00470 }
00471 
00472 
00473 QMap<IncidenceBase::Field,bool> IncidenceBase::dirtyFields() const
00474 {
00475   return mDirtyFields;
00476 }
00477 
00478 void IncidenceBase::resetDirtyFields()
00479 {
00480   mDirtyFields.clear();
00481 }
00482 
00483 void IncidenceBase::setFieldDirty( IncidenceBase::Field field )
00484 {
00485   mDirtyFields.insert( field, true );
00486 }
KDE Home | KDE Accessibility Home | Description of Access Keys