[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-pim
Subject:    [Kde-pim] Re: [PATCH] Recursion on todo's improved (update)
From:       Bram Schoenmakers <bramschoenmakers () kde ! nl>
Date:       2004-06-28 22:46:09
Message-ID: 200406290045.31782.bramschoenmakers () kde ! nl
[Download RAW message or body]

Hi,

In the meantime I've been working on this feature. Some tweaks on the 
agendaview, and some changes on the todoeditor's recurrencetab. The original 
patch based the recurrence startdate on the DTSTART-value, now it is based on 
the DTDUE of the first occurence, which makes more sense IMO.

I found out that this patch will break calendars made with KOrganizer-versions 
after 3.2 (because we're using Recurrence-ID for the first time). People 
already using recurrent todo's will see invalid dates on these items. I don't 
think that's critical, they're paying the risk of using betasoftware.

-- 
Bram Schoenmakers

["korganizer_recurtodo.diff" (text/x-diff)]

? calendarview.cpp.backup
? korganizer_kate.kateproject
Index: calendarview.cpp
===================================================================
RCS file: /home/kde/kdepim/korganizer/calendarview.cpp,v
retrieving revision 1.273
diff -B -b -u -p -r1.273 calendarview.cpp
--- calendarview.cpp	26 Jun 2004 13:13:37 -0000	1.273
+++ calendarview.cpp	28 Jun 2004 22:30:28 -0000
@@ -2039,31 +2039,26 @@ void CalendarView::editCanceled( Inciden
 void CalendarView::recurTodo( Todo *todo )
 {
   if (!todo) return;
-  Recurrence *r = todo->recurrence();

+  if ( todo->doesRecur() ) {
+    Recurrence *r = todo->recurrence();
   QDateTime endDateTime = r->endDateTime();
-  if ( ( todo->hasDueDate() && todo->doesRecur() ) &&
-     ( r->duration() == -1 ||
-     ( endDateTime.isValid() && todo->dtDue() < endDateTime ) ) ) {
-
-      int length = 0;
-      if (todo->hasStartDate())
-        length = todo->dtDue().daysTo( todo->dtStart() );
+    QDateTime nextDate = r->getNextDateTime( todo->dtDue() );

-      do {
+    if ( ( r->duration() == -1 || ( nextDate.isValid() && endDateTime.isValid()
+                                    && nextDate <= endDateTime ) ) ) {
+      todo->setDtDue( nextDate );
+      while ( !todo->recursAt( todo->dtDue() ) ||
+               todo->dtDue() <= QDateTime::currentDateTime() ) {
         todo->setDtDue( r->getNextDateTime( todo->dtDue() ) );
-      } while ( !todo->recursAt( todo->dtDue() ) ||
-                 todo->dtDue() <= QDateTime::currentDateTime() );
+      }

-      // prevent setDtStart() from overwriting recurrence's startdate
-      QDateTime oldRecStartDate = r->recurStart();
-      todo->setDtStart( todo->dtDue().addDays( length ) );
-      r->setRecurStart( oldRecStartDate );
       todo->setCompleted( false );
+      todo->setRevision( todo->revision() + 1 );

       return;
   }
-
+  }
   todo->setCompleted( QDateTime::currentDateTime() );
   // incidenceChanged(todo) should be emitted by caller.
 }
Index: koagendaview.cpp
===================================================================
RCS file: /home/kde/kdepim/korganizer/koagendaview.cpp,v
retrieving revision 1.158
diff -B -b -u -p -r1.158 koagendaview.cpp
--- koagendaview.cpp	28 Jun 2004 21:33:18 -0000	1.158
+++ koagendaview.cpp	28 Jun 2004 22:30:29 -0000
@@ -1075,13 +1075,16 @@ void KOAgendaView::insertIncidence( Inci

 void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
 {
+  Todo *todo = dynamic_cast<Todo *>(incidence);
   if ( !calendar()->filter()->filterIncidence( incidence ) ||
-     ( incidence->type() == "Todo" && !KOPrefs::instance()->showAllDayTodo() ) )
+     ( todo && !KOPrefs::instance()->showAllDayTodo() ) )
     return;

   QDate f = mSelectedDates.first();
   QDate l = mSelectedDates.last();
-  QDate startDt = incidence->dtStart().date();
+  QDate startDt;
+  if (todo) todo->dtStart().date();
+  else incidence->dtStart().date();

   if ( incidence->doesRecur() ) {
     DateList::ConstIterator dit;
@@ -1098,9 +1101,11 @@ void KOAgendaView::changeIncidenceDispla
   QDate endDt;
   if ( incidence->type() == "Event" )
     endDt = (static_cast<Event *>(incidence))->dtEnd().date();
-  if ( incidence->type() == "Todo" ) {
-    Todo *todo = static_cast<Todo *>(incidence);
-    endDt = todo->dtDue().date();
+  if ( todo ) {
+    bool overdue = (!todo->isCompleted()) &&
+                   (todo->dtDue() < QDate::currentDate() );
+    endDt = overdue ? QDate::currentDate()
+                    : todo->dtDue().date();
     if ( endDt >= f && endDt <= l ) {
       insertIncidence( incidence, endDt );
       return;
@@ -1208,8 +1213,8 @@ void KOAgendaView::fillAgenda()
         // Already completed items can be displayed on their original due date
         bool overdue = (!todo->isCompleted()) && (todo->dtDue() < today);

-        if ( ((todo->dtDue().date() == currentDate) && !overdue) ||
-             ((currentDate == today) && overdue) ||
+        if ( (( todo->dtDue().date() == currentDate) && !overdue) ||
+             (( currentDate == today) && overdue) ||
              ( todo->recursOn( currentDate ) ) ) {
           if ( todo->doesFloat() || overdue ) {  // Todo has no due-time set or is \
                already overdue
             //kdDebug(5850) << "todo without time:" << todo->dtDueDateStr() << ";" \
                << todo->summary() << endl;
Index: koeditorgeneraltodo.cpp
===================================================================
RCS file: /home/kde/kdepim/korganizer/koeditorgeneraltodo.cpp,v
retrieving revision 1.48
diff -B -b -u -p -r1.48 koeditorgeneraltodo.cpp
--- koeditorgeneraltodo.cpp	8 Jun 2004 12:31:58 -0000	1.48
+++ koeditorgeneraltodo.cpp	28 Jun 2004 22:30:33 -0000
@@ -121,15 +121,15 @@ void KOEditorGeneralTodo::initTime(QWidg
   mStartCheck = new QCheckBox(i18n("Sta&rt:"),timeBoxFrame);
   layoutTimeBox->addWidget(mStartCheck,1,0);
   connect(mStartCheck,SIGNAL(toggled(bool)),SLOT(enableStartEdit(bool)));
-  connect(mStartCheck,SIGNAL(toggled(bool)),SLOT(dateChanged()));
+  connect(mStartCheck,SIGNAL(toggled(bool)),SLOT(startDateModified()));

   mStartDateEdit = new KDateEdit(timeBoxFrame);
   layoutTimeBox->addWidget(mStartDateEdit,1,1);
-  connect(mStartDateEdit,SIGNAL(dateChanged(QDate)),SLOT(dateChanged()));
+  connect(mStartDateEdit,SIGNAL(dateChanged(QDate)),SLOT(startDateModified()));

   mStartTimeEdit = new KTimeEdit(timeBoxFrame);
   layoutTimeBox->addWidget(mStartTimeEdit,1,2);
-  connect(mStartTimeEdit,SIGNAL(timeChanged(QTime)),SLOT(dateChanged()));
+  connect(mStartTimeEdit,SIGNAL(timeChanged(QTime)),SLOT(startDateModified()));

   mTimeButton = new QCheckBox(i18n("Ti&me associated"),timeBoxFrame);
   layoutTimeBox->addMultiCellWidget(mTimeButton,2,2,0,2);
@@ -211,6 +211,7 @@ void KOEditorGeneralTodo::setDefaults(QD

   mStartDateEdit->setDate(QDate::currentDate());
   mStartTimeEdit->setTime(QTime::currentTime());
+  mStartDateModified = false;

   mPriorityCombo->setCurrentItem(2);

@@ -252,15 +253,16 @@ void KOEditorGeneralTodo::readTodo(Todo

   mTimeButton->setChecked( !todo->doesFloat() );

-  alreadyComplete = false;
+  mAlreadyComplete = false;
   mCompletedCombo->setCurrentItem(todo->percentComplete() / 10);
   if (todo->isCompleted() && todo->hasCompletedDate()) {
     mCompleted = todo->completed();
-    alreadyComplete = true;
+    mAlreadyComplete = true;
   }
   setCompletedDate();

   mPriorityCombo->setCurrentItem(todo->priority()-1);
+  mStartDateModified = false;
 }

 void KOEditorGeneralTodo::writeTodo(Todo *todo)
@@ -273,40 +275,52 @@ void KOEditorGeneralTodo::writeTodo(Todo
   todo->setHasDueDate(mDueCheck->isChecked());
   todo->setHasStartDate(mStartCheck->isChecked());

-  QDate tmpDate;
-  QTime tmpTime;
-  QDateTime tmpDT;
+  QDate tmpSDate, tmpDDate;
+  QTime tmpSTime, tmpDTime;
+  QDateTime tmpStartDT, tmpDueDT;
   if ( mTimeButton->isChecked() ) {
     todo->setFloats(false);

     // set due date/time
-    tmpDate = mDueDateEdit->date();
-    tmpTime = mDueTimeEdit->getTime();
-    tmpDT.setDate(tmpDate);
-    tmpDT.setTime(tmpTime);
-    todo->setDtDue(tmpDT);
+    tmpDDate = mDueDateEdit->date();
+    tmpDTime = mDueTimeEdit->getTime();
+    tmpDueDT.setDate(tmpDDate);
+    tmpDueDT.setTime(tmpDTime);

     // set start date/time
-    tmpDate = mStartDateEdit->date();
-    tmpTime = mStartTimeEdit->getTime();
-    tmpDT.setDate(tmpDate);
-    tmpDT.setTime(tmpTime);
-    todo->setDtStart(tmpDT);
+    if ( mStartCheck->isChecked() ) {
+      tmpSDate = mStartDateEdit->date();
+      tmpSTime = mStartTimeEdit->getTime();
+      tmpStartDT.setDate(tmpSDate);
+      tmpStartDT.setTime(tmpSTime);
+    } else {
+      tmpStartDT = tmpDueDT;
+    }
   } else {
     todo->setFloats(true);

     // need to change this.
-    tmpDate = mDueDateEdit->date();
-    tmpTime.setHMS(0,0,0);
-    tmpDT.setDate(tmpDate);
-    tmpDT.setTime(tmpTime);
-    todo->setDtDue(tmpDT);
-
-    tmpDate = mStartDateEdit->date();
-    tmpTime.setHMS(0,0,0);
-    tmpDT.setDate(tmpDate);
-    tmpDT.setTime(tmpTime);
-    todo->setDtStart(tmpDT);
+    tmpDDate = mDueDateEdit->date();
+    tmpDTime.setHMS(0,0,0);
+    tmpDueDT.setDate(tmpDDate);
+    tmpDueDT.setTime(tmpDTime);
+
+    if ( mStartCheck->isChecked() ) {
+      tmpSDate = mStartDateEdit->date();
+      tmpSTime.setHMS(0,0,0);
+      tmpStartDT.setDate(tmpSDate);
+      tmpStartDT.setTime(tmpSTime);
+    } else {
+      tmpStartDT = tmpDueDT;
+    }
+  }
+
+  if ( todo->doesRecur() && !mStartDateModified ) {
+    todo->setDtDue( tmpDueDT );
+  } else {
+      todo->setDtDue( tmpDueDT, true );
+      todo->setDtStart( tmpStartDT );
+      todo->setDtRecurrence( tmpDueDT );
   }

   todo->setPriority(mPriorityCombo->currentItem()+1);
@@ -314,9 +328,12 @@ void KOEditorGeneralTodo::writeTodo(Todo
   // set completion state
   todo->setPercentComplete(mCompletedCombo->currentItem() * 10);

+  // TODO: Can we recur after setting duedate?
   if (mCompletedCombo->currentItem() == 10 && mCompleted.isValid()) {
-    if (! alreadyComplete) emit todoCompleted( todo );
-    else todo->setCompleted(mCompleted);
+    if (! mAlreadyComplete)
+      emit todoCompleted( todo );
+    else
+      todo->setCompleted(mCompleted);
   }
 }

@@ -455,6 +472,14 @@ void KOEditorGeneralTodo::dateChanged()
   }

   emit dateTimeStrChanged( dateTimeStr );
+  QDateTime endDt( mDueDateEdit->date(), mDueTimeEdit->getTime() );
+  emit signalDateTimeChanged( endDt, endDt );
+}
+
+void KOEditorGeneralTodo::startDateModified()
+{
+  mStartDateModified = true;
+  dateChanged();
 }

 void KOEditorGeneralTodo::setCompletedDate()
Index: koeditorgeneraltodo.h
===================================================================
RCS file: /home/kde/kdepim/korganizer/koeditorgeneraltodo.h,v
retrieving revision 1.29
diff -B -b -u -p -r1.29 koeditorgeneraltodo.h
--- koeditorgeneraltodo.h	8 Jun 2004 12:31:58 -0000	1.29
+++ koeditorgeneraltodo.h	28 Jun 2004 22:30:33 -0000
@@ -67,10 +67,12 @@ class KOEditorGeneralTodo : public KOEdi
     void todoCompleted( Todo * );
     void dueDateEditToggle( bool );
     void dateTimeStrChanged( const QString & );
+    void signalDateTimeChanged( QDateTime, QDateTime );

   protected slots:
     void completedChanged(int);
     void dateChanged();
+    void startDateModified();

     void enableDueEdit( bool enable );
     void enableStartEdit( bool enable );
@@ -81,7 +83,8 @@ class KOEditorGeneralTodo : public KOEdi
     void setCompletedDate();

  private:
-    bool                    alreadyComplete;
+    bool                    mAlreadyComplete;
+    bool                    mStartDateModified;

     KDateEdit               *mStartDateEdit;
     KTimeEdit               *mStartTimeEdit;
Index: koeditorrecurrence.cpp
===================================================================
RCS file: /home/kde/kdepim/korganizer/koeditorrecurrence.cpp,v
retrieving revision 1.67
diff -B -b -u -p -r1.67 koeditorrecurrence.cpp
--- koeditorrecurrence.cpp	19 Jun 2004 23:22:27 -0000	1.67
+++ koeditorrecurrence.cpp	28 Jun 2004 22:30:33 -0000
@@ -1009,9 +1009,13 @@ void KOEditorRecurrence::readIncidence(I
   int day = 0;
   int count = 0;
   int month = 0;
-  setDefaults( incidence->dtStart(), incidence->dtEnd(), incidence->doesFloat() );

-  setDateTimes( incidence->dtStart(), incidence->dtEnd() );
+  if ( incidence->type() == "Todo" ) {
+    Todo *todo = static_cast<Todo *>(incidence);
+    setDefaults( todo->dtStart(true), todo->dtDue(), todo->doesFloat() );
+  } else {
+    setDefaults( incidence->dtStart(), incidence->dtEnd(), incidence->doesFloat() );
+  }

   int recurs = incidence->doesRecur();
   int f = 0;
@@ -1134,6 +1138,8 @@ void KOEditorRecurrence::readIncidence(I

   mRecurrenceChooser->setType( recurrenceType );
   showCurrentRule( recurrenceType );
+  mType = mRecurrenceChooser->type();
+  kdDebug(5850) << "mType set to " << mType << endl;

   mRecurrenceRange->setDateTimes( incidence->recurrence()->recurStart() );

@@ -1147,14 +1153,23 @@ void KOEditorRecurrence::readIncidence(I

 void KOEditorRecurrence::writeIncidence( Incidence *incidence )
 {
-  if ( !mEnabledCheck->isChecked() )
+  if ( !mEnabledCheck->isChecked() || !isEnabled() )
   {
-    if (incidence->doesRecur())
+    if ( incidence->doesRecur() )
         incidence->recurrence()->unsetRecurs();
     return;
   }

   Recurrence *r = incidence->recurrence();
+  kdDebug(5850) << "mType=" << mType << " mRecurrenceChooser->type()=" << \
mRecurrenceChooser->type() << endl; +  if ( incidence->type() == "Todo" && mType != \
mRecurrenceChooser->type() ) { +    Todo *todo = static_cast<Todo *>(incidence);
+    if ( todo->hasStartDate() ) {
+      // make relative startdate absolute
+      todo->setDtStart( todo->dtStart() );
+    }
+      todo->setDtDue( todo->dtDue(), true );
+  }

   // clear out any old settings;
   r->unsetRecurs();
@@ -1232,6 +1246,11 @@ void KOEditorRecurrence::writeIncidence(
       }
     } // end "Yearly"

+    if ( incidence->type() == "Todo" ) {
+      Todo *todo = static_cast<Todo *>(incidence);
+      todo->setHasStartDate( todo->hasStartDate() );
+    }
+
     incidence->setExDates( mExceptions->dates() );
 }

Index: koeditorrecurrence.h
===================================================================
RCS file: /home/kde/kdepim/korganizer/koeditorrecurrence.h,v
retrieving revision 1.26
diff -B -b -u -p -r1.26 koeditorrecurrence.h
--- koeditorrecurrence.h	19 Jun 2004 23:22:27 -0000	1.26
+++ koeditorrecurrence.h	28 Jun 2004 22:30:33 -0000
@@ -308,6 +308,8 @@ class KOEditorRecurrence : public QWidge
     void showRecurrenceRangeDialog();

   private:
+    int mType; // contains type when opening editor
+
     QCheckBox *mEnabledCheck;

     QGroupBox *mTimeGroupBox;
Index: koeventviewer.cpp
===================================================================
RCS file: /home/kde/kdepim/korganizer/koeventviewer.cpp,v
retrieving revision 1.47
diff -B -b -u -p -r1.47 koeventviewer.cpp
--- koeventviewer.cpp	17 Jun 2004 21:32:01 -0000	1.47
+++ koeventviewer.cpp	28 Jun 2004 22:30:33 -0000
@@ -150,11 +150,18 @@ void KOEventViewer::appendTodo( Todo *to
                      .arg( todo->percentComplete() ) );

   if ( todo->doesRecur() ) {
+    QString tmp;
+    if ( todo->doesFloat() ) {
+      QDate d = todo->recurrence()->getNextDate( QDate::currentDate() );
+      tmp = KGlobal::locale()->formatDate( d, true );
+    } else {
     QDateTime dt = todo->recurrence()->getNextDateTime(
                                          QDateTime::currentDateTime() );
+      tmp = KGlobal::locale()->formatDateTime(dt, true );
+    }
     addTag( "p", "<em>" +
-      i18n("This is a recurring todo. The next occurrence will be on %1.").arg(
-      KGlobal::locale()->formatDateTime( dt, true ) ) + "</em>" );
+      i18n("This is a recurring todo. The next occurrence will be on ") + tmp +
+           "</em>" );
   }
   formatReadOnly( todo );
   formatAttendees( todo );
Index: kotodoeditor.cpp
===================================================================
RCS file: /home/kde/kdepim/korganizer/kotodoeditor.cpp,v
retrieving revision 1.67
diff -B -b -u -p -r1.67 kotodoeditor.cpp
--- kotodoeditor.cpp	20 Jun 2004 12:26:42 -0000	1.67
+++ kotodoeditor.cpp	28 Jun 2004 22:30:33 -0000
@@ -70,6 +70,8 @@ void KOTodoEditor::init()

   connect( mGeneral, SIGNAL( dateTimeStrChanged( const QString & ) ),
            mRecurrence, SLOT( setDateTimeStr( const QString & ) ) );
+  connect( mGeneral, SIGNAL( signalDateTimeChanged( QDateTime, QDateTime ) ),
+           mRecurrence, SLOT( setDateTimes( QDateTime, QDateTime ) ) );
 }

 void KOTodoEditor::reload()
@@ -295,13 +297,16 @@ void KOTodoEditor::setDefaults( QDateTim
     mGeneral->setDefaults( due, allDay );

   mDetails->setDefaults();
-  mRecurrence->setDefaults(QDateTime::currentDateTime(), due, false);
+  if ( mTodo )
+    mRecurrence->setDefaults( mTodo->dtStart(), due, false );
+  else
+    mRecurrence->setDefaults( QDateTime::currentDateTime(), due, false );
   mAttachments->setDefaults();
 }

 void KOTodoEditor::readTodo( Todo *todo )
 {
-kdDebug()<<"read todo"<<endl;
+  kdDebug()<<"read todo"<<endl;
   mGeneral->readTodo( todo );
   mDetails->readEvent( todo );
   mRecurrence->readIncidence( todo );
@@ -313,20 +318,11 @@ kdDebug()<<"read todo"<<endl;

 void KOTodoEditor::writeTodo( Todo *todo )
 {
-  // prevent mGeneral overwriting startdate recurrence
-  Recurrence *r = todo->recurrence();
-  QDateTime oldRecStartDate;
-  if ( todo->doesRecur() )
-    oldRecStartDate = r->recurStart();
-
   mGeneral->writeTodo( todo );
   mDetails->writeEvent( todo );
   mRecurrence->writeIncidence( todo );
   mAttachments->writeIncidence( todo );

-  oldRecStartDate.isValid() ? r->setRecurStart( oldRecStartDate )
-                            : r->setRecurStart( todo->dtDue() );
-
   // set related event, i.e. parent to-do in this case.
   if ( mRelatedTodo ) {
     todo->setRelatedTo( mRelatedTodo );
Index: kotodoeditor.h
===================================================================
RCS file: /home/kde/kdepim/korganizer/kotodoeditor.h,v
retrieving revision 1.31
diff -B -b -u -p -r1.31 kotodoeditor.h
Index: kotodoview.cpp
===================================================================
RCS file: /home/kde/kdepim/korganizer/kotodoview.cpp,v
retrieving revision 1.161
diff -B -b -u -p -r1.161 kotodoview.cpp
--- kotodoview.cpp	27 Jun 2004 14:57:54 -0000	1.161
+++ kotodoview.cpp	28 Jun 2004 22:30:33 -0000
@@ -778,15 +778,13 @@ void KOTodoView::setNewDate(QDate date)
       dt.setTime( todo->dtDue().time() );

     Todo *oldTodo = todo->clone();
-    if ( !todo->hasDueDate() )
-      todo->setHasDueDate( true );

     if ( date.isNull() )
       todo->setHasDueDate( false );
+    else if ( !todo->hasDueDate() )
+      todo->setHasDueDate( true );
     todo->setDtDue( dt );
-
-    if ( todo->doesRecur() )
-      todo->recurrence()->setRecurStart( todo->dtDue() );
+    todo->setRevision( todo->revision() + 1 );

     mActiveItem->construct();
     emit incidenceChanged( oldTodo, todo, KOGlobals::DATE_MODIFIED );


["libkcal_recurtodo.diff" (text/x-diff)]

Index: icalformatimpl.cpp
===================================================================
RCS file: /home/kde/kdepim/libkcal/icalformatimpl.cpp,v
retrieving revision 1.104
diff -B -b -u -p -r1.104 icalformatimpl.cpp
--- icalformatimpl.cpp	12 Jun 2004 17:21:20 -0000	1.104
+++ icalformatimpl.cpp	28 Jun 2004 22:29:56 -0000
@@ -361,22 +361,22 @@ icalcomponent *ICalFormatImpl::writeTodo
   if (todo->hasDueDate()) {
     icaltimetype due;
     if (todo->doesFloat()) {
-      due = writeICalDate(todo->dtDue().date());
+      due = writeICalDate(todo->dtDue(true).date());
     } else {
-      due = writeICalDateTime(todo->dtDue());
+      due = writeICalDateTime(todo->dtDue(true));
     }
     icalcomponent_add_property(vtodo,icalproperty_new_due(due));
   }
 
   // start time
-  if (todo->hasStartDate()) {
+  if ( todo->hasStartDate() || todo->doesRecur() ) {
     icaltimetype start;
     if (todo->doesFloat()) {
 //      kdDebug(5800) << " Incidence " << todo->summary() << " floats." << endl;
-      start = writeICalDate(todo->dtStart().date());
+      start = writeICalDate(todo->dtStart(true).date());
     } else {
 //      kdDebug(5800) << " incidence " << todo->summary() << " has time." << endl;
-      start = writeICalDateTime(todo->dtStart());
+      start = writeICalDateTime(todo->dtStart(true));
     }
     icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start));
   }
@@ -395,6 +395,9 @@ icalcomponent *ICalFormatImpl::writeTodo
   icalcomponent_add_property(vtodo,
       icalproperty_new_percentcomplete(todo->percentComplete()));
 
+  icalcomponent_add_property(vtodo,
+      icalproperty_new_recurrenceid( writeICalDateTime( todo->dtDue())));
+
   return vtodo;
 }
 
@@ -1105,11 +1108,11 @@ Todo *ICalFormatImpl::readTodo(icalcompo
         icaltime = icalproperty_get_due(p);
         readTzidParameter(p,icaltime);
         if (icaltime.is_date) {
-          todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
+          todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0)),true);
           todo->setFloats(true);
 
         } else {
-          todo->setDtDue(readICalDateTime(icaltime));
+          todo->setDtDue(readICalDateTime(icaltime),true);
           todo->setFloats(false);
         }
         todo->setHasDueDate(true);
@@ -1130,9 +1133,19 @@ Todo *ICalFormatImpl::readTodo(icalcompo
         mTodosRelate.append(todo);
         break;
 
-      case ICAL_DTSTART_PROPERTY:
+      case ICAL_DTSTART_PROPERTY: {
         // Flag that todo has start date. Value is read in by readIncidence().
-        todo->setHasStartDate(true);
+        if ( todo->comments().grep("NoStartDate").count() )
+          todo->setHasStartDate( false );
+        else
+          todo->setHasStartDate( true );
+        break;
+      }
+
+      case ICAL_RECURRENCEID_PROPERTY:
+        icaltime = icalproperty_get_recurrenceid(p);
+        readTzidParameter(p,icaltime);
+        todo->setDtRecurrence( readICalDateTime(icaltime) );
         break;
 
       default:
Index: incidence.cpp
===================================================================
RCS file: /home/kde/kdepim/libkcal/incidence.cpp,v
retrieving revision 1.45
diff -B -b -u -p -r1.45 incidence.cpp
--- incidence.cpp	12 Jun 2004 17:21:20 -0000	1.45
+++ incidence.cpp	28 Jun 2004 22:29:56 -0000
@@ -187,7 +187,7 @@ int Incidence::revision() const
 void Incidence::setDtStart(const QDateTime &dtStart)
 {
   if (mRecurrence)
-    mRecurrence->setRecurStart( dtStart);
+    mRecurrence->setRecurStart( dtStart );
   IncidenceBase::setDtStart( dtStart );
 }
 
Index: incidencebase.h
===================================================================
RCS file: /home/kde/kdepim/libkcal/incidencebase.h,v
retrieving revision 1.20
diff -B -b -u -p -r1.20 incidencebase.h
--- incidencebase.h	5 Jun 2004 01:14:15 -0000	1.20
+++ incidencebase.h	28 Jun 2004 22:29:56 -0000
@@ -74,16 +74,16 @@ class IncidenceBase : public CustomPrope
     /** for setting the event's starting date/time with a QDateTime. */
     virtual void setDtStart( const QDateTime &dtStart );
     /** returns an event's starting date/time as a QDateTime. */
-    QDateTime dtStart() const;
+    virtual QDateTime dtStart() const;
     /** returns an event's starting time as a string formatted according to the
      users locale settings */
-    QString dtStartTimeStr() const;
+    virtual QString dtStartTimeStr() const;
     /** returns an event's starting date as a string formatted according to the
      users locale settings */
-    QString dtStartDateStr( bool shortfmt = true ) const;
+    virtual QString dtStartDateStr( bool shortfmt = true ) const;
     /** returns an event's starting date and time as a string formatted according
      to the users locale settings */
-    QString dtStartStr() const;
+    virtual QString dtStartStr() const;
 
     virtual void setDuration( int seconds );
     int duration() const;
Index: recurrence.cpp
===================================================================
RCS file: /home/kde/kdepim/libkcal/recurrence.cpp,v
retrieving revision 1.41
diff -B -b -u -p -r1.41 recurrence.cpp
--- recurrence.cpp	9 Jun 2004 19:52:12 -0000	1.41
+++ recurrence.cpp	28 Jun 2004 22:29:56 -0000
@@ -1245,7 +1245,7 @@ QDate Recurrence::getNextDateNoTime(cons
   if (rDuration >= 0 && nextDate.isValid()) {
     // Check that the date found is within the range of the recurrence
     QDate end = endDate();
-    if (nextDate > end)
+    if ( nextDate > end )
       return QDate();
     if (last  &&  nextDate == end)
       *last = true;
Index: recurrence.h
===================================================================
RCS file: /home/kde/kdepim/libkcal/recurrence.h,v
retrieving revision 1.35
diff -B -b -u -p -r1.35 recurrence.h
Index: todo.cpp
===================================================================
RCS file: /home/kde/kdepim/libkcal/todo.cpp,v
retrieving revision 1.20
diff -B -b -u -p -r1.20 todo.cpp
--- todo.cpp	19 Dec 2003 17:00:05 -0000	1.20
+++ todo.cpp	28 Jun 2004 22:29:56 -0000
@@ -44,6 +44,7 @@ Todo::Todo(const Todo &t) : Incidence(t)
   mCompleted = t.mCompleted;
   mHasCompletedDate = t.mHasCompletedDate;
   mPercentComplete = t.mPercentComplete;
+  mDtRecurrence = t.mDtRecurrence;
 }
 
 Todo::~Todo()
@@ -68,7 +69,7 @@ bool Todo::operator==( const Todo& t2 ) 
         percentComplete() == t2.percentComplete();
 }
 
-void Todo::setDtDue(const QDateTime &dtDue)
+void Todo::setDtDue(const QDateTime &dtDue, bool first )
 {
   //int diffsecs = mDtDue.secsTo(dtDue);
 
@@ -79,7 +80,15 @@ void Todo::setDtDue(const QDateTime &dtD
       alarm->setTime(alarm->time().addSecs(diffsecs));
     }
   }*/
+  if( doesRecur() && !first ) {
+    mDtRecurrence = dtDue;
+  } else {
   mDtDue = dtDue;
+    recurrence()->setRecurStart( dtDue );
+  }
+
+  if ( doesRecur() && dtDue < recurrence()->recurStart() )
+    recurrence()->setRecurStart( dtDue );
 
   //kdDebug(5800) << "setDtDue says date is " << mDtDue.toString() << endl;
 
@@ -90,24 +99,27 @@ void Todo::setDtDue(const QDateTime &dtD
   updated();
 }
 
-QDateTime Todo::dtDue() const
+QDateTime Todo::dtDue( bool first ) const
 {
+  if ( doesRecur() && !first )
+    return mDtRecurrence;
+  else
   return mDtDue;
 }
 
 QString Todo::dtDueTimeStr() const
 {
-  return KGlobal::locale()->formatTime(mDtDue.time());
+  return KGlobal::locale()->formatTime( dtDue(!doesRecur()).time() );
 }
 
 QString Todo::dtDueDateStr(bool shortfmt) const
 {
-  return KGlobal::locale()->formatDate(mDtDue.date(),shortfmt);
+  return KGlobal::locale()->formatDate(dtDue( !doesRecur() ).date(),shortfmt);
 }
 
 QString Todo::dtDueStr() const
 {
-  return KGlobal::locale()->formatDateTime(mDtDue);
+  return KGlobal::locale()->formatDateTime( dtDue( !doesRecur() ) );
 }
 
 bool Todo::hasDueDate() const
@@ -131,10 +143,47 @@ bool Todo::hasStartDate() const
 void Todo::setHasStartDate(bool f)
 {
   if (mReadOnly) return;
+
+  if ( doesRecur() && !f ) {
+    if ( !comments().grep("NoStartDate").count() )
+      addComment("NoStartDate");
+  } else {
+    QString s("NoStartDate");
+    removeComment(s);
+  }
   mHasStartDate = f;
   updated();
 }
 
+QDateTime Todo::dtStart( bool first ) const
+{
+  if ( doesRecur() && !first )
+    return mDtRecurrence.addDays( dtDue( true ).daysTo( IncidenceBase::dtStart() ) );
+  else
+    return IncidenceBase::dtStart();
+}
+
+void Todo::setDtStart( const QDateTime &dtStart )
+{
+  if ( doesRecur() )
+    recurrence()->setRecurStart( mDtDue );
+  IncidenceBase::setDtStart( dtStart );
+}
+
+QString Todo::dtStartTimeStr( bool first ) const
+{
+  return KGlobal::locale()->formatTime(dtStart(first).time());
+}
+
+QString Todo::dtStartDateStr(bool shortfmt, bool first) const
+{
+  return KGlobal::locale()->formatDate(dtStart(first).date(),shortfmt);
+}
+
+QString Todo::dtStartStr(bool first) const
+{
+  return KGlobal::locale()->formatDateTime(dtStart(first));
+}
 
 bool Todo::isCompleted() const
 {
@@ -183,3 +232,12 @@ void Todo::setPercentComplete(int v)
   updated();
 }
 
+void Todo::setDtRecurrence( const QDateTime &dt )
+{
+  mDtRecurrence = dt;
+}
+
+QDateTime Todo::dtRecurrence() const
+{
+  return mDtRecurrence;
+}
Index: todo.h
===================================================================
RCS file: /home/kde/kdepim/libkcal/todo.h,v
retrieving revision 1.17
diff -B -b -u -p -r1.17 todo.h
--- todo.h	19 Dec 2003 17:00:05 -0000	1.17
+++ todo.h	28 Jun 2004 22:29:56 -0000
@@ -48,12 +48,18 @@ class Todo : public Incidence
 
     /**
       Set due date and time.
+
+      @param dtDue The due date/time.
+      @param first Set the date of the first occurence (if the todo is recurrent).
     */
-    void setDtDue(const QDateTime &dtDue);
+    void setDtDue(const QDateTime &dtDue, bool first = false);
     /**
       Return due date and time.
+
+      @param first Return the due date of the first occurence, else return the
+      recursion date (only if todo is recurrent).
     */
-    QDateTime dtDue() const;
+    QDateTime dtDue( bool first = false ) const;
     /**
       Return due time as string formatted according to the users locale
       settings.
@@ -96,6 +102,27 @@ class Todo : public Incidence
     void setHasStartDate( bool hasStartDate );
 
     /**
+      Returns the startdate relative to the recurrence-ID. If the argument is
+      true or the todo does not recur, the normal startdate will be returned.
+    */
+    QDateTime dtStart( bool first = false ) const;
+
+    /**
+      Sets the startdate of the todo.
+    */
+    void setDtStart( const QDateTime &dtStart );
+
+    /** returns an todo's starting time as a string formatted according to the
+     users locale settings */
+    QString dtStartTimeStr( bool first = false ) const;
+    /** returns an todo's starting date as a string formatted according to the
+     users locale settings */
+    QString dtStartDateStr( bool shortfmt = true, bool first = false ) const;
+    /** returns an todo's starting date and time as a string formatted according
+     to the users locale settings */
+    QString dtStartStr( bool first = false ) const;
+
+    /**
       Return true if the todo is 100% completed, otherwise return false.
     */
     bool isCompleted() const;
@@ -138,10 +165,22 @@ class Todo : public Incidence
     */
     bool hasCompletedDate() const;
     
+    /**
+      Sets the due date/time of the current occurence if recurrent.
+    */
+    void setDtRecurrence( const QDateTime &dt );
+
+    /**
+      Returns the due date/time of the current occurence if recurrent.
+    */
+    QDateTime dtRecurrence() const;
+
   private:
     bool accept(Visitor &v) { return v.visit( this ); }
 
     QDateTime mDtDue;                    // due date of todo
+                                         // (first occurence if recurrent)
+    QDateTime mDtRecurrence;             // due date of recurrence
 
     bool mHasDueDate;                    // if todo has associated due date
     bool mHasStartDate;                  // if todo has associated start date


_______________________________________________
kde-pim mailing list
kde-pim@mail.kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
kde-pim home page at http://pim.kde.org/

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic