/****************************************************************************** * Called when the mouse is moved. * Creates a drag object when the mouse drags one or more selected items. */ void AlarmListView::contentsMouseMoveEvent(QMouseEvent *e) { QListView::contentsMouseMoveEvent(e); if(mMousePressed && (mMousePressPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) { // Create a calendar object containing all the currently selected alarms kdDebug(5950) << "AlarmListView::contentsMouseMoveEvent(): drag started" << endl; mMousePressed = false; KCal::CalendarLocal cal(QString::fromLatin1("UTC")); cal.setLocalTime(); // write out using local time (i.e. no time zone) QValueList<EventListViewItemBase *> items = selectedItems(); if(!items.count()) return; for(QValueList<EventListViewItemBase *>::Iterator it = items.begin(); it != items.end(); ++it) { const KAEvent &event = (*it)->event(); KCal::Event *kcalEvent = new KCal::Event; event.updateKCalEvent(*kcalEvent, false, true); kcalEvent->setUid(event.id()); cal.addEvent(kcalEvent); } // Create the drag object for the destination program to receive mDragging = true; KCal::ICalDrag *dobj = new KCal::ICalDrag(&cal, this); dobj->dragCopy(); // the drag operation will copy the alarms } }
/****************************************************************************** * Add all the current alarms to the list. */ void AlarmListView::populate() { KAEvent event; KCal::Event::List events; KCal::Event::List::ConstIterator it; QDateTime now = QDateTime::currentDateTime(); if(mShowExpired) { AlarmCalendar *cal = AlarmCalendar::expiredCalendarOpen(); if(cal) { events = cal->events(); for(it = events.begin(); it != events.end(); ++it) { KCal::Event *kcalEvent = *it; if(kcalEvent->alarms().count() > 0) { event.set(*kcalEvent); addEntry(event, now); } } } } events = AlarmCalendar::activeCalendar()->events(); for(it = events.begin(); it != events.end(); ++it) { KCal::Event *kcalEvent = *it; event.set(*kcalEvent); if(mShowExpired || !event.expired()) addEntry(event, now); } }
void KAlarmResource::itemAdded(const Akonadi::Item& item, const Akonadi::Collection&) { if (!checkItemAddedChanged<EventPtr>(item, CheckForAdded)) return; EventPtr e = item.payload<EventPtr>(); KCal::Event* kcalEvent = new KCal::Event; #ifdef __GNUC__ #warning Should updateKCalEvent() third parameter be true for archived events? #endif e->updateKCalEvent(kcalEvent, false, false); calendar()->addIncidence(kcalEvent); Item it(item); it.setRemoteId(kcalEvent->uid()); scheduleWrite(); changeCommitted(it); }
KCal::Event* ICalReport::generateEvent(Task* task, ResourceList& resourceList) { KCal::Event *event = new KCal::Event(); QDateTime dt; /* Start-Time of the task */ dt.setTime_t(task->getStart(scenarios[0]), Qt::UTC); event->setDtStart(dt); /* Due-Time of the event -> plan End */ dt.setTime_t(task->getEnd(scenarios[0]) + 1, Qt::UTC); event->setHasEndDate(true); event->setDtEnd(dt); // Make sure that the time is not ignored. event->setFloats(false); /* Description and summary -> project ID */ event->setDescription(task->getNote()); event->setSummary(task->getName()); /* ICal defines priorities between 1..9 where 1 is the highest. TaskJuggler * uses Priority 1 - 1000, 1000 being the highest. So we have to map the * priorities. */ event->setPriority(1 + ((1000 - task->getPriority()) / 100)); /* Resources */ ResourceListIterator rli = task->getBookedResourcesIterator(scenarios[0]); for (; *rli != 0; ++rli) // We only include resources that have not been filtered out. if (resourceList.find(*rli)) event->addAttendee(new KCal::Attendee ((*rli)->getName(), "", false, KCal::Attendee::NeedsAction, KCal::Attendee::ReqParticipant, (*rli)->getId())); return event; }
KCal::Event *IncidenceConverter::convertFromAppointment(ngwt__Appointment *appointment) { kdDebug() << "IncidenceConverter::convertFromAppointment()" << endl; if(!appointment) return 0; KCal::Event *event = new KCal::Event(); if(!convertFromCalendarItem(appointment, event)) { delete event; return 0; } if(appointment->allDayEvent && (*appointment->allDayEvent)) { event->setFloats(true); if(appointment->startDay != 0) event->setDtStart(stringToQDate(appointment->startDay).addDays(1)); if(appointment->endDay != 0) event->setDtEnd(stringToQDate(appointment->endDay)); kdDebug() << " all day event." << endl; } else { event->setFloats(false); if(appointment->startDate != 0) { event->setDtStart(charToQDateTime(appointment->startDate, mTimezone)); } if(appointment->endDate != 0) event->setDtEnd(charToQDateTime(appointment->endDate, mTimezone)); } kdDebug() << "start date: " << event->dtStart() << endl; kdDebug() << "end date: " << event->dtEnd() << endl; if(appointment->alarm) { KCal::Alarm *alarm = event->newAlarm(); alarm->setStartOffset(appointment->alarm->__item * -1); alarm->setEnabled(appointment->alarm->enabled); } if(appointment->place) event->setLocation(stringToQString(appointment->place)); if(appointment->acceptLevel) { if(*appointment->acceptLevel == Tentative) event->setTransparency(KCal::Event::Transparent); else event->setTransparency(KCal::Event::Opaque); } return event; }
SummaryEventInfo::List SummaryEventInfo::eventsForDate( const QDate &date, KCal::Calendar *calendar ) { KCal::Event *ev; KCal::Event::List events = calendar->events( date, calendar->timeSpec() ); KCal::Event::List::ConstIterator it = events.constBegin(); KDateTime qdt; KDateTime::Spec spec = KSystemTimeZones::local(); KDateTime currentDateTime = KDateTime::currentDateTime( spec ); QDate currentDate = currentDateTime.date(); // sort the events for this date by summary events = KCal::Calendar::sortEvents( &events, KCal::EventSortSummary, KCal::SortDirectionAscending ); // sort the events for this date by start date events = KCal::Calendar::sortEvents( &events, KCal::EventSortStartDate, KCal::SortDirectionAscending ); List eventInfoList; for ( it=events.constBegin(); it != events.constEnd(); ++it ) { ev = *it; int daysTo = -1; // Count number of days remaining in multiday event int span = 1; int dayof = 1; if ( ev->isMultiDay() ) { QDate d = ev->dtStart().date(); if ( d < currentDate ) { dayof += d.daysTo( currentDate ); span += d.daysTo( currentDate ); d = currentDate; } while ( d < ev->dtEnd().date() ) { if ( d < date ) { dayof++; } span++; d = d.addDays( 1 ); } } QDate startOfMultiday = ev->dtStart().date(); if ( startOfMultiday < currentDate ) { startOfMultiday = currentDate; } bool firstDayOfMultiday = ( date == startOfMultiday ); // If this date is part of a floating, multiday event, then we // only make a print for the first day of the event. if ( ev->isMultiDay() && ev->allDay() && ( currentDate > ev->dtStart().date() || !firstDayOfMultiday ) ) { continue; } // If the event is already over, then it isn't upcoming. so don't print it. if ( !ev->allDay() ) { if ( ev->recurs() ) { KDateTime kdt( date, QTime( 0, 0, 0 ), KSystemTimeZones::local() ); kdt = kdt.addSecs( -1 ); if ( currentDateTime > ev->recurrence()->getNextDateTime( kdt ) ) { continue; } } else { if ( currentDateTime > ev->dtEnd() ) { continue; } } } SummaryEventInfo *summaryEvent = new SummaryEventInfo(); eventInfoList.append( summaryEvent ); // Event summaryEvent->ev = ev; // Start date label QString str = ""; QDate sD = QDate( date.year(), date.month(), date.day() ); if ( ( sD.month() == currentDate.month() ) && ( sD.day() == currentDate.day() ) ) { str = i18nc( "the appointment is today", "Today" ); summaryEvent->makeBold = true; } else if ( ( sD.month() == currentDate.addDays( 1 ).month() ) && ( sD.day() == currentDate.addDays( 1 ).day() ) ) { str = i18nc( "the appointment is tomorrow", "Tomorrow" ); } else { str = KGlobal::locale()->formatDate( sD, KLocale::FancyLongDate ); } summaryEvent->startDate = str; // Print the date span for multiday, floating events, for the // first day of the event only. if ( ev->isMultiDay() && ev->allDay() && firstDayOfMultiday && span > 1 ) { str = IncidenceFormatter::dateToString( ev->dtStart(), false, spec ) + " -\n " + IncidenceFormatter::dateToString( ev->dtEnd(), false, spec ); } summaryEvent->dateSpan = str; // Days to go label str = ""; dateDiff( startOfMultiday, daysTo ); if ( ev->isMultiDay() && !ev->allDay() ) { dateDiff( date, daysTo ); } if ( daysTo > 0 ) { str = i18np( "in 1 day", "in %1 days", daysTo ); } else { if ( !ev->allDay() ) { int secs; if ( !ev->recurs() ) { secs = currentDateTime.secsTo( ev->dtStart() ); } else { KDateTime kdt( date, QTime( 0, 0, 0 ), KSystemTimeZones::local() ); kdt = kdt.addSecs( -1 ); KDateTime next = ev->recurrence()->getNextDateTime( kdt ); secs = currentDateTime.secsTo( next ); } if ( secs > 0 ) { str = i18nc( "eg. in 1 hour 2 minutes", "in " ); int hours = secs / 3600; if ( hours > 0 ) { str += i18ncp( "use abbreviation for hour to keep the text short", "1 hr", "%1 hrs", hours ); str += ' '; secs -= ( hours * 3600 ); } int mins = secs / 60; if ( mins > 0 ) { str += i18ncp( "use abbreviation for minute to keep the text short", "1 min", "%1 mins", mins ); } } else { str = i18n( "now" ); } } else { str = i18n( "all day" ); } } summaryEvent->daysToGo = str; // Summary label str = ev->richSummary(); if ( ev->isMultiDay() && !ev->allDay() ) { str.append( QString( " (%1/%2)" ).arg( dayof ).arg( span ) ); } summaryEvent->summaryText = str; summaryEvent->summaryUrl = ev->uid(); QString tipText( KCal::IncidenceFormatter::toolTipStr( calendar, ev, date, true, spec ) ); if ( !tipText.isEmpty() ) { summaryEvent->summaryTooltip = tipText; } // Time range label (only for non-floating events) str = ""; if ( !ev->allDay() ) { QTime sST = ev->dtStart().toTimeSpec( spec ).time(); QTime sET = ev->dtEnd().toTimeSpec( spec ).time(); if ( ev->isMultiDay() ) { if ( ev->dtStart().date() < date ) { sST = QTime( 0, 0 ); } if ( ev->dtEnd().date() > date ) { sET = QTime( 23, 59 ); } } str = i18nc( "Time from - to", "%1 - %2", KGlobal::locale()->formatTime( sST ), KGlobal::locale()->formatTime( sET ) ); summaryEvent->timeRange = str; } // For recurring events, append the next occurrence to the time range label if ( ev->recurs() ) { KDateTime kdt( date, QTime( 0, 0, 0 ), KSystemTimeZones::local() ); kdt = kdt.addSecs( -1 ); KDateTime next = ev->recurrence()->getNextDateTime( kdt ); QString tmp = IncidenceFormatter::dateTimeToString( ev->recurrence()->getNextDateTime( next ), ev->allDay(), true, KSystemTimeZones::local() ); if ( !summaryEvent->timeRange.isEmpty() ) { summaryEvent->timeRange += "<br>"; } summaryEvent->timeRange += "<font size=\"small\"><i>" + i18nc( "next occurrence", "Next: %1", tmp ) + "</i></font>"; } } return eventInfoList; }
bool ICalReport::generate() { #if KDE_IS_VERSION(3,4,89) KCal::CalendarLocal cal("UTC"); #else KCal::CalendarLocal cal; #endif if( !open()) { tjWarning(i18n("Can not open ICal File '%1' for writing!") .arg(fileName)); return false; } TaskList filteredList; if (!filterTaskList(filteredList, 0, getHideTask(), getRollUpTask())) return false; // Make sure that parents are in front of childs. We need this later to set // the relation. filteredList.setSorting(CoreAttributesList::TreeMode, 0); filteredList.setSorting(CoreAttributesList::StartUp, 1); sortTaskList(filteredList); ResourceList filteredResourceList; if (!filterResourceList(filteredResourceList, 0, hideResource, rollUpResource)) return false; sortResourceList(filteredResourceList); QPtrDict<KCal::Todo> toDoDict; QPtrDict<KCal::Event> eventDict; for (TaskListIterator tli(filteredList); *tli != 0; ++tli) { // Generate a TODO item for each task. KCal::Todo* todo = generateTODO(*tli, filteredResourceList); // In case we have the parent in the list set the relation pointer. if((*tli)->getParent() && toDoDict.find((*tli)->getParent())) todo->setRelatedTo(toDoDict[(*tli)->getParent()]); // Insert the just created TODO into the calendar. cal.addTodo(todo); // Insert the TODO into the dict. We might need it as a parent. toDoDict.insert(*tli, todo); if ((*tli)->isLeaf() && !(*tli)->isMilestone()) { // Generate an event item for each task. KCal::Event* event = generateEvent(*tli, filteredResourceList); // In case we have the parent in the list set the relation pointer. if((*tli)->getParent() && eventDict.find((*tli)->getParent())) event->setRelatedTo(eventDict[(*tli)->getParent()]); // Insert the just created EVENT into the calendar. cal.addEvent(event); // Insert the EVENT into the dict. We might need it as a parent. eventDict.insert(*tli, event); } } // Dump the calendar in ICal format into a text file. KCal::ICalFormat format; s << format.toString(&cal) << endl; return close(); }
void SummaryEventTester::test_Multiday() { QDate today = QDate::currentDate(); QString multidayWithTimeInProgress = "Multiday, time specified, in progress"; KCal::CalendarLocal *cal = new KCal::CalendarLocal( KDateTime().timeSpec() ); KCal::Event *event = new KCal::Event(); event->setDtStart( KDateTime( today.addDays( -1 ) ) ); event->setDtEnd( KDateTime( today.addDays( 5 ) ) ); event->setSummary( "Multiday, allday, in progress (day 2/6)" ); QVERIFY( cal->addEvent( event ) ); event = new KCal::Event(); event->setDtStart( KDateTime( today.addDays( -1 ), QTime::fromString("12:00","hh:mm") ) ); event->setDtEnd( KDateTime( today.addDays( 5 ), QTime::fromString("12:00","hh:mm") ) ); event->setSummary( multidayWithTimeInProgress ); QVERIFY( cal->addEvent( event ) ); for ( int i = 0; i < 5; i++ ) { SummaryEventInfo::List events4 = SummaryEventInfo::eventsForDate( today.addDays( i ), cal ); QCOMPARE( 1, events4.size() ); SummaryEventInfo *ev4 = events4.at(0); QCOMPARE( ev4->summaryText, QString(multidayWithTimeInProgress + " (%1/7)").arg(i+2)); QCOMPARE( ev4->timeRange, QString("00:00 - 23:59") ); // QCOMPARE( ev4->startDate, KGlobal::locale()->formatDate( QDate( today.addDays( i ) ), KLocale::FancyLongDate ) ); QCOMPARE( ev4->makeBold, i == 0 ); qDeleteAll( events4 ); } // Test date a multiday event in the future has to correct DaysTo set QString multiDayWithTimeFuture = "Multiday, with time, in the future"; event = new KCal::Event(); event->setDtStart( KDateTime( today.addDays( 100 ), QTime::fromString("12:00","hh:mm") ) ); event->setDtEnd( KDateTime( today.addDays( 106 ), QTime::fromString("12:00","hh:mm") ) ); event->setSummary( multiDayWithTimeFuture ); QVERIFY( cal->addEvent( event ) ); for ( int i = 100; i <= 106; i++ ) { SummaryEventInfo::List events5 = SummaryEventInfo::eventsForDate( today.addDays( i ), cal ); QCOMPARE( 1, events5.size() ); SummaryEventInfo *ev5 = events5.at(0); /*qDebug() << ev5->summaryText; qDebug() << ev5->daysToGo; qDebug() << i;*/ QCOMPARE( ev5->summaryText, QString(multiDayWithTimeFuture + " (%1/7)").arg(i-100+1)); QCOMPARE( ev5->daysToGo, QString("in %1 days").arg(i) ); qDeleteAll( events5 ); } QString multiDayAllDayInFuture = "Multiday, allday, in future"; int multiDayFuture = 30; event = new KCal::Event(); event->setDtStart( KDateTime( today.addDays( multiDayFuture ) ) ); event->setDtEnd( KDateTime( today.addDays( multiDayFuture + 5 ) ) ); event->setSummary( multiDayAllDayInFuture ); QVERIFY( cal->addEvent( event ) ); event = new KCal::Event(); event->setDtStart( KDateTime( today.addDays( 2 ), QTime::fromString("12:00","hh:mm") ) ); event->setDtEnd( KDateTime( today.addDays( 5 ), QTime::fromString("12:00","hh:mm") ) ); event->setSummary( "Multiday, time specified, in future" ); QVERIFY( cal->addEvent( event ) ); QString multiDayAllDayStartingToday = "Multiday, allday, starting today"; event = new KCal::Event(); event->setDtStart( KDateTime( today ) ); event->setDtEnd( KDateTime( today.addDays( 5 ) ) ); event->setSummary( multiDayAllDayStartingToday ); QVERIFY( cal->addEvent( event ) ); event = new KCal::Event(); event->setDtStart( KDateTime( today.addDays(-10), QTime::fromString("12:00","hh:mm") ) ); event->setDtEnd( KDateTime( today.addDays( -5 ), QTime::fromString("10:00","hh:mm") ) ); event->setSummary( "Some event in the past" ); QVERIFY( cal->addEvent( event ) ); SummaryEventInfo::List eventsToday = SummaryEventInfo::eventsForDate( today, cal ); QCOMPARE( 2, eventsToday.size() ); foreach( const SummaryEventInfo *ev, eventsToday ) { if ( ev->summaryText == multidayWithTimeInProgress + " (2/7)" ) { QCOMPARE( ev->timeRange, QString("00:00 - 23:59") ); QCOMPARE( ev->startDate, QString("Today") ); QCOMPARE( ev->daysToGo, QString("now") ); QCOMPARE( ev->makeBold, true ); } else if ( ev->summaryText == multiDayAllDayStartingToday ) { QVERIFY( ev->timeRange.isEmpty() ); QCOMPARE( ev->startDate, QString("Today") ); QCOMPARE( ev->daysToGo, QString("all day") ); QCOMPARE( ev->makeBold, true ); } else Q_ASSERT( false ); // unexpected event! } SummaryEventInfo::List events2 = SummaryEventInfo::eventsForDate( today.addDays( multiDayFuture ), cal ); QCOMPARE( 1, events2.size() ); SummaryEventInfo *ev1 = events2.at( 0 ); QCOMPARE( ev1->summaryText, multiDayAllDayInFuture ); QVERIFY( ev1->timeRange.isEmpty() ); QCOMPARE( ev1->startDate, KGlobal::locale()->formatDate( QDate( today.addDays( multiDayFuture ) ) ) ); QCOMPARE( ev1->daysToGo, QString("in %1 days").arg(multiDayFuture) ); QCOMPARE( ev1->makeBold, false ); // Make sure multiday is only displayed once for ( int i = 1; i < 30; i++ ) { SummaryEventInfo::List events3 = SummaryEventInfo::eventsForDate( today.addDays( multiDayFuture + i ), cal ); foreach(SummaryEventInfo *ev, events3 ) { QVERIFY( ev->summaryText.contains( multiDayAllDayInFuture ) ); } qDeleteAll( events3 ); }
int KMobileGnokii::storeCalendarEntry( int index, const KCal::Event &event ) { if (index < 0 || index >= GN_CALNOTE_MAX_NUMBER) return KIO::ERR_DOES_NOT_EXIST; gn_error error; gn_calnote entry; gn_data_clear(&data); memset(&entry, 0, sizeof(entry)); entry.location = index+1; data.calnote = &entry; data.calnote_list = &calnote_list; // read first error = gn_sm_functions(GN_OP_GetCalendarNote, &data, &state); // GNOKII_CHECK_ERROR(error); QDateTime_2_timestamp( event.dtStart(), entry.time ); strncpy(entry.text, event.summary().utf8(), sizeof(entry.text)-1); // type: entry.type = GN_CALNOTE_MEETING; if (event.categories().findIndex(i18n("MEETING")) != -1) { entry.type = GN_CALNOTE_MEETING; } else if (event.categories().findIndex(i18n("PHONE CALL")) != -1) { entry.type = GN_CALNOTE_CALL; strncpy(entry.phone_number, event.description().utf8(), sizeof(entry.phone_number)-1); } else if (event.categories().findIndex(i18n("BIRTHDAY")) != -1) { entry.type = GN_CALNOTE_BIRTHDAY; } else { // assume i18n("REMINDER") entry.type = GN_CALNOTE_REMINDER; } // alarm: entry.alarm.enabled = 0; if (event.isAlarmEnabled()) { const KCal::Alarm *eventalarm = *event.alarms().at(0); if (eventalarm) { if (eventalarm->hasTime()) { QDateTime_2_timestamp( eventalarm->time(), entry.alarm.timestamp ); } else if (eventalarm->hasStartOffset()) { QDateTime dt = event.dtStart(); dt = dt.addSecs(-eventalarm->startOffset().asSeconds()); QDateTime_2_timestamp( dt, entry.alarm.timestamp ); } } } // recurrence: switch (event.recurrence()->recurrenceType()) { case KCal::Recurrence::rNone: default: entry.recurrence = GN_CALNOTE_NEVER; break; case KCal::Recurrence::rHourly: entry.recurrence = (gn_calnote_recurrence) (event.recurrence()->frequency()); break; case KCal::Recurrence::rDaily: entry.recurrence = GN_CALNOTE_DAILY; break; case KCal::Recurrence::rWeekly: entry.recurrence = (gn_calnote_recurrence) (GN_CALNOTE_WEEKLY * event.recurrence()->frequency()); break; case KCal::Recurrence::rMonthlyPos: case KCal::Recurrence::rMonthlyDay: entry.recurrence = GN_CALNOTE_MONTHLY; break; case KCal::Recurrence::rYearlyMonth: case KCal::Recurrence::rYearlyDay: case KCal::Recurrence::rYearlyPos: entry.recurrence = GN_CALNOTE_YEARLY; break; } print_calnote( entry ); return 0; // XXX error = gn_sm_functions(GN_OP_WriteCalendarNote, &data, &state); GNOKII_CHECK_ERROR(error); return 0; }
int KMobileGnokii::readCalendarEntry( int index, KCal::Event &event ) { if (index < 0 || index >= GN_CALNOTE_MAX_NUMBER) return KIO::ERR_DOES_NOT_EXIST; gn_data_clear(&data); gn_calnote entry; memset(&entry, 0, sizeof(entry)); entry.location = index+1; data.calnote = &entry; data.calnote_list = &calnote_list; gn_error error = gn_sm_functions(GN_OP_GetCalendarNote, &data, &state); GNOKII_CHECK_ERROR(error); if (error != GN_ERR_NONE) return gn_error2kio_error(error); print_calnote( entry ); QDateTime dt_start = timestamp_2_QDateTime(entry.time); QDateTime dt_end = dt_start.addSecs( 60*60 ); // XXX: assume one hour event.setDtStart( dt_start ); event.setDtEnd( dt_end ); event.setSummary( QString::fromUtf8(entry.text) ); // type: switch (entry.type) { case GN_CALNOTE_MEETING: event.setCategories(i18n("MEETING")); break; case GN_CALNOTE_CALL: event.setCategories(i18n("PHONE CALL")); event.setDescription(QString::fromUtf8(entry.phone_number)); break; case GN_CALNOTE_BIRTHDAY: event.setCategories(i18n("BIRTHDAY")); break; case GN_CALNOTE_REMINDER: event.setCategories(i18n("REMINDER")); break; default: kdWarning() << "unknown calendar GN_CALNOTE_XXXX type #" << entry.type << endl; } // alarm: if (entry.alarm.enabled) { QDateTime at = timestamp_2_QDateTime(entry.alarm.timestamp); if (at.isValid() && dt_start.isValid()) { int seconds = abs(at.secsTo(dt_start)); seconds %= 60*60*24; /* max. 1 day in advance... */ KCal::Alarm *eventalarm = event.newAlarm(); eventalarm->setStartOffset(KCal::Duration(seconds)); } } // recurrence: switch (entry.recurrence) { case GN_CALNOTE_NEVER: break; case GN_CALNOTE_DAILY: event.recurrence()->setDaily(1,-1); break; case GN_CALNOTE_WEEKLY: case GN_CALNOTE_2WEEKLY: event.recurrence()->setDaily( 7 + (entry.recurrence==GN_CALNOTE_2WEEKLY ? 7:0) , -1); break; case GN_CALNOTE_MONTHLY: event.recurrence()->setMonthly(KCal::Recurrence::rMonthlyPos, 1, -1); break; case GN_CALNOTE_YEARLY: event.recurrence()->setYearly(KCal::Recurrence::rYearlyPos, 1, -1); break; default: // hourly event.recurrence()->setHourly(entry.recurrence, -1); break; } return 0; }
/****************************************************************************** * Check if any alarms are pending for a specified calendar, and display the * pending alarms. */ void AlarmDaemon::checkAlarms(ADCalendar *cal) { kdDebug(5901) << "AlarmDaemons::checkAlarms(" << cal->urlString() << ")" << endl; if(!cal->loaded() || !cal->enabled()) return; QDateTime now = QDateTime::currentDateTime(); kdDebug(5901) << " To: " << now.toString() << endl; QValueList<KCal::Alarm *> alarms = cal->alarmsTo(now); if(!alarms.count()) return; QValueList<KCal::Event *> eventsDone; for(QValueList<KCal::Alarm *>::ConstIterator it = alarms.begin(); it != alarms.end(); ++it) { KCal::Event *event = dynamic_cast<KCal::Event *>((*it)->parent()); if(!event || eventsDone.find(event) != eventsDone.end()) continue; // either not an event, or the event has already been processed eventsDone += event; const QString &eventID = event->uid(); kdDebug(5901) << "AlarmDaemon::checkAlarms(): event " << eventID << endl; // Check which of the alarms for this event are due. // The times in 'alarmtimes' corresponding to due alarms are set. // The times for non-due alarms are set invalid in 'alarmtimes'. bool recurs = event->doesRecur(); const QStringList cats = event->categories(); bool floats = (cats.find(QString::fromLatin1("DATE")) != cats.end()); QDateTime nextDateTime = event->dtStart(); if(recurs) { QString prop = event->customProperty("KALARM", "NEXTRECUR"); if(prop.length() >= 8) { // The next due recurrence time is specified QDate d(prop.left(4).toInt(), prop.mid(4, 2).toInt(), prop.mid(6, 2).toInt()); if(d.isValid()) { if(floats && prop.length() == 8) nextDateTime = d; else if(!floats && prop.length() == 15 && prop[8] == QChar('T')) { QTime t(prop.mid(9, 2).toInt(), prop.mid(11, 2).toInt(), prop.mid(13, 2).toInt()); if(t.isValid()) nextDateTime = QDateTime(d, t); } } } } if(floats) nextDateTime.setTime(mStartOfDay); QValueList<QDateTime> alarmtimes; KCal::Alarm::List alarms = event->alarms(); for(KCal::Alarm::List::ConstIterator al = alarms.begin(); al != alarms.end(); ++al) { KCal::Alarm *alarm = *al; QDateTime dt; if(alarm->enabled()) { QDateTime dt1; if(!alarm->hasTime()) { // Find the latest recurrence for the alarm. // Need to do this for alarms with offsets in order to detect // reminders due for recurrences. int offset = alarm->hasStartOffset() ? alarm->startOffset().asSeconds() : alarm->endOffset().asSeconds() + event->dtStart().secsTo(event->dtEnd()); if(offset) { dt1 = nextDateTime.addSecs(floats ? (offset / SECS_PER_DAY) * SECS_PER_DAY : offset); if(dt1 > now) dt1 = QDateTime(); } } // Get latest due repetition, or the recurrence time if none dt = nextDateTime; if(nextDateTime <= now && alarm->repeatCount() > 0) { int snoozeSecs = alarm->snoozeTime() * 60; int offset = alarm->repeatCount() * snoozeSecs; QDateTime lastRepetition = nextDateTime.addSecs(floats ? (offset / SECS_PER_DAY) * SECS_PER_DAY : offset); if(lastRepetition <= now) dt = lastRepetition; else { int repetition = nextDateTime.secsTo(now) / snoozeSecs; int offset = repetition * snoozeSecs; dt = nextDateTime.addSecs(floats ? (offset / SECS_PER_DAY) * SECS_PER_DAY : offset); } } if(!dt.isValid() || dt > now || dt1.isValid() && dt1 > dt) // already tested dt1 <= now dt = dt1; } alarmtimes.append(dt); } if(!cal->eventHandled(event, alarmtimes)) { if(notifyEvent(cal, eventID)) cal->setEventPending(event, alarmtimes); } } }
void ExchangeDownload::slotPropFindResult(KIO::Job *job) { kdDebug() << "slotPropFindResult" << endl; int error = job->error(); if(error) { job->showErrorDialog(0); finishUp(ExchangeClient::CommunicationError, job); return; } QDomDocument response = static_cast<KIO::DavJob *>(job)->response(); kdDebug() << "Response: " << endl; kdDebug() << response.toString() << endl; QDomElement prop = response.documentElement().namedItem("response") .namedItem("propstat").namedItem("prop").toElement(); KCal::Event *event = new KCal::Event(); QDomElement uidElement = prop.namedItem("uid").toElement(); if(uidElement.isNull()) { kdError() << "Error: no uid in Exchange server reply" << endl; finishUp(ExchangeClient::IllegalAppointmentError, "WebDAV server response:\n" + response.toString()); return; } event->setUid(uidElement.text()); // kdDebug() << "Got UID: " << uidElement.text() << endl; QString timezoneid = prop.namedItem("timezoneid").toElement().text(); // kdDebug() << "DEBUG: timezoneid = " << timezoneid << endl; QString timezone = prop.namedItem("timezone").toElement().text(); // kdDebug() << "DEBUG: timezone = " << timezone << endl; // mFormat is used for parsing recurrence rules. QString localTimeZoneId; if(mCalendar) { mFormat->setTimeZone(mCalendar->timeZoneId(), !mCalendar->isLocalTime()); localTimeZoneId = mCalendar->timeZoneId(); } else { localTimeZoneId = "UTC"; // If no mCalendar, stay in UTC } QString lastModified = prop.namedItem("lastmodified").toElement().text(); if(!lastModified.isEmpty()) { QDateTime dt = utcAsZone(QDateTime::fromString(lastModified, Qt::ISODate), localTimeZoneId); event->setLastModified(dt); kdDebug() << "Got lastModified:" << lastModified << ", " << dt.toString() << endl; } QString organizer = prop.namedItem("organizer").toElement().text(); // TODO: Does outlook have a common name? Or does the organizer already contain both? event->setOrganizer(organizer); // kdDebug() << "Got organizer: " << organizer << endl; // Trying to find attendees, not working yet QString contact = prop.namedItem("contact").toElement().text(); // event->setOrganizer( organizer ); // kdDebug() << "DEBUG: Got contact: " << contact << endl; // This looks promising for finding attendees // FIXME: get this to work QString to = prop.namedItem("to").toElement().text(); // kdDebug() << "DEBUG: Got to: " << to << endl; QStringList attn = QStringList::split(",", to); // This doesn't work: there can be commas between "" QStringList::iterator it; for(it = attn.begin(); it != attn.end(); ++it) { // kdDebug() << " attendee: " << (*it) << endl; QString name = ""; // KCal::Attendee* a = new KCal::Attendee( name, email ); // event->addAttendee( a ); } QString readonly = prop.namedItem("isreadonly").toElement().text(); event->setReadOnly(readonly == "1"); kdDebug() << "Got readonly: " << readonly << ":" << (readonly != "0") << endl; QString created = prop.namedItem("created").toElement().text(); if(!created.isEmpty()) { QDateTime dt = utcAsZone(QDateTime::fromString(created, Qt::ISODate), localTimeZoneId); event->setCreated(dt); kdDebug() << "got created: " << dt.toString() << endl; } QString dtstart = prop.namedItem("dtstart").toElement().text(); if(!dtstart.isEmpty()) { QDateTime dt = utcAsZone(QDateTime::fromString(dtstart, Qt::ISODate), localTimeZoneId); event->setDtStart(dt); kdDebug() << "got dtstart: " << dtstart << " becomes in timezone " << dt.toString() << endl; } QString alldayevent = prop.namedItem("alldayevent").toElement().text(); bool floats = alldayevent.toInt() != 0; event->setFloats(floats); kdDebug() << "Got alldayevent: \"" << alldayevent << "\":" << floats << endl; QString dtend = prop.namedItem("dtend").toElement().text(); if(!dtend.isEmpty()) { QDateTime dt = utcAsZone(QDateTime::fromString(dtend, Qt::ISODate), localTimeZoneId); // Outlook thinks differently about floating event timing than libkcal if(floats) dt = dt.addDays(-1); event->setDtEnd(dt); kdDebug() << "got dtend: " << dtend << " becomes in timezone " << dt.toString() << endl; } QString transparent = prop.namedItem("transparent").toElement().text(); event->setTransparency(transparent.toInt() > 0 ? KCal::Event::Transparent : KCal::Event::Opaque); // kdDebug() << "Got transparent: " << transparent << endl; QString description = prop.namedItem("textdescription").toElement().text(); event->setDescription(description); kdDebug() << "Got description: " << description << endl; QString subject = prop.namedItem("subject").toElement().text(); event->setSummary(subject); kdDebug() << "Got summary: " << subject << endl; QString location = prop.namedItem("location").toElement().text(); event->setLocation(location); // kdDebug() << "Got location: " << location << endl; QString rrule = prop.namedItem("rrule").toElement().text(); kdDebug() << "Got rrule: " << rrule << endl; if(!rrule.isEmpty()) { // Timezone should be handled automatically // because we used mFormat->setTimeZone() earlier KCal::RecurrenceRule *rr = event->recurrence()->defaultRRule(true); if(!rr || !mFormat->fromString(rr, rrule)) { kdError() << "ERROR parsing rrule " << rrule << endl; } } QDomElement keywords = prop.namedItem("Keywords").toElement(); QStringList categories; QDomNodeList list = keywords.elementsByTagNameNS("xml:", "v"); for(uint i = 0; i < list.count(); i++) { QDomElement item = list.item(i).toElement(); categories.append(item.text()); } event->setCategories(categories); // kdDebug() << "Got categories: " << categories.join( ", " ) << endl; QDomElement exdate = prop.namedItem("exdate").toElement(); KCal::DateList exdates; list = exdate.elementsByTagNameNS("xml:", "v"); for(uint i = 0; i < list.count(); i++) { QDomElement item = list.item(i).toElement(); QDate date = utcAsZone(QDateTime::fromString(item.text(), Qt::ISODate), localTimeZoneId).date(); exdates.append(date); // kdDebug() << "Got exdate: " << date.toString() << endl; } event->recurrence()->setExDates(exdates); // Exchange sentitivity values: // 0 None // 1 Personal // 2 Private // 3 Company Confidential QString sensitivity = prop.namedItem("sensitivity").toElement().text(); if(! sensitivity.isNull()) switch(sensitivity.toInt()) { case 0: event->setSecrecy(KCal::Incidence::SecrecyPublic); break; case 1: event->setSecrecy(KCal::Incidence::SecrecyPrivate); break; case 2: event->setSecrecy(KCal::Incidence::SecrecyPrivate); break; case 3: event->setSecrecy(KCal::Incidence::SecrecyConfidential); break; default: kdWarning() << "Unknown sensitivity: " << sensitivity << endl; } // kdDebug() << "Got sensitivity: " << sensitivity << endl; QString reminder = prop.namedItem("reminderoffset").toElement().text(); // kdDebug() << "Reminder offset: " << reminder << endl; if(!reminder.isEmpty()) { // Duration before event in seconds KCal::Duration offset(- reminder.toInt()); KCal::Alarm *alarm = event->newAlarm(); alarm->setStartOffset(offset); alarm->setDisplayAlarm(""); alarm->setEnabled(true); // TODO: multiple alarms; alarm->setType( KCal::Alarm::xxxx ); } /** Create a new alarm which is associated with this incidence */ //Alarm* newAlarm(); /** Add an alarm which is associated with this incidence */ //void addAlarm(Alarm*); /** point at some other event to which the event relates */ //void setRelatedTo(Incidence *relatedTo); /** Add an event which is related to this event */ //void addRelation(Incidence *); /** set the list of attachments/associated files for this event */ //void setAttachments(const QStringList &attachments); /** set resources used, such as Office, Car, etc. */ //void setResources(const QStringList &resources); /** set the event's priority, 0 is undefined, 1 highest (decreasing order) */ //void setPriority(int priority); /** Add Attendee to this incidence. IncidenceBase takes ownership of the Attendee object. */ //void addAttendee(Attendee *a, bool doupdate=true ); // THE FOLLOWING EVENT PROPERTIES ARE NOT READ // Revision ID in webdav is a String, not an int /** set the number of revisions this event has seen */ //void setRevision(int rev); // Problem: When you sync Outlook to a Palm, the conduit splits up // multi-day events into single-day events WITH ALL THE SAME UID // Grrrrrrr. if(mCalendar) { KCal::Event *oldEvent = mCalendar->event(event->uid()); if(oldEvent) { kdWarning() << "Already got his event, replace it..." << endl; mCalendar->deleteEvent(oldEvent); } kdDebug() << "ADD EVENT" << endl; mCalendar->addEvent(event); } else { kdDebug() << "EMIT gotEvent" << endl; emit gotEvent(event, static_cast<KIO::DavJob *>(job)->url()); // mEvents->append( event ); } decreaseDownloads(); }