Exemple #1
0
void CompatPre32::fixRecurrence( const Incidence::Ptr &incidence )
{
  Recurrence *recurrence = incidence->recurrence();
  if ( recurrence->recurs() &&  recurrence->duration() > 0 ) {
    recurrence->setDuration( recurrence->duration() + incidence->recurrence()->exDates().count() );
  }
  // Call base class method now that everything else is done
  CompatPre35::fixRecurrence( incidence );
}
Exemple #2
0
void CompatPre35::fixRecurrence( const Incidence::Ptr &incidence )
{
  Recurrence *recurrence = incidence->recurrence();
  if ( recurrence ) {
    KDateTime start( incidence->dtStart() );
    // kde < 3.5 only had one rrule, so no need to loop over all RRULEs.
    RecurrenceRule *r = recurrence->defaultRRule();
    if ( r && !r->dateMatchesRules( start ) ) {
      recurrence->addExDateTime( start );
    }
  }

  // Call base class method now that everything else is done
  Compat::fixRecurrence( incidence );
}
Exemple #3
0
/******************************************************************************
* Get the previous time the recurrence occurred, strictly before a specified time.
*/
QDateTime KARecurrence::getPreviousDateTime(const QDateTime &afterDateTime) const
{
    switch(type())
    {
        case ANNUAL_DATE:
        case ANNUAL_POS:
        {
            Recurrence recur;
            writeRecurrence(recur);
            return recur.getPreviousDateTime(afterDateTime);
        }
        default:
            return Recurrence::getPreviousDateTime(afterDateTime);
    }
}
Exemple #4
0
/******************************************************************************
* Get the next time the recurrence occurs, strictly after a specified time.
*/
QDateTime KARecurrence::getNextDateTime(const QDateTime &preDateTime) const
{
    switch(type())
    {
        case ANNUAL_DATE:
        case ANNUAL_POS:
        {
            Recurrence recur;
            writeRecurrence(recur);
            return recur.getNextDateTime(preDateTime);
        }
        default:
            return Recurrence::getNextDateTime(preDateTime);
    }
}
Exemple #5
0
//@cond PRIVATE
bool Todo::Private::recurTodo( Todo *todo )
{
  if ( todo->recurs() ) {
    Recurrence *r = todo->recurrence();
    KDateTime endDateTime = r->endDateTime();
    KDateTime nextDate = r->getNextDateTime( todo->dtDue() );

    if ( ( r->duration() == -1 ||
           ( nextDate.isValid() && endDateTime.isValid() &&
             nextDate <= endDateTime ) ) ) {

      while ( !todo->recursAt( nextDate ) ||
              nextDate <= KDateTime::currentUtcDateTime() ) {

        if ( !nextDate.isValid() ||
             ( nextDate > endDateTime && r->duration() != -1 ) ) {

          return false;
        }

        nextDate = r->getNextDateTime( nextDate );
      }

      todo->setDtDue( nextDate );
      todo->setCompleted( false );
      todo->setRevision( todo->revision() + 1 );

      return true;
    }
  }

  return false;
}
Exemple #6
0
void KOWhatsNextView::updateView()
{
  KIconLoader kil("kdepim");
  QString *ipath = new QString();
  kil.loadIcon("kdepim",KIcon::NoGroup,32,KIcon::DefaultState,ipath);

  mText = "<table width=\"100%\">\n";
  mText += "<tr bgcolor=\"#3679AD\"><td><h1>";
  mText += "<img src=\"";
  mText += *ipath;
  mText += "\">";
  mText += "<font color=\"white\"> ";
  mText += i18n("What's Next?") + "</font></h1>";
  mText += "</td></tr>\n<tr><td>";

  mText += "<h2>";
  if ( mStartDate.daysTo( mEndDate ) < 1 ) {
    mText += KGlobal::locale()->formatDate( mStartDate );
  } else {
    mText += i18n("Date from - to", "%1 - %2")
            .arg( KGlobal::locale()->formatDate( mStartDate ) )
            .arg( KGlobal::locale()->formatDate( mEndDate ) );
  }
  mText+="</h2>\n";

  Event::List events;
  for ( QDate date = mStartDate; date <= mEndDate; date = date.addDays( 1 ) )
    events += calendar()->events(date, EventSortStartDate, SortDirectionAscending);

  if (events.count() > 0) {
    mText += "<p></p>";
    kil.loadIcon("appointment",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
    mText += "<h2><img src=\"";
    mText += *ipath;
    mText += "\">";
    mText += i18n("Events:") + "</h2>\n";
    mText += "<table>\n";
    Event::List::ConstIterator it;
    for( it = events.begin(); it != events.end(); ++it ) {
      Event *ev = *it;
      if ( !ev->doesRecur() ){
        appendEvent(ev);
      } else {
        // FIXME: This should actually be cleaned up. Libkcal should
        // provide a method to return a list of all recurrences in a
        // given time span.
        Recurrence *recur = ev->recurrence();
        int duration = ev->dtStart().secsTo( ev->dtEnd() );
        QDateTime start = recur->getPreviousDateTime(
                                QDateTime( mStartDate, QTime() ) );
        QDateTime end = start.addSecs( duration );
        if ( end.date() >= mStartDate ) {
          appendEvent( ev, start, end );
        }
        start = recur->getNextDateTime( start );
        while ( start.isValid() && start.date() <= mEndDate ) {
          appendEvent( ev, start );
          start = recur->getNextDateTime( start );
        }
      }
    }
    mText += "</table>\n";
  }

  mTodos.clear();
  Todo::List todos = calendar()->todos( TodoSortDueDate, SortDirectionAscending );
  if ( todos.count() > 0 ) {
    kil.loadIcon("todo",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
    mText += "<h2><img src=\"";
    mText += *ipath;
    mText += "\">";
    mText += i18n("To-do:") + "</h2>\n";
    mText += "<ul>\n";
    Todo::List::ConstIterator it;
    for( it = todos.begin(); it != todos.end(); ++it ) {
      Todo *todo = *it;
      if ( !todo->isCompleted() && todo->hasDueDate() && todo->dtDue().date() <= mEndDate )
                  appendTodo(todo);
    }
    bool gotone = false;
    int priority = 1;
    while (!gotone && priority<=9 ) {
      for( it = todos.begin(); it != todos.end(); ++it ) {
        Todo *todo = *it;
        if (!todo->isCompleted() && (todo->priority() == priority) ) {
          appendTodo(todo);
          gotone = true;
        }
      }
      priority++;
      kdDebug(5850) << "adding the todos..." << endl;
    }
    mText += "</ul>\n";
  }

  QStringList myEmails( KOPrefs::instance()->allEmails() );
  int replies = 0;
  events = calendar()->events( QDate::currentDate(), QDate(2975,12,6) );
  Event::List::ConstIterator it2;
  for( it2 = events.begin(); it2 != events.end(); ++it2 ) {
    Event *ev = *it2;
    Attendee *me = ev->attendeeByMails( myEmails );
    if (me!=0) {
      if (me->status()==Attendee::NeedsAction && me->RSVP()) {
        if (replies == 0) {
          mText += "<p></p>";
          kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
          mText += "<h2><img src=\"";
          mText += *ipath;
          mText += "\">";
          mText += i18n("Events and to-dos that need a reply:") + "</h2>\n";
          mText += "<table>\n";
        }
        replies++;
        appendEvent( ev );
      }
    }
  }
  todos = calendar()->todos();
  Todo::List::ConstIterator it3;
  for( it3 = todos.begin(); it3 != todos.end(); ++it3 ) {
    Todo *to = *it3;
    Attendee *me = to->attendeeByMails( myEmails );
    if (me!=0) {
      if (me->status()==Attendee::NeedsAction && me->RSVP()) {
        if (replies == 0) {
          mText += "<p></p>";
          kil.loadIcon("reply",KIcon::NoGroup,22,KIcon::DefaultState,ipath);
          mText += "<h2><img src=\"";
          mText += *ipath;
          mText += "\">";
          mText += i18n("Events and to-dos that need a reply:") + "</h2>\n";
          mText += "<table>\n";
        }
        replies++;
        appendEvent(to);
      }
    }
    kdDebug () << "check for todo-replies..." << endl;
  }
  if (replies > 0 ) mText += "</table>\n";


  mText += "</td></tr>\n</table>\n";

  kdDebug(5850) << "KOWhatsNextView::updateView: text: " << mText << endl;

  delete ipath;

  mView->setText(mText);
}
Exemple #7
0
void CompatPre31::fixRecurrence( const Incidence::Ptr &incidence )
{
  CompatPre32::fixRecurrence( incidence );

  Recurrence *recur = incidence->recurrence();
  RecurrenceRule *r = 0;
  if ( recur ) {
    r = recur->defaultRRule();
  }
  if ( recur && r ) {
    int duration = r->duration();
    if ( duration > 0 ) {
      // Backwards compatibility for KDE < 3.1.
      // rDuration was set to the number of time periods to recur,
      // with week start always on a Monday.
      // Convert this to the number of occurrences.
      r->setDuration( -1 );
      QDate end( r->startDt().date() );
      bool doNothing = false;
      // # of periods:
      int tmp = ( duration - 1 ) * r->frequency();
      switch ( r->recurrenceType() ) {
      case RecurrenceRule::rWeekly:
      {
        end = end.addDays( tmp * 7 + 7 - end.dayOfWeek() );
        break;
      }
      case RecurrenceRule::rMonthly:
      {
        int month = end.month() - 1 + tmp;
        end.setDate( end.year() + month / 12, month % 12 + 1, 31 );
        break;
      }
      case RecurrenceRule::rYearly:
      {
        end.setDate( end.year() + tmp, 12, 31 );
        break;
      }
      default:
        doNothing = true;
        break;
      }
      if ( !doNothing ) {
        duration = r->durationTo(
          KDateTime( end, QTime( 0, 0, 0 ), incidence->dtStart().timeSpec() ) );
        r->setDuration( duration );
      }
    }

    /* addYearlyNum */
    // Dates were stored as day numbers, with a fiddle to take account of
    // leap years. Convert the day number to a month.
    QList<int> days = r->byYearDays();
    if ( !days.isEmpty() ) {
      QList<int> months = r->byMonths();
      for ( int i = 0; i < months.size(); ++i ) {
        int newmonth =
          QDate( r->startDt().date().year(), 1, 1 ).addDays( months.at( i ) - 1 ).month();
        if ( !months.contains( newmonth ) ) {
          months.append( newmonth );
        }
      }

      r->setByMonths( months );
      days.clear();
      r->setByYearDays( days );
    }
  }
}
void KCalResourceSlox::parseRecurrence( const QDomNode &node, Event *event )
{
  QString type;

  int dailyValue = -1;
  KDateTime end;

  int weeklyValue = -1;
  QBitArray days( 7 ); // days, starting with monday
  bool daysSet = false;

  int monthlyValueDay = -1;
  int monthlyValueMonth = -1;

  int yearlyValueDay = -1;
  int yearlyMonth = -1;

  int monthly2Recurrency = 0;
  int monthly2Day = 0;
  int monthly2ValueMonth = -1;

  int yearly2Recurrency = 0;
  int yearly2Day = 0;
  int yearly2Month = -1;

  DateList deleteExceptions;

  QDomNode n;

  for( n = node.firstChild(); !n.isNull(); n = n.nextSibling() ) {
    QDomElement e = n.toElement();
    QString tag = e.tagName();
    QString text = decodeText( e.text() );
    kDebug() << tag << ":" << text;

    if ( tag == fieldName( RecurrenceType ) ) {
      type = text;
    } else if ( tag == "daily_value" ) {
      dailyValue = text.toInt();
    } else if ( tag == fieldName( RecurrenceEnd ) ) {
      end = WebdavHandler::sloxToKDateTime( text );
    } else if ( tag == "weekly_value" ) {
      weeklyValue = text.toInt();
    } else if ( tag.left( 11 ) == "weekly_day_" ) {
      int day = tag.mid( 11, 1 ).toInt();
      int index;
      if ( day == 1 ) index = 0;
      else index = day - 2;
      days.setBit( index );
    } else if ( tag == "monthly_value_day" ) {
      monthlyValueDay = text.toInt();
    } else if ( tag == "monthly_value_month" ) {
      monthlyValueMonth = text.toInt();
    } else if ( tag == "yearly_value_day" ) {
      yearlyValueDay = text.toInt();
    } else if ( tag == "yearly_month" ) {
      yearlyMonth = text.toInt();
    } else if ( tag == "monthly2_recurrency" ) {
      monthly2Recurrency = text.toInt();
    } else if ( tag == "monthly2_day" ) {
      monthly2Day = text.toInt();
    } else if ( tag == "monthly2_value_month" ) {
      monthly2ValueMonth = text.toInt();
    } else if ( tag == "yearly2_reccurency" ) { // this is not a typo, this is what SLOX really sends!
      yearly2Recurrency = text.toInt();
    } else if ( tag == "yearly2_day" ) {
      yearly2Day = text.toInt();
    } else if ( tag == "yearly2_month" ) {
      yearly2Month = text.toInt() + 1;
    // OX recurrence fields
    } else if ( tag == "interval" ) {
      dailyValue = text.toInt();
      weeklyValue = text.toInt();
      monthlyValueMonth = text.toInt();
      monthly2ValueMonth = text.toInt();
    } else if ( tag == "days" ) {
      int tmp = text.toInt();  // OX encodes days binary: 1=Su, 2=Mo, 4=Tu, ...
      for ( int i = 0; i < 7; ++i ) {
        if ( tmp & (1 << i) )
          days.setBit( (i + 6) % 7 );
      }
      daysSet = true;
    } else if ( tag == "day_in_month" ) {
      monthlyValueDay = text.toInt();
      monthly2Recurrency = text.toInt();
      yearlyValueDay = text.toInt();
      yearly2Recurrency = text.toInt();
    } else if ( tag == "month" ) {
      yearlyMonth = text.toInt() + 1; // starts at 0
      yearly2Month = text.toInt() + 1;
    } else if ( tag == fieldName( RecurrenceDelEx ) ) {
      QStringList exdates = text.split( "," );
      QStringList::ConstIterator it;
      for ( it = exdates.constBegin(); it != exdates.constEnd(); ++it )
        deleteExceptions.append( WebdavHandler::sloxToKDateTime( *it ).date() );
    }
  }

  if ( daysSet && type == "monthly" )
    type = "monthly2"; // HACK: OX doesn't cleanly distinguish between monthly and monthly2
  if ( daysSet && type == "yearly" )
    type = "yearly2";

  Recurrence *r = event->recurrence();

  if ( type == "daily" ) {
    r->setDaily( dailyValue );
  } else if ( type == "weekly" ) {
    r->setWeekly( weeklyValue, days );
  } else if ( type == "monthly" ) {
    r->setMonthly( monthlyValueMonth );
    r->addMonthlyDate( monthlyValueDay );
  } else if ( type == "yearly" ) {
    r->setYearly( 1 );
    r->addYearlyDate( yearlyValueDay );
    r->addYearlyMonth( yearlyMonth );
  } else if ( type == "monthly2" ) {
    r->setMonthly( monthly2ValueMonth );
    QBitArray _days( 7 );
    if ( daysSet )
      _days = days;
    else
      _days.setBit( event->dtStart().date().dayOfWeek() );
    r->addMonthlyPos( monthly2Recurrency, _days );
  } else if ( type == "yearly2" ) {
    r->setYearly( 1 );
    r->addYearlyMonth( yearly2Month );
    QBitArray _days( 7 );
    if ( daysSet )
      _days = days;
    else
      _days.setBit( ( yearly2Day + 5 ) % 7 );
    r->addYearlyPos( yearly2Recurrency, _days );
  }
  r->setEndDate( end.date() );
  r->setExDates( deleteExceptions );
}
void KCalResourceSlox::createRecurrenceAttributes( QDomDocument &doc,
                                                   QDomElement &parent,
                                                   KCal::Incidence *incidence )
{
  if ( !incidence->recurs() ) {
    WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ),
                                   type() == "ox" ? "none" : "no" );
    return;
  }
  Recurrence *r = incidence->recurrence();
  int monthOffset = ( type() == "ox" ? -1 : 0 );
  switch ( r->recurrenceType() ) {
    case Recurrence::rDaily:
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "daily" );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceDailyFreq ),
                                     QString::number( r->frequency() ) );
      break;
    case Recurrence::rWeekly: {
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "weekly" );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceWeeklyFreq ),
                                     QString::number( r->frequency() ) );
      // TODO: SLOX support
      int oxDays = 0;
      for ( int i = 0; i < 7; ++i ) {
        if ( r->days()[i] )
          oxDays += 1 << ( ( i + 1 ) % 7 );
      }
      if ( type() == "ox" )
        WebdavHandler::addSloxElement( this, doc, parent, "days", QString::number( oxDays ) );
      break; }
    case Recurrence::rMonthlyDay:
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "monthly" );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthlyFreq ),
                                     QString::number( r->frequency() ) );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthlyDay ),
                                     QString::number( r->monthDays().first() ) );
      break;
    case Recurrence::rMonthlyPos: {
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ),
                                     type() == "ox" ? "monthly" : "monthly2" );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthly2Freq ),
                                     QString::number( r->frequency() ) );
      RecurrenceRule::WDayPos wdp = r->monthPositions().first();
      // TODO: SLOX support
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthly2Day ),
                                     QString::number( 1 << wdp.day() ) );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthly2Pos ),
                                     QString::number( wdp.pos() ) );
      break; }
    case Recurrence::rYearlyMonth:
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "yearly" );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearlyDay ),
                                     QString::number( r->yearDates().first() ) );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearlyMonth ),
                                     QString::number( r->yearMonths().first() + monthOffset ) );
      if ( type() == "ox" )
        WebdavHandler::addSloxElement( this, doc, parent, "interval", "1" );
      break;
    case Recurrence::rYearlyPos: {
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ),
                                     type() == "ox" ? "yearly" : "yearly2" );
      RecurrenceRule::WDayPos wdp = r->monthPositions().first();
      // TODO: SLOX support
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearly2Day ),
                                     QString::number( 1 << wdp.day() ) );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearly2Pos ),
                                     QString::number( wdp.pos() ) );
      WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearly2Month ),
                                     QString::number( r->yearMonths().first() + monthOffset ) );
      if ( type() == "ox" )
        WebdavHandler::addSloxElement( this, doc, parent, "interval", "1" );
      break; }
    default:
      kDebug() << "unsupported recurrence type:" << r->recurrenceType();
  }
  WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceEnd ),
                                 WebdavHandler::kDateTimeToSlox( r->endDateTime() ) );
  // delete exceptions
  DateList exlist = r->exDates();
  QStringList res;
  for ( DateList::ConstIterator it = exlist.constBegin(); it != exlist.constEnd(); ++it )
    res.append( WebdavHandler::qDateTimeToSlox( QDateTime( *it ) ) );
  WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceDelEx ), res.join( "," ) );
}
Exemple #10
0
/** Dissociate a single occurrence or all future occurrences from a recurring sequence.
    The new incidence is returned, but not automatically inserted into the calendar,
    which is left to the calling application */
Incidence *Calendar::dissociateOccurrence(Incidence *incidence, QDate date,
        bool single)
{
    if(!incidence || !incidence->doesRecur())
        return 0;

    Incidence *newInc = incidence->clone();
    newInc->recreate();
    newInc->setRelatedTo(incidence);
    Recurrence *recur = newInc->recurrence();
    if(single)
    {
        recur->clear();
    }
    else
    {
        // Adjust the recurrence for the future incidences. In particular
        // adjust the "end after n occurrences" rules! "No end date" and "end by ..."
        // don't need to be modified.
        int duration = recur->duration();
        if(duration > 0)
        {
            int doneduration = recur->durationTo(date.addDays(-1));
            if(doneduration >= duration)
            {
                kdDebug(5850) << "The dissociated event already occurred more often "
                              << "than it was supposed to ever occur. ERROR!" << endl;
                recur->clear();
            }
            else
            {
                recur->setDuration(duration - doneduration);
            }
        }
    }
    // Adjust the date of the incidence
    if(incidence->type() == "Event")
    {
        Event *ev = static_cast<Event *>(newInc);
        QDateTime start(ev->dtStart());
        int daysTo = start.date().daysTo(date);
        ev->setDtStart(start.addDays(daysTo));
        ev->setDtEnd(ev->dtEnd().addDays(daysTo));
    }
    else if(incidence->type() == "Todo")
    {
        Todo *td = static_cast<Todo *>(newInc);
        bool haveOffset = false;
        int daysTo = 0;
        if(td->hasDueDate())
        {
            QDateTime due(td->dtDue());
            daysTo = due.date().daysTo(date);
            td->setDtDue(due.addDays(daysTo), true);
            haveOffset = true;
        }
        if(td->hasStartDate())
        {
            QDateTime start(td->dtStart());
            if(!haveOffset)
                daysTo = start.date().daysTo(date);
            td->setDtStart(start.addDays(daysTo));
            haveOffset = true;
        }
    }
    recur = incidence->recurrence();
    if(recur)
    {
        if(single)
        {
            recur->addExDate(date);
        }
        else
        {
            // Make sure the recurrence of the past events ends
            // at the corresponding day
            recur->setEndDate(date.addDays(-1));
        }
    }
    return newInc;
}