• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KCal Library

todo.cpp

Go to the documentation of this file.
00001 /*
00002   This file is part of the kcal library.
00003 
00004   Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
00005 
00006   This library is free software; you can redistribute it and/or
00007   modify it under the terms of the GNU Library General Public
00008   License as published by the Free Software Foundation; either
00009   version 2 of the License, or (at your option) any later version.
00010 
00011   This library is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014   Library General Public License for more details.
00015 
00016   You should have received a copy of the GNU Library General Public License
00017   along with this library; see the file COPYING.LIB.  If not, write to
00018   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019   Boston, MA 02110-1301, USA.
00020 */
00032 #include "todo.h"
00033 
00034 #include <kglobal.h>
00035 #include <klocale.h>
00036 #include <kdebug.h>
00037 #include <ksystemtimezone.h>
00038 
00039 using namespace KCal;
00040 
00045 //@cond PRIVATE
00046 class KCal::Todo::Private
00047 {
00048   public:
00049     Private()
00050       : mPercentComplete( 0 ),
00051         mHasDueDate( false ),
00052         mHasStartDate( false ),
00053         mHasCompletedDate( false )
00054     {}
00055     Private( const KCal::Todo::Private &other )
00056       : mDtDue( other.mDtDue ),
00057         mDtRecurrence( other.mDtRecurrence ),
00058         mCompleted( other.mCompleted ),
00059         mPercentComplete( other.mPercentComplete ),
00060         mHasDueDate( other.mHasDueDate ),
00061         mHasStartDate( other.mHasStartDate ),
00062         mHasCompletedDate( other.mHasCompletedDate )
00063     {}
00064 
00065     KDateTime mDtDue;        // to-do due date (if there is one)
00066                              // ALSO the first occurrence of a recurring to-do
00067     KDateTime mDtRecurrence; // next occurrence (for recurring to-dos)
00068     KDateTime mCompleted;    // to-do completion date (if it has been completed)
00069     int mPercentComplete;    // to-do percent complete [0,100]
00070     bool mHasDueDate;        // true if the to-do has a due date
00071     bool mHasStartDate;      // true if the to-do has a starting date
00072     bool mHasCompletedDate;  // true if the to-do has a completion date
00073 
00077     bool recurTodo( Todo *todo );
00078 };
00079 //@endcond
00080 
00081 Todo::Todo()
00082   : d( new KCal::Todo::Private )
00083 {
00084 }
00085 
00086 Todo::Todo( const Todo &other )
00087   : Incidence( other ), d( new KCal::Todo::Private( *other.d ) )
00088 {
00089 }
00090 
00091 Todo::~Todo()
00092 {
00093   delete d;
00094 }
00095 
00096 Todo *Todo::clone()
00097 {
00098   return new Todo( *this );
00099 }
00100 
00101 bool Todo::operator==( const Todo &t2 ) const
00102 {
00103   return
00104     static_cast<const Incidence &>( *this ) == static_cast<const Incidence &>( t2 ) &&
00105     dtDue() == t2.dtDue() &&
00106     hasDueDate() == t2.hasDueDate() &&
00107     hasStartDate() == t2.hasStartDate() &&
00108     completed() == t2.completed() &&
00109     hasCompletedDate() == t2.hasCompletedDate() &&
00110     percentComplete() == t2.percentComplete();
00111 }
00112 
00113 QByteArray Todo::type() const
00114 {
00115   return "Todo";
00116 }
00117 
00118 void Todo::setDtDue( const KDateTime &dtDue, bool first )
00119 {
00120   //int diffsecs = d->mDtDue.secsTo(dtDue);
00121 
00122   /*if (mReadOnly) return;
00123   const Alarm::List& alarms = alarms();
00124   for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) {
00125     if (alarm->enabled()) {
00126       alarm->setTime(alarm->time().addSecs(diffsecs));
00127     }
00128   }*/
00129   if ( recurs() && !first ) {
00130     d->mDtRecurrence = dtDue;
00131   } else {
00132     d->mDtDue = dtDue;
00133     // TODO: This doesn't seem right...
00134     recurrence()->setStartDateTime( dtDue );
00135     recurrence()->setAllDay( allDay() );
00136   }
00137 
00138   if ( recurs() && dtDue < recurrence()->startDateTime() ) {
00139     setDtStart( dtDue );
00140   }
00141 
00142   //kDebug(5800) << "setDtDue says date is" << d->mDtDue.toString();
00143 
00144   /*const Alarm::List& alarms = alarms();
00145   for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next())
00146     alarm->setAlarmStart(d->mDtDue);*/
00147 
00148   updated();
00149 }
00150 
00151 KDateTime Todo::dtDue( bool first ) const
00152 {
00153   if ( recurs() && !first && d->mDtRecurrence.isValid() ) {
00154     return d->mDtRecurrence;
00155   }
00156 
00157   return d->mDtDue;
00158 }
00159 
00160 QString Todo::dtDueTimeStr( bool shortfmt, const KDateTime::Spec &spec ) const
00161 {
00162   if ( spec.isValid() ) {
00163 
00164     QString timeZone;
00165     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00166       timeZone = ' ' + spec.timeZone().name();
00167     }
00168 
00169     return KGlobal::locale()->formatTime( dtDue( !recurs() ).toTimeSpec( spec ).time(), shortfmt )
00170       + timeZone;
00171   } else {
00172     return KGlobal::locale()->formatTime( dtDue( !recurs() ).time(), shortfmt );
00173   }
00174 }
00175 
00176 QString Todo::dtDueDateStr( bool shortfmt, const KDateTime::Spec &spec ) const
00177 {
00178   if ( spec.isValid() ) {
00179 
00180     QString timeZone;
00181     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00182       timeZone = ' ' + spec.timeZone().name();
00183     }
00184 
00185     return KGlobal::locale()->formatDate(
00186       dtDue( !recurs() ).toTimeSpec( spec ).date(),
00187       ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) )
00188       + timeZone;
00189   } else {
00190     return KGlobal::locale()->formatDate(
00191       dtDue( !recurs() ).date(),
00192       ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00193   }
00194 }
00195 
00196 QString Todo::dtDueStr( bool shortfmt, const KDateTime::Spec &spec ) const
00197 {
00198   if ( spec.isValid() ) {
00199 
00200     QString timeZone;
00201     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00202       timeZone = ' ' + spec.timeZone().name();
00203     }
00204 
00205     return KGlobal::locale()->formatDateTime(
00206       dtDue( !recurs() ).toTimeSpec( spec ).dateTime(),
00207       ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) )
00208       + timeZone;
00209   } else {
00210     return  KGlobal::locale()->formatDateTime(
00211       dtDue( !recurs() ).dateTime(),
00212       ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00213   }
00214 }
00215 
00216 bool Todo::hasDueDate() const
00217 {
00218   return d->mHasDueDate;
00219 }
00220 
00221 void Todo::setHasDueDate( bool f )
00222 {
00223   if ( mReadOnly ) {
00224     return;
00225   }
00226   d->mHasDueDate = f;
00227   updated();
00228 }
00229 
00230 bool Todo::hasStartDate() const
00231 {
00232   return d->mHasStartDate;
00233 }
00234 
00235 void Todo::setHasStartDate( bool f )
00236 {
00237   if ( mReadOnly ) {
00238     return;
00239   }
00240 
00241   if ( recurs() && !f ) {
00242     if ( !comments().filter( "NoStartDate" ).count() ) {
00243       addComment( "NoStartDate" ); //TODO: --> custom flag?
00244     }
00245   } else {
00246     QString s( "NoStartDate" );
00247     removeComment( s );
00248   }
00249   d->mHasStartDate = f;
00250   updated();
00251 }
00252 
00253 KDateTime Todo::dtStart() const
00254 {
00255   return dtStart( false );
00256 }
00257 
00258 KDateTime Todo::dtStart( bool first ) const
00259 {
00260   if ( recurs() && !first ) {
00261     return d->mDtRecurrence.addDays( dtDue( first ).daysTo( IncidenceBase::dtStart() ) );
00262   } else {
00263     return IncidenceBase::dtStart();
00264   }
00265 }
00266 
00267 void Todo::setDtStart( const KDateTime &dtStart )
00268 {
00269   // TODO: This doesn't seem right (rfc 2445/6 says, recurrence is calculated from the dtstart...)
00270   if ( recurs() ) {
00271     recurrence()->setStartDateTime( d->mDtDue );
00272     recurrence()->setAllDay( allDay() );
00273   }
00274   IncidenceBase::setDtStart( dtStart );
00275 }
00276 
00277 QString Todo::dtStartTimeStr( bool shortfmt, bool first, const KDateTime::Spec &spec ) const
00278 {
00279   if ( spec.isValid() ) {
00280 
00281     QString timeZone;
00282     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00283       timeZone = ' ' + spec.timeZone().name();
00284     }
00285 
00286     return KGlobal::locale()->formatTime( dtStart( first ).toTimeSpec( spec ).time(), shortfmt )
00287       + timeZone;
00288   } else {
00289     return KGlobal::locale()->formatTime( dtStart( first ).time(), shortfmt );
00290   }
00291 }
00292 
00293 QString Todo::dtStartTimeStr( bool shortfmt, const KDateTime::Spec &spec ) const
00294 {
00295   return Incidence::dtStartTimeStr( shortfmt, spec );
00296 }
00297 
00298 QString Todo::dtStartDateStr( bool shortfmt, bool first, const KDateTime::Spec &spec ) const
00299 {
00300   if ( spec.isValid() ) {
00301 
00302     QString timeZone;
00303     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00304       timeZone = ' ' + spec.timeZone().name();
00305     }
00306 
00307     return
00308       KGlobal::locale()->formatDate( dtStart( first ).toTimeSpec( spec ).date(),
00309                                    ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) )
00310       + timeZone;
00311   } else {
00312     return
00313       KGlobal::locale()->formatDate( dtStart( first ).date(),
00314                                    ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00315   }
00316 }
00317 
00318 QString Todo::dtStartDateStr( bool shortfmt, const KDateTime::Spec &spec ) const
00319 {
00320   return Incidence::dtStartDateStr( shortfmt, spec );
00321 }
00322 
00323 QString Todo::dtStartStr( bool shortfmt, bool first, const KDateTime::Spec &spec ) const
00324 {
00325   if ( spec.isValid() ) {
00326 
00327     QString timeZone;
00328     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00329       timeZone = ' ' + spec.timeZone().name();
00330     }
00331 
00332     return
00333       KGlobal::locale()->formatDateTime( dtStart( first ).toTimeSpec( spec ).dateTime(),
00334                                        ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) )
00335       + timeZone;
00336   } else {
00337     return
00338       KGlobal::locale()->formatDateTime( dtStart( first ).dateTime(),
00339                                        ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00340   }
00341 }
00342 
00343 QString Todo::dtStartStr( bool shortfmt, const KDateTime::Spec &spec ) const
00344 {
00345   return Incidence::dtStartStr( shortfmt, spec );
00346 }
00347 
00348 bool Todo::isCompleted() const
00349 {
00350   if ( d->mPercentComplete == 100 ) {
00351     return true;
00352   } else {
00353     return false;
00354   }
00355 }
00356 
00357 void Todo::setCompleted( bool completed )
00358 {
00359   if ( completed ) {
00360     d->mPercentComplete = 100;
00361   } else {
00362     d->mPercentComplete = 0;
00363     d->mHasCompletedDate = false;
00364     d->mCompleted = KDateTime();
00365   }
00366   updated();
00367 }
00368 
00369 KDateTime Todo::completed() const
00370 {
00371   if ( hasCompletedDate() ) {
00372     return d->mCompleted;
00373   } else {
00374     return KDateTime();
00375   }
00376 }
00377 
00378 QString Todo::completedStr( bool shortfmt ) const
00379 {
00380   return
00381     KGlobal::locale()->formatDateTime( d->mCompleted.dateTime(),
00382                                        ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00383 }
00384 
00385 void Todo::setCompleted( const KDateTime &completed )
00386 {
00387   if ( !d->recurTodo( this ) ) {
00388     d->mHasCompletedDate = true;
00389     d->mPercentComplete = 100;
00390     d->mCompleted = completed.toUtc();
00391   }
00392   updated();
00393 }
00394 
00395 bool Todo::hasCompletedDate() const
00396 {
00397   return d->mHasCompletedDate;
00398 }
00399 
00400 int Todo::percentComplete() const
00401 {
00402   return d->mPercentComplete;
00403 }
00404 
00405 void Todo::setPercentComplete( int percent )
00406 {
00407   //TODO: (?) assert percent between 0 and 100, inclusive
00408   d->mPercentComplete = percent;
00409   if ( percent != 100 ) {
00410     d->mHasCompletedDate = false;
00411   }
00412   updated();
00413 }
00414 
00415 void Todo::shiftTimes( const KDateTime::Spec &oldSpec,
00416                        const KDateTime::Spec &newSpec )
00417 {
00418   Incidence::shiftTimes( oldSpec, newSpec );
00419   d->mDtDue = d->mDtDue.toTimeSpec( oldSpec );
00420   d->mDtDue.setTimeSpec( newSpec );
00421   if ( recurs() ) {
00422     d->mDtRecurrence = d->mDtRecurrence.toTimeSpec( oldSpec );
00423     d->mDtRecurrence.setTimeSpec( newSpec );
00424   }
00425   if ( d->mHasCompletedDate ) {
00426     d->mCompleted = d->mCompleted.toTimeSpec( oldSpec );
00427     d->mCompleted.setTimeSpec( newSpec );
00428   }
00429 }
00430 
00431 void Todo::setDtRecurrence( const KDateTime &dt )
00432 {
00433   d->mDtRecurrence = dt;
00434 }
00435 
00436 KDateTime Todo::dtRecurrence() const
00437 {
00438   return d->mDtRecurrence.isValid() ? d->mDtRecurrence : d->mDtDue;
00439 }
00440 
00441 bool Todo::recursOn( const QDate &date, const KDateTime::Spec &timeSpec ) const
00442 {
00443   QDate today = QDate::currentDate();
00444   return
00445     Incidence::recursOn( date, timeSpec ) &&
00446     !( date < today && d->mDtRecurrence.date() < today &&
00447        d->mDtRecurrence > recurrence()->startDateTime() );
00448 }
00449 
00450 bool Todo::isOverdue() const
00451 {
00452   bool inPast = allDay() ?
00453                 dtDue().date() < QDate::currentDate() :
00454                 dtDue() < KDateTime::currentUtcDateTime();
00455   return inPast && !isCompleted();
00456 }
00457 
00458 KDateTime Todo::endDateRecurrenceBase() const
00459 {
00460   return dtDue();
00461 }
00462 
00463 //@cond PRIVATE
00464 bool Todo::Private::recurTodo( Todo *todo )
00465 {
00466   if ( todo->recurs() ) {
00467     Recurrence *r = todo->recurrence();
00468     KDateTime endDateTime = r->endDateTime();
00469     KDateTime nextDate = r->getNextDateTime( todo->dtDue() );
00470 
00471     if ( ( r->duration() == -1 ||
00472            ( nextDate.isValid() && endDateTime.isValid() &&
00473              nextDate <= endDateTime ) ) ) {
00474 
00475       while ( !todo->recursAt( nextDate ) ||
00476               nextDate <= KDateTime::currentUtcDateTime() ) {
00477 
00478         if ( !nextDate.isValid() || nextDate > endDateTime ) {
00479           return false;
00480         }
00481 
00482         nextDate = r->getNextDateTime( nextDate );
00483       }
00484 
00485       todo->setDtDue( nextDate );
00486       todo->setCompleted( false );
00487       todo->setRevision( todo->revision() + 1 );
00488 
00489       return true;
00490     }
00491   }
00492 
00493   return false;
00494 }
00495 //@endcond

KCal Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal