• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.10.5 API Reference
  • KDE Home
  • Contact Us
 

KCal Library

  • kcal
incidencebase.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcal library.
3 
4  Copyright (c) 2001,2004 Cornelius Schumacher <schumacher@kde.org>
5  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
35 #include "incidencebase.h"
36 #include "calformat.h"
37 #include "incidenceformatter.h"
38 
39 #include <kglobal.h>
40 #include <klocale.h>
41 #include <kdebug.h>
42 #include <kurl.h>
43 #include <ksystemtimezone.h>
44 
45 #include <QtCore/QList>
46 
47 using namespace KCal;
48 
53 //@cond PRIVATE
54 class KCal::IncidenceBase::Private
55 {
56  public:
57  Private()
58  : mUpdateGroupLevel( 0 ),
59  mUpdatedPending( false ),
60  mAllDay( true ),
61  mHasDuration( false )
62  { mAttendees.setAutoDelete( true ); }
63 
64  Private( const Private &other )
65  : mUpdateGroupLevel( 0 ),
66  mUpdatedPending( false ),
67  mAllDay( true ),
68  mHasDuration( false )
69  {
70  mAttendees.setAutoDelete( true );
71  init( other );
72  }
73 
74  void init( const Private &other );
75 
76  KDateTime mLastModified; // incidence last modified date
77  KDateTime mDtStart; // incidence start time
78  Person mOrganizer; // incidence person (owner)
79  QString mUid; // incidence unique id
80  Duration mDuration; // incidence duration
81  int mUpdateGroupLevel; // if non-zero, suppresses update() calls
82  bool mUpdatedPending; // true if an update has occurred since startUpdates()
83  bool mAllDay; // true if the incidence is all-day
84  bool mHasDuration; // true if the incidence has a duration
85 
86  Attendee::List mAttendees; // list of incidence attendees
87  QStringList mComments; // list of incidence comments
88  QList<IncidenceObserver*> mObservers; // list of incidence observers
89 };
90 
91 void IncidenceBase::Private::init( const Private &other )
92 {
93  mLastModified = other.mLastModified;
94  mDtStart = other.mDtStart;
95  mOrganizer = other.mOrganizer;
96  mUid = other.mUid;
97  mDuration = other.mDuration;
98  mAllDay = other.mAllDay;
99  mHasDuration = other.mHasDuration;
100  mComments = other.mComments;
101 
102  mAttendees.clearAll();
103  Attendee::List::ConstIterator it;
104  for ( it = other.mAttendees.constBegin(); it != other.mAttendees.constEnd(); ++it ) {
105  mAttendees.append( new Attendee( *(*it) ) );
106  }
107 }
108 //@endcond
109 
110 IncidenceBase::IncidenceBase()
111  : d( new KCal::IncidenceBase::Private )
112 {
113  mReadOnly = false;
114 
115  setUid( CalFormat::createUniqueId() );
116 }
117 
118 IncidenceBase::IncidenceBase( const IncidenceBase &i )
119  : CustomProperties( i ),
120  d( new KCal::IncidenceBase::Private( *i.d ) )
121 {
122  mReadOnly = i.mReadOnly;
123 }
124 
125 IncidenceBase::~IncidenceBase()
126 {
127  delete d;
128 }
129 
130 IncidenceBase &IncidenceBase::operator=( const IncidenceBase &other )
131 {
132  // check for self assignment
133  if ( &other == this ) {
134  return *this;
135  }
136 
137  CustomProperties::operator=( other );
138  d->init( *other.d );
139  mReadOnly = other.mReadOnly;
140  return *this;
141 }
142 
143 bool IncidenceBase::operator==( const IncidenceBase &i2 ) const
144 {
145  if ( attendees().count() != i2.attendees().count() ) {
146  return false; // no need to check further
147  }
148 
149  Attendee::List al1 = attendees();
150  Attendee::List al2 = i2.attendees();
151  Attendee::List::ConstIterator a1 = al1.constBegin();
152  Attendee::List::ConstIterator a2 = al2.constBegin();
153  //TODO Does the order of attendees in the list really matter?
154  //Please delete this comment if you know it's ok, kthx
155  for ( ; a1 != al1.constEnd() && a2 != al2.constEnd(); ++a1, ++a2 ) {
156  if ( !( **a1 == **a2 ) ) {
157  return false;
158  }
159  }
160 
161  if ( !CustomProperties::operator == (i2) ) {
162  return false;
163  }
164 
165  return
166  dtStart() == i2.dtStart() &&
167  organizer() == i2.organizer() &&
168  uid() == i2.uid() &&
169  // Don't compare lastModified, otherwise the operator is not
170  // of much use. We are not comparing for identity, after all.
171  allDay() == i2.allDay() &&
172  duration() == i2.duration() &&
173  hasDuration() == i2.hasDuration();
174  // no need to compare mObserver
175 }
176 
177 void IncidenceBase::setUid( const QString &uid )
178 {
179  d->mUid = uid;
180  updated();
181 }
182 
183 QString IncidenceBase::uid() const
184 {
185  return d->mUid;
186 }
187 
188 void IncidenceBase::setLastModified( const KDateTime &lm )
189 {
190  // DON'T! updated() because we call this from
191  // Calendar::updateEvent().
192 
193  // Convert to UTC and remove milliseconds part.
194  KDateTime current = lm.toUtc();
195  QTime t = current.time();
196  t.setHMS( t.hour(), t.minute(), t.second(), 0 );
197  current.setTime( t );
198 
199  d->mLastModified = current;
200 }
201 
202 KDateTime IncidenceBase::lastModified() const
203 {
204  return d->mLastModified;
205 }
206 
207 void IncidenceBase::setOrganizer( const Person &o )
208 {
209  // we don't check for readonly here, because it is
210  // possible that by setting the organizer we are changing
211  // the event's readonly status...
212  d->mOrganizer = o;
213 
214  updated();
215 }
216 
217 void IncidenceBase::setOrganizer( const QString &o )
218 {
219  QString mail( o );
220  if ( mail.startsWith( QLatin1String( "MAILTO:" ), Qt::CaseInsensitive ) ) {
221  mail = mail.remove( 0, 7 );
222  }
223 
224  // split the string into full name plus email.
225  const Person organizer = Person::fromFullName( mail );
226  setOrganizer( organizer );
227 }
228 
229 Person IncidenceBase::organizer() const
230 {
231  return d->mOrganizer;
232 }
233 
234 void IncidenceBase::setReadOnly( bool readOnly )
235 {
236  mReadOnly = readOnly;
237 }
238 
239 void IncidenceBase::setDtStart( const KDateTime &dtStart )
240 {
241 // if ( mReadOnly ) return;
242  d->mDtStart = dtStart;
243  d->mAllDay = dtStart.isDateOnly();
244  updated();
245 }
246 
247 KDateTime IncidenceBase::dtStart() const
248 {
249  return d->mDtStart;
250 }
251 
252 QString IncidenceBase::dtStartTimeStr( bool shortfmt, const KDateTime::Spec &spec ) const
253 {
254  if ( spec.isValid() ) {
255 
256  QString timeZone;
257  if ( spec.timeZone() != KSystemTimeZones::local() ) {
258  timeZone = ' ' + spec.timeZone().name();
259  }
260 
261  return KGlobal::locale()->formatTime(
262  dtStart().toTimeSpec( spec ).time(), !shortfmt ) + timeZone;
263  } else {
264  return KGlobal::locale()->formatTime( dtStart().time(), !shortfmt );
265  }
266 }
267 
268 QString IncidenceBase::dtStartDateStr( bool shortfmt, const KDateTime::Spec &spec ) const
269 {
270  if ( spec.isValid() ) {
271 
272  QString timeZone;
273  if ( spec.timeZone() != KSystemTimeZones::local() ) {
274  timeZone = ' ' + spec.timeZone().name();
275  }
276 
277  return KGlobal::locale()->formatDate(
278  dtStart().toTimeSpec( spec ).date(),
279  ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) ) + timeZone;
280  } else {
281  return KGlobal::locale()->formatDate(
282  dtStart().date(), ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
283  }
284 }
285 
286 QString IncidenceBase::dtStartStr( bool shortfmt, const KDateTime::Spec &spec ) const
287 {
288  if ( allDay() ) {
289  return IncidenceFormatter::dateToString( dtStart(), shortfmt, spec );
290  }
291 
292  if ( spec.isValid() ) {
293 
294  QString timeZone;
295  if ( spec.timeZone() != KSystemTimeZones::local() ) {
296  timeZone = ' ' + spec.timeZone().name();
297  }
298 
299  return KGlobal::locale()->formatDateTime(
300  dtStart().toTimeSpec( spec ).dateTime(),
301  ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) ) + timeZone;
302  } else {
303  return KGlobal::locale()->formatDateTime(
304  dtStart().dateTime(),
305  ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
306  }
307 }
308 
309 bool IncidenceBase::allDay() const
310 {
311  return d->mAllDay;
312 }
313 
314 void IncidenceBase::setAllDay( bool f )
315 {
316  if ( mReadOnly || f == d->mAllDay ) {
317  return;
318  }
319  d->mAllDay = f;
320  updated();
321 }
322 
323 void IncidenceBase::shiftTimes( const KDateTime::Spec &oldSpec,
324  const KDateTime::Spec &newSpec )
325 {
326  d->mDtStart = d->mDtStart.toTimeSpec( oldSpec );
327  d->mDtStart.setTimeSpec( newSpec );
328  updated();
329 }
330 
331 void IncidenceBase::addComment( const QString &comment )
332 {
333  d->mComments += comment;
334 }
335 
336 bool IncidenceBase::removeComment( const QString &comment )
337 {
338  bool found = false;
339  QStringList::Iterator i;
340 
341  for ( i = d->mComments.begin(); !found && i != d->mComments.end(); ++i ) {
342  if ( (*i) == comment ) {
343  found = true;
344  d->mComments.erase( i );
345  }
346  }
347 
348  return found;
349 }
350 
351 void IncidenceBase::clearComments()
352 {
353  d->mComments.clear();
354 }
355 
356 QStringList IncidenceBase::comments() const
357 {
358  return d->mComments;
359 }
360 
361 void IncidenceBase::addAttendee( Attendee *a, bool doupdate )
362 {
363  if ( !a || mReadOnly ) {
364  return;
365  }
366 
367  if ( a->name().left(7).toUpper() == "MAILTO:" ) {
368  a->setName( a->name().remove( 0, 7 ) );
369  }
370 
371  d->mAttendees.append( a );
372  if ( doupdate ) {
373  updated();
374  }
375 }
376 
377 const Attendee::List &IncidenceBase::attendees() const
378 {
379  return d->mAttendees;
380 }
381 
382 int IncidenceBase::attendeeCount() const
383 {
384  return d->mAttendees.count();
385 }
386 
387 void IncidenceBase::clearAttendees()
388 {
389  if ( mReadOnly ) {
390  return;
391  }
392  qDeleteAll( d->mAttendees );
393  d->mAttendees.clear();
394 }
395 
396 Attendee *IncidenceBase::attendeeByMail( const QString &email ) const
397 {
398  Attendee::List::ConstIterator it;
399  for ( it = d->mAttendees.constBegin(); it != d->mAttendees.constEnd(); ++it ) {
400  if ( (*it)->email() == email ) {
401  return *it;
402  }
403  }
404 
405  return 0;
406 }
407 
408 Attendee *IncidenceBase::attendeeByMails( const QStringList &emails,
409  const QString &email ) const
410 {
411  QStringList mails = emails;
412  if ( !email.isEmpty() ) {
413  mails.append( email );
414  }
415 
416  Attendee::List::ConstIterator itA;
417  for ( itA = d->mAttendees.constBegin(); itA != d->mAttendees.constEnd(); ++itA ) {
418  for ( QStringList::const_iterator it = mails.constBegin(); it != mails.constEnd(); ++it ) {
419  if ( (*itA)->email() == (*it) ) {
420  return *itA;
421  }
422  }
423  }
424 
425  return 0;
426 }
427 
428 Attendee *IncidenceBase::attendeeByUid( const QString &uid ) const
429 {
430  Attendee::List::ConstIterator it;
431  for ( it = d->mAttendees.constBegin(); it != d->mAttendees.constEnd(); ++it ) {
432  if ( (*it)->uid() == uid ) {
433  return *it;
434  }
435  }
436 
437  return 0;
438 }
439 
440 void IncidenceBase::setDuration( const Duration &duration )
441 {
442  d->mDuration = duration;
443  setHasDuration( true );
444  updated();
445 }
446 
447 Duration IncidenceBase::duration() const
448 {
449  return d->mDuration;
450 }
451 
452 void IncidenceBase::setHasDuration( bool hasDuration )
453 {
454  d->mHasDuration = hasDuration;
455 }
456 
457 bool IncidenceBase::hasDuration() const
458 {
459  return d->mHasDuration;
460 }
461 
462 void IncidenceBase::registerObserver( IncidenceBase::IncidenceObserver *observer )
463 {
464  if ( !d->mObservers.contains( observer ) ) {
465  d->mObservers.append( observer );
466  }
467 }
468 
469 void IncidenceBase::unRegisterObserver( IncidenceBase::IncidenceObserver *observer )
470 {
471  d->mObservers.removeAll( observer );
472 }
473 
474 void IncidenceBase::updated()
475 {
476  if ( d->mUpdateGroupLevel ) {
477  d->mUpdatedPending = true;
478  } else {
479  foreach ( IncidenceObserver *o, d->mObservers ) {
480  if ( o ) {
481  o->incidenceUpdated( this );
482  }
483  }
484  }
485 }
486 
487 void IncidenceBase::startUpdates()
488 {
489  ++d->mUpdateGroupLevel;
490 }
491 
492 void IncidenceBase::endUpdates()
493 {
494  if ( d->mUpdateGroupLevel > 0 ) {
495  if ( --d->mUpdateGroupLevel == 0 && d->mUpdatedPending ) {
496  d->mUpdatedPending = false;
497  updated();
498  }
499  }
500 }
501 
502 void IncidenceBase::customPropertyUpdated()
503 {
504  updated();
505 }
506 
507 KUrl IncidenceBase::uri() const
508 {
509  return KUrl( QString( "urn:x-ical:" ) + uid() );
510 }
511 
512 bool IncidenceBase::Visitor::visit( Event *event )
513 {
514  Q_UNUSED( event );
515  return false;
516 }
517 
518 bool IncidenceBase::Visitor::visit( Todo *todo )
519 {
520  Q_UNUSED( todo );
521  return false;
522 }
523 
524 bool IncidenceBase::Visitor::visit( Journal *journal )
525 {
526  Q_UNUSED( journal );
527  return false;
528 }
529 
530 bool IncidenceBase::Visitor::visit( FreeBusy *freebusy )
531 {
532  Q_UNUSED( freebusy );
533  return false;
534 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:29:15 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCal Library

Skip menu "KCal Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.10.5 API Reference

Skip menu "kdepimlibs-4.10.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal