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 ) 00036 { 00037 setUid( CalFormat::createUniqueId() ); 00038 00039 mAttendees.setAutoDelete( true ); 00040 } 00041 00042 IncidenceBase::IncidenceBase(const IncidenceBase &i) : 00043 CustomProperties( i ) 00044 { 00045 mReadOnly = i.mReadOnly; 00046 mDtStart = i.mDtStart; 00047 mDuration = i.mDuration; 00048 mHasDuration = i.mHasDuration; 00049 mOrganizer = i.mOrganizer; 00050 mUid = i.mUid; 00051 Attendee::List attendees = i.attendees(); 00052 Attendee::List::ConstIterator it; 00053 for( it = attendees.begin(); it != attendees.end(); ++it ) { 00054 mAttendees.append( new Attendee( *(*it) ) ); 00055 } 00056 mFloats = i.mFloats; 00057 mLastModified = i.mLastModified; 00058 mPilotId = i.mPilotId; 00059 mSyncStatus = i.mSyncStatus; 00060 mComments = i.mComments; 00061 00062 // The copied object is a new one, so it isn't observed by the observer 00063 // of the original object. 00064 mObservers.clear(); 00065 00066 mAttendees.setAutoDelete( true ); 00067 } 00068 00069 IncidenceBase::~IncidenceBase() 00070 { 00071 } 00072 00073 IncidenceBase& IncidenceBase::operator=( const IncidenceBase& i ) 00074 { 00075 CustomProperties::operator=( i ); 00076 mReadOnly = i.mReadOnly; 00077 mDtStart = i.mDtStart; 00078 mDuration = i.mDuration; 00079 mHasDuration = i.mHasDuration; 00080 mOrganizer = i.mOrganizer; 00081 mUid = i.mUid; 00082 mAttendees.clear(); 00083 Attendee::List attendees = i.attendees(); 00084 Attendee::List::ConstIterator it; 00085 for( it = attendees.begin(); it != attendees.end(); ++it ) { 00086 mAttendees.append( new Attendee( *(*it) ) ); 00087 } 00088 mFloats = i.mFloats; 00089 mLastModified = i.mLastModified; 00090 mPilotId = i.mPilotId; 00091 mSyncStatus = i.mSyncStatus; 00092 mComments = i.mComments; 00093 00094 return *this; 00095 } 00096 00097 bool IncidenceBase::operator==( const IncidenceBase& i2 ) const 00098 { 00099 if( attendees().count() != i2.attendees().count() ) { 00100 return false; // no need to check further 00101 } 00102 00103 Attendee::List al1 = attendees(); 00104 Attendee::List al2 = i2.attendees(); 00105 Attendee::List::ConstIterator a1 = al1.begin(); 00106 Attendee::List::ConstIterator a2 = al2.begin(); 00107 for( ; a1 != al1.end() && a2 != al2.end(); ++a1, ++a2 ) { 00108 if( **a1 == **a2 ) 00109 continue; 00110 else { 00111 return false; 00112 } 00113 } 00114 00115 if ( !CustomProperties::operator==(i2) ) 00116 return false; 00117 00118 return ( dtStart() == i2.dtStart() && 00119 organizer() == i2.organizer() && 00120 uid() == i2.uid() && 00121 // Don't compare lastModified, otherwise the operator is not 00122 // of much use. We are not comparing for identity, after all. 00123 doesFloat() == i2.doesFloat() && 00124 duration() == i2.duration() && 00125 hasDuration() == i2.hasDuration() && 00126 pilotId() == i2.pilotId() && 00127 syncStatus() == i2.syncStatus() ); 00128 // no need to compare mObserver 00129 } 00130 00131 00132 00133 00134 void IncidenceBase::setUid(const TQString &uid) 00135 { 00136 mUid = uid; 00137 updated(); 00138 } 00139 00140 TQString IncidenceBase::uid() const 00141 { 00142 return mUid; 00143 } 00144 00145 void IncidenceBase::setLastModified(const TQDateTime &lm) 00146 { 00147 // DON'T! updated() because we call this from 00148 // Calendar::updateEvent(). 00149 00150 // Remove milliseconds part. 00151 TQDateTime current = lm; 00152 TQTime t = current.time(); 00153 t.setHMS( t.hour(), t.minute(), t.second(), 0 ); 00154 current.setTime( t ); 00155 00156 mLastModified = current; 00157 } 00158 00159 TQDateTime IncidenceBase::lastModified() const 00160 { 00161 return mLastModified; 00162 } 00163 00164 void IncidenceBase::setOrganizer( const Person &o ) 00165 { 00166 // we don't check for readonly here, because it is 00167 // possible that by setting the organizer we are changing 00168 // the event's readonly status... 00169 mOrganizer = o; 00170 00171 updated(); 00172 } 00173 00174 void IncidenceBase::setOrganizer(const TQString &o) 00175 { 00176 TQString mail( o ); 00177 if ( mail.startsWith("MAILTO:", false) ) 00178 mail = mail.remove( 0, 7 ); 00179 // split the string into full name plus email. 00180 Person organizer( mail ); 00181 setOrganizer( organizer ); 00182 } 00183 00184 Person IncidenceBase::organizer() const 00185 { 00186 return mOrganizer; 00187 } 00188 00189 void IncidenceBase::setReadOnly( bool readOnly ) 00190 { 00191 mReadOnly = readOnly; 00192 } 00193 00194 void IncidenceBase::setDtStart(const TQDateTime &dtStart) 00195 { 00196 // if (mReadOnly) return; 00197 mDtStart = dtStart; 00198 updated(); 00199 } 00200 00201 TQDateTime IncidenceBase::dtStart() const 00202 { 00203 return mDtStart; 00204 } 00205 00206 TQString IncidenceBase::dtStartTimeStr() const 00207 { 00208 return KGlobal::locale()->formatTime(dtStart().time()); 00209 } 00210 00211 TQString IncidenceBase::dtStartDateStr(bool shortfmt) const 00212 { 00213 return KGlobal::locale()->formatDate(dtStart().date(),shortfmt); 00214 } 00215 00216 TQString IncidenceBase::dtStartStr() const 00217 { 00218 return KGlobal::locale()->formatDateTime(dtStart()); 00219 } 00220 00221 00222 bool IncidenceBase::doesFloat() const 00223 { 00224 return mFloats; 00225 } 00226 00227 void IncidenceBase::setFloats(bool f) 00228 { 00229 if (mReadOnly) return; 00230 mFloats = f; 00231 updated(); 00232 } 00233 00234 00235 void IncidenceBase::addComment(const TQString& comment) 00236 { 00237 mComments += comment; 00238 } 00239 00240 bool IncidenceBase::removeComment( const TQString& comment) 00241 { 00242 bool found = false; 00243 TQStringList::Iterator i; 00244 00245 for ( i = mComments.begin(); !found && i != mComments.end(); ++i ) { 00246 if ( (*i) == comment ) { 00247 found = true; 00248 mComments.remove(i); 00249 } 00250 } 00251 00252 return found; 00253 } 00254 00255 void IncidenceBase::clearComments() 00256 { 00257 mComments.clear(); 00258 } 00259 00260 TQStringList IncidenceBase::comments() const 00261 { 00262 return mComments; 00263 } 00264 00265 00266 void IncidenceBase::addAttendee(Attendee *a, bool doupdate) 00267 { 00268 // kdDebug(5800) << "IncidenceBase::addAttendee()" << endl; 00269 if (mReadOnly) return; 00270 // kdDebug(5800) << "IncidenceBase::addAttendee() weiter" << endl; 00271 if (a->name().left(7).upper() == "MAILTO:") 00272 a->setName(a->name().remove(0,7)); 00273 00274 mAttendees.append(a); 00275 if (doupdate) updated(); 00276 } 00277 00278 #if 0 00279 void IncidenceBase::removeAttendee(Attendee *a) 00280 { 00281 if (mReadOnly) return; 00282 mAttendees.removeRef(a); 00283 updated(); 00284 } 00285 00286 void IncidenceBase::removeAttendee(const char *n) 00287 { 00288 Attendee *a; 00289 00290 if (mReadOnly) return; 00291 for (a = mAttendees.first(); a; a = mAttendees.next()) 00292 if (a->getName() == n) { 00293 mAttendees.remove(); 00294 break; 00295 } 00296 } 00297 #endif 00298 00299 void IncidenceBase::clearAttendees() 00300 { 00301 if (mReadOnly) return; 00302 mAttendees.clear(); 00303 } 00304 00305 Attendee *IncidenceBase::attendeeByMail( const TQString &email ) const 00306 { 00307 Attendee::List::ConstIterator it; 00308 for( it = mAttendees.begin(); it != mAttendees.end(); ++it ) { 00309 if ( (*it)->email() == email ) return *it; 00310 } 00311 00312 return 0; 00313 } 00314 00315 Attendee *IncidenceBase::attendeeByMails( const TQStringList &emails, 00316 const TQString &email) const 00317 { 00318 TQStringList mails = emails; 00319 if ( !email.isEmpty() ) mails.append( email ); 00320 00321 Attendee::List::ConstIterator itA; 00322 for( itA = mAttendees.begin(); itA != mAttendees.end(); ++itA ) { 00323 for ( TQStringList::Iterator it = mails.begin(); it != mails.end(); ++it ) { 00324 if ( (*itA)->email() == (*it) ) return *itA; 00325 } 00326 } 00327 00328 return 0; 00329 } 00330 00331 Attendee *IncidenceBase::attendeeByUid( const TQString &uid ) const 00332 { 00333 Attendee::List::ConstIterator it; 00334 for( it = mAttendees.begin(); it != mAttendees.end(); ++it ) { 00335 if ( (*it)->uid() == uid ) return *it; 00336 } 00337 00338 return 0; 00339 } 00340 00341 00342 void IncidenceBase::setDuration(int seconds) 00343 { 00344 mDuration = seconds; 00345 setHasDuration(true); 00346 updated(); 00347 } 00348 00349 int IncidenceBase::duration() const 00350 { 00351 return mDuration; 00352 } 00353 00354 void IncidenceBase::setHasDuration(bool hasDuration) 00355 { 00356 mHasDuration = hasDuration; 00357 } 00358 00359 bool IncidenceBase::hasDuration() const 00360 { 00361 return mHasDuration; 00362 } 00363 00364 void IncidenceBase::setSyncStatus(int stat) 00365 { 00366 if (mReadOnly) return; 00367 if ( mSyncStatus == stat ) return; 00368 mSyncStatus = stat; 00369 updatedSilent(); 00370 } 00371 void IncidenceBase::setSyncStatusSilent(int stat) 00372 { 00373 if (mReadOnly) return; 00374 mSyncStatus = stat; 00375 } 00376 00377 int IncidenceBase::syncStatus() const 00378 { 00379 return mSyncStatus; 00380 } 00381 00382 void IncidenceBase::setPilotId( unsigned long id ) 00383 { 00384 if (mReadOnly) return; 00385 if ( mPilotId == id) return; 00386 mPilotId = id; 00387 updatedSilent(); 00388 } 00389 00390 unsigned long IncidenceBase::pilotId() const 00391 { 00392 return mPilotId; 00393 } 00394 00395 void IncidenceBase::registerObserver( IncidenceBase::Observer *observer ) 00396 { 00397 if( !mObservers.contains( observer ) ) mObservers.append( observer ); 00398 } 00399 00400 void IncidenceBase::unRegisterObserver( IncidenceBase::Observer *observer ) 00401 { 00402 mObservers.remove( observer ); 00403 } 00404 00405 void IncidenceBase::updated() 00406 { 00407 TQPtrListIterator<Observer> it(mObservers); 00408 while( it.current() ) { 00409 Observer *o = it.current(); 00410 ++it; 00411 if ( o ) { 00412 o->incidenceUpdated( this ); 00413 } 00414 } 00415 } 00416 00417 void IncidenceBase::customPropertyUpdated() 00418 { 00419 updated(); 00420 } 00421 00422 void IncidenceBase::updatedSilent() 00423 { 00424 TQPtrListIterator<Observer> it(mObservers); 00425 while( it.current() ) { 00426 Observer *o = it.current(); 00427 ++it; 00428 o->incidenceUpdatedSilent( this ); 00429 } 00430 } 00431