KCal::Event* IncidenceConverter::convertFromAppointment( ngwt__Appointment* appointment ) { kDebug() <<"IncidenceConverter::convertFromAppointment()"; if ( !appointment ) return 0; KCal::Event *event = new KCal::Event(); if ( !convertFromCalendarItem( appointment, event ) ) { delete event; return 0; } if ( appointment->allDayEvent && (*appointment->allDayEvent) ) { event->setAllDay( true ); if ( appointment->startDay != 0 ) event->setDtStart( stringToKDateTime( appointment->startDay ).addDays( 1 ) ); if ( appointment->endDay != 0 ) //TODO: Use KDateTime::fromString()? event->setDtEnd( stringToKDateTime( appointment->endDay) ); kDebug() <<" all day event."; } else { event->setAllDay( false ); if ( appointment->startDate != 0 ) { event->setDtStart( charToKDateTime( appointment->startDate, mTimeSpec ) ); } if ( appointment->endDate != 0 ) { event->setDtEnd( charToKDateTime( appointment->endDate, mTimeSpec ) ); } } kDebug() <<"start date:" << event->dtStart(); kDebug() <<"end date:" << event->dtEnd(); 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; }
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(); }
void Incidence::saveTo(KCal::Incidence *incidence) { KolabBase::saveTo(incidence); if(mFloatingStatus == AllDay) { // This is a floating event. Don't timezone move this one incidence->setDtStart(startDate()); incidence->setFloats(true); } else { incidence->setDtStart(utcToLocal(startDate())); incidence->setFloats(false); } incidence->setSummary(summary()); incidence->setLocation(location()); if(mHasAlarm) { KCal::Alarm *alarm = incidence->newAlarm(); alarm->setStartOffset(qRound(mAlarm * 60.0)); alarm->setEnabled(true); } if(organizer().displayName.isEmpty()) incidence->setOrganizer(organizer().smtpAddress); else incidence->setOrganizer(organizer().displayName + "<" + organizer().smtpAddress + ">"); incidence->clearAttendees(); QValueList<Attendee>::ConstIterator it; for(it = mAttendees.begin(); it != mAttendees.end(); ++it) { KCal::Attendee::PartStat status = attendeeStringToStatus((*it).status); KCal::Attendee::Role role = attendeeStringToRole((*it).role); KCal::Attendee *attendee = new KCal::Attendee((*it).displayName, (*it).smtpAddress, (*it).requestResponse, status, role); attendee->setDelegate((*it).delegate); attendee->setDelegator((*it).delegator); incidence->addAttendee(attendee); } incidence->clearAttachments(); KCal::Attachment::List::ConstIterator it2; for(it2 = mAttachments.begin(); it2 != mAttachments.end(); ++it2) { KCal::Attachment *a = (*it2); // TODO should we copy? incidence->addAttachment(a); } if(!mRecurrence.cycle.isEmpty()) { KCal::Recurrence *recur = incidence->recurrence(); // yeah, this creates it // done below recur->setFrequency( mRecurrence.interval ); if(mRecurrence.cycle == "minutely") { recur->setMinutely(mRecurrence.interval); } else if(mRecurrence.cycle == "hourly") { recur->setHourly(mRecurrence.interval); } else if(mRecurrence.cycle == "daily") { recur->setDaily(mRecurrence.interval); } else if(mRecurrence.cycle == "weekly") { QBitArray rDays = daysListToBitArray(mRecurrence.days); recur->setWeekly(mRecurrence.interval, rDays); } else if(mRecurrence.cycle == "monthly") { recur->setMonthly(mRecurrence.interval); if(mRecurrence.type == "weekday") { recur->addMonthlyPos(mRecurrence.dayNumber.toInt(), daysListToBitArray(mRecurrence.days)); } else if(mRecurrence.type == "daynumber") { recur->addMonthlyDate(mRecurrence.dayNumber.toInt()); } else kdWarning() << "Unhandled monthly recurrence type " << mRecurrence.type << endl; } else if(mRecurrence.cycle == "yearly") { recur->setYearly(mRecurrence.interval); if(mRecurrence.type == "monthday") { recur->addYearlyDate(mRecurrence.dayNumber.toInt()); for(int i = 0; i < 12; ++i) if(s_monthName[ i ] == mRecurrence.month) recur->addYearlyMonth(i + 1); } else if(mRecurrence.type == "yearday") { recur->addYearlyDay(mRecurrence.dayNumber.toInt()); } else if(mRecurrence.type == "weekday") { for(int i = 0; i < 12; ++i) if(s_monthName[ i ] == mRecurrence.month) recur->addYearlyMonth(i + 1); recur->addYearlyPos(mRecurrence.dayNumber.toInt(), daysListToBitArray(mRecurrence.days)); } else kdWarning() << "Unhandled yearly recurrence type " << mRecurrence.type << endl; } else kdWarning() << "Unhandled recurrence cycle " << mRecurrence.cycle << endl; if(mRecurrence.rangeType == "number") { recur->setDuration(mRecurrence.range.toInt()); } else if(mRecurrence.rangeType == "date") { recur->setEndDate(stringToDate(mRecurrence.range)); } // "none" is default since tje set*ly methods set infinite recurrence incidence->recurrence()->setExDates(mRecurrence.exclusions); } /* If we've stored a uid to be used internally instead of the real one * (to deal with duplicates of events in different folders) before, then * restore it, so it does not change. Keep the original uid around for * scheduling purposes. */ if(!internalUID().isEmpty()) { incidence->setUid(internalUID()); incidence->setSchedulingID(uid()); } for(QValueList<Custom>::ConstIterator it = mCustomList.begin(); it != mCustomList.end(); ++it) { incidence->setNonKDECustomProperty((*it).key, (*it).value); } }