//@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; }
void DateRangeFilterProxyModel::setStartDate( const KDateTime &date ) { if ( date.isValid() ) { d->mStart = date; invalidateFilter(); } }
void DateRangeFilterProxyModel::setEndDate( const KDateTime &date ) { if ( date.isValid() ) { d->mEnd = date.toUtc(); invalidateFilter(); } }
//! @return "opened x minutes ago" string or similar static QString openedString(const QDateTime& _opened) { const KDateTime cur(KDateTime::currentUtcDateTime()); const KDateTime opened = KDateTime(_opened); if (!opened.isValid() || opened >= cur) return QString(); const int days = opened.daysTo(cur); if (days <= 1 && opened.secsTo(cur) < 24*60*60) { const int minutes = opened.secsTo(cur) / 60; const int hours = minutes / 60; if (hours < 1) { if (minutes == 0) return i18n("Opened less than minute ago"); else return i18np("Opened 1 minute ago", "Opened %1 minutes ago", minutes); } else { return i18np("Opened 1 hour ago", "Opened %1 hours ago", hours); } } else { if (days < 30) return i18np("Opened yesterday", "Opened %1 days ago", days); if (days < 365) return i18np("Opened over a month ago", "Opened %1 months ago", days / 30); return i18np("Opened one year ago", "Opened %1 years ago", days / 365); } return QString(); }
/** static */ KDateTime AlarmDialog::triggerDateForIncidence( const Incidence::Ptr &incidence, const QDateTime &reminderAt, QString &displayStr ) { KDateTime result; if ( incidence->alarms().isEmpty() ) { return result; } Alarm::Ptr alarm = incidence->alarms().first(); if ( incidence->recurs() ) { result = incidence->recurrence()->getNextDateTime( KDateTime( reminderAt, KDateTime::Spec::LocalZone( ) ) ); displayStr = KGlobal::locale()->formatDateTime( result.toLocalZone() ); } if ( !result.isValid() ) { result = incidence->dateTime( Incidence::RoleAlarm ); displayStr = IncidenceFormatter::dateTimeToString( result, false, true, KDateTime::Spec::LocalZone() ); } return result; }
QString DateStringBuilder::getDateString(const KDateTime &dateTime, bool grouped) { if (!dateTime.isValid() || dateTime.isNull()) { return QString(); } QString day; if (QDateTime().currentDateTime().date() == dateTime.date()) { day = i18nc( "today", "Today" ); } if (QDateTime().currentDateTime().date().addDays(1) == dateTime.date()) { day = i18nc( "tomorrow", "Tomorrow" ); } if (QDateTime().currentDateTime().date() == dateTime.date().addDays(1)) { day = i18nc( "yesterday", "Yesterday" ); } if (!grouped && !day.isEmpty()) { return day.append("/t").append(dateTime.toString("%d.%m.%Y")); } if (!grouped && day.isEmpty()) { return dateTime.toString("%:a %d.%m.%Y"); } if (QDateTime().currentDateTime().date().weekNumber() == dateTime.date().weekNumber()) { return dateTime.toString("%A"); } //TODO last week return dateTime.toString("%B"); //KGlobal::locale()->formatDate(pimitem->getPrimaryDate().dateTime()); //return pimitem->getPrimaryDate().dateTime().toString("ddd dd.MM hh:mm"); //return dateTime.toString("%:a %d.%m.%Y"); }
void CalSettings::loadSpecial(const QUrl& url, const QColor& color) { if (url.isEmpty()) { qCDebug(DIGIKAM_GENERAL_LOG) << "Loading calendar from file failed: No valid url provided!"; return; } KCalCore::MemoryCalendar::Ptr memCal(new KCalCore::MemoryCalendar(QString::fromLatin1("UTC"))); KCalCore::FileStorage::Ptr fileStorage(new KCalCore::FileStorage(memCal, url.toLocalFile(), new KCalCore::ICalFormat)); qCDebug(DIGIKAM_GENERAL_LOG) << "Loading calendar from file " << url.toLocalFile(); if (!fileStorage->load()) { qCDebug(DIGIKAM_GENERAL_LOG) << "Failed!"; } else { CalSystem calSys; QDate qFirst, qLast; qFirst = calSys.date(params.year, 1, 1); qLast = calSys.date(params.year + 1, 1, 1); qLast = qLast.addDays(-1); KDateTime dtFirst(qFirst); KDateTime dtLast(qLast); KDateTime dtCurrent; int counter = 0; KCalCore::Event::List list = memCal->rawEvents(qFirst, qLast); foreach(const KCalCore::Event::Ptr event, list) { qCDebug(DIGIKAM_GENERAL_LOG) << event->summary() << endl << "--------"; counter++; if (event->recurs()) { KCalCore::Recurrence* const recur = event->recurrence(); for (dtCurrent = recur->getNextDateTime(dtFirst.addDays(-1)); (dtCurrent <= dtLast) && dtCurrent.isValid(); dtCurrent = recur->getNextDateTime(dtCurrent)) { addSpecial(dtCurrent.date(), Day(color, event->summary())); } } else { addSpecial(event->dtStart().date(), Day(color, event->summary())); } } qCDebug(DIGIKAM_GENERAL_LOG) << "Loaded " << counter << " events"; memCal->close(); fileStorage->close(); }
static QString yearForDate( const QString &upnpDate ) { KDateTime dateTime = KDateTime::fromString( upnpDate ); int year = dateTime.date().year(); if( !dateTime.isValid() ) { year = 0; } return QString::number( year ); }
void KCalResourceSlox::parseTodoAttribute( const QDomElement &e, Todo *todo ) { QString tag = e.tagName(); QString text = decodeText( e.text() ); if ( text.isEmpty() ) return; if ( tag == fieldName( TaskBegin ) ) { KDateTime dt = WebdavHandler::sloxToKDateTime( text ); if ( dt.isValid() ) { todo->setDtStart( dt ); todo->setHasStartDate( true ); } } else if ( tag == fieldName( TaskEnd ) ) { KDateTime dt = WebdavHandler::sloxToKDateTime( text ); if ( dt.isValid() ) { todo->setDtDue( dt ); todo->setHasDueDate( true ); } } else if ( tag == fieldName( Priority ) ) { int p = text.toInt(); if ( p < 1 || p > 3 ) { kError() << "Unknown priority:" << text; } else { int priority; switch ( p ) { case 1: priority = 9; break; default: case 2: priority = 5; break; case 3: priority = 1; break; } todo->setPriority( priority ); } } else if ( tag == fieldName( PercentComplete ) ) { int completed = text.toInt(); todo->setPercentComplete( completed ); } }
QString DateStringBuilder::getFullDateTime(const KDateTime &dateTime) { if (!dateTime.isValid() || dateTime.isNull()) { return QString(); } QString date; date.append(getFullDate(dateTime)); date.append(" "); date.append(dateTime.toString("%k:%M:%S")); return date; }
static KDateTime VEventDateTimeToKDateTime(const QString &s, KDateTime::Spec &tz) { kDebug(30015) << "top... tz.offset:" << tz.timeZone().currentOffset(); if (s.endsWith('Z')) { tz = KSystemTimeZones::zone("UTC"); kDebug(30015) << "tz.offset:" << tz.timeZone().currentOffset(); kDebug(30015) << "new date string:" << s; } KDateTime ret = KDateTime::fromString(s, "yyyyMMddTHHmmss"); if (!ret.isValid()) { // "2003-01-08T13:00:00" kDebug(30015) << "parsing dateThh:mm format...from input:" << s; ret = KDateTime::fromString(s, KDateTime::ISODate); } // // Parsed as UTC, must now adjust for given timezone // if (ret.isValid() && tz.timeZone().currentOffset()) { ret.setTimeSpec(tz); } // // convert to local tz for ease of editing. // ret = ret.toLocalZone(); tz = KSystemTimeZones::local(); kDebug(30015) << "date string:" << s << "\n" << " is valid:" << ret.isValid() << "\n" << " parsed:" << ret.toString() << "\n" << " time.tz.offset:" << ret.timeZone().currentOffset() << " tz.offset:" << tz.timeZone().currentOffset(); return ret; }
void TimelineItem::insertIncidence( KCal::Incidence *incidence, const KDateTime & _start, const KDateTime & _end ) { KDateTime start = incidence->dtStart().toTimeSpec( KOPrefs::instance()->timeSpec() ); KDateTime end = incidence->dtEnd().toTimeSpec( KOPrefs::instance()->timeSpec() ); if ( _start.isValid() ) { start = _start; } if ( _end.isValid() ) { end = _end; } if ( incidence->allDay() ) { end = end.addDays( 1 ); } typedef QList<TimelineSubItem*> ItemList; ItemList list = mItemMap[incidence]; for ( ItemList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it ) { if ( KDateTime( (*it)->startTime() ) == start && KDateTime( (*it)->endTime() ) == end ) { return; } } TimelineSubItem * item = new TimelineSubItem( mCalendar, incidence, this ); QColor c1, c2, c3; colors( c1, c2, c3 ); item->setColors( c1, c2, c3 ); item->setStartTime( start.dateTime() ); item->setOriginalStart( start ); item->setEndTime( end.dateTime() ); mItemMap[incidence].append( item ); }
QString DateStringBuilder::getGroupedDate(const KDateTime &dateTime) { if (!dateTime.isValid() || dateTime.isNull()) { return QString(); } QDate currentDate = QDateTime::currentDateTime().date(); if (currentDate.weekNumber() == dateTime.date().weekNumber()) { //this week return getDayName(dateTime); } if (currentDate.addDays(-7).weekNumber() == dateTime.date().weekNumber()) { //last week return i18n("Last Week"); } if (currentDate.year() == dateTime.date().year()) { //this year return dateTime.toString("%B"); } return dateTime.toString("%B %Y"); }
QString getDayName(const KDateTime &dateTime) { if (!dateTime.isValid() || dateTime.isNull()) { return QString(); } QString day; if (QDateTime().currentDateTime().date() == dateTime.date()) { return i18n("Today" ); } if (QDateTime().currentDateTime().date().addDays(1) == dateTime.date()) { return i18n( "Tomorrow" ); } if (QDateTime().currentDateTime().date() == dateTime.date().addDays(1)) { return i18n("Yesterday" ); } return dateTime.toString("%A"); }
bool AllNotesListJob::shouldStartNewJob(const KUrl &prev, const KUrl &next) { Q_UNUSED(next); Q_D(AllNotesListJob); const QString since = prev.queryItem("since"); if (since.isEmpty()) { kDebug() << "Aborting notes fetching, no date range found in URL!"; return false; } KDateTime sinceTime; sinceTime.setTime_t(since.toLongLong()); if (!sinceTime.isValid()) { kDebug() << "Aborting notes fetching, invalid date range found in URL!"; return false; } return (sinceTime >= d->lowerLimit); }
DateTime DateTime::fromString( const QString dts, const KDateTime::Spec &spec ) { if (dts.isEmpty()) { return DateTime(); } KDateTime dt = KDateTime::fromString(dts); if ( ! dt.isValid() ) { // try to parse in qt default format (used in early version) dt = KDateTime( QDateTime::fromString(dts), spec ).toLocalZone(); return dt.dateTime(); } if ( dt.isClockTime() ) { // timezone offset missing, set to spec return DateTime( dt.toLocalZone().dateTime() ); } DateTime t = DateTime( dt.toTimeSpec( spec ).toLocalZone().dateTime() ); return t; }
QString DateStringBuilder::getShortDate(const KDateTime &dateTime) { if (!dateTime.isValid() || dateTime.isNull()) { return QString(); } QDate currentDate = QDateTime().currentDateTime().date(); if (currentDate.weekNumber() == dateTime.date().weekNumber() || currentDate.addDays(1) == dateTime.date()) { //this week or tomorrow (i.e. on sunday) return getDayName(dateTime); } if (currentDate.year() == dateTime.date().year()) { //this year //Micro optimization because this function showed up as hotspot static QCache<uint, QString> cache; uint hash = dateTime.date().month() ^ dateTime.date().day(); if (!cache.contains(hash)) { cache.insert(hash, new QString(dateTime.toString("%d.%m"))); } return *cache[hash]; } return dateTime.toString("%d.%m.%Y"); }
/****************************************************************************** * Called every minute to update the alarm time data entry fields. * If the maximum date/time has been reached, a 'pastMax()' signal is emitted. */ void AlarmTimeWidget::updateTimes() { KDateTime now; if (mMinDateTimeIsNow) { // Make sure that the minimum date is updated when the day changes now = KDateTime::currentDateTime(mTimeSpec); mDateEdit->setMinDate(now.date()); } if (mMaxDateTime.isValid()) { if (!now.isValid()) now = KDateTime::currentDateTime(mTimeSpec); if (!mPastMax) { // Check whether the maximum date/time has now been reached if (now.date() >= mMaxDateTime.date()) { // The current date has reached or has passed the maximum date if (now.date() > mMaxDateTime.date() || (!mAnyTime && now.time() > mTimeEdit->maxTime())) { mPastMax = true; emit pastMax(); } else if (mMinDateTimeIsNow && !mMinMaxTimeSet) { // The minimum date/time tracks the clock, so set the minimum // and maximum times setMaxMinTimeIf(now); } } } setMaxDelayTime(now); } if (mAtTimeRadio->isChecked()) dateTimeChanged(); else delayTimeChanged(mDelayTimeEdit->value()); }
QString dumpTime( const KDateTime &dt, const KDateTime::Spec &viewSpec ) { if ( !dt.isValid() ) { return QString(); } KDateTime vdt = viewSpec.isValid() ? dt.toTimeSpec( viewSpec ) : dt; QString format; #ifdef FLOAT_IS_DATE_ONLY if ( vdt.isDateOnly() ) { format = QLatin1String( "%Y-%m-%d" ); } else #endif format = QLatin1String( "%Y-%m-%dT%H:%M:%S" ); if ( vdt.isSecondOccurrence() ) { format += QLatin1String( " %Z" ); } if ( vdt.timeSpec() != KDateTime::ClockTime ) { format += QLatin1String( " %:Z" ); } return vdt.toString( format ); }
KCal::Alarm::List ResourceKolab::alarms( const KDateTime& from, const KDateTime& to ) { KCal::Alarm::List alarms; KCal::Journal::List notes = mCalendar.journals(); KCal::Journal::List::ConstIterator note; for ( note = notes.constBegin(); note != notes.constEnd(); ++note ) { KDateTime preTime = from.addSecs( -1 ); KCal::Alarm::List::ConstIterator it; for( it = (*note)->alarms().constBegin(); it != (*note)->alarms().constEnd(); ++it ) { if ( (*it)->enabled() ) { KDateTime dt = (*it)->nextRepetition( preTime ); if ( dt.isValid() && dt <= to ) alarms.append( *it ); } } } return alarms; }
Incidence::Ptr pasteIncidence( const Incidence::Ptr &incidence, KDateTime newDateTime, const QFlags<PasteFlag> &pasteOptions ) { Incidence::Ptr inc( incidence ); if ( inc ) { inc = Incidence::Ptr( inc->clone() ); inc->recreate(); } if ( inc && newDateTime.isValid() ) { if ( inc->type() == Incidence::TypeEvent ) { Event::Ptr event = inc.staticCast<Event>(); if ( pasteOptions & FlagPasteAtOriginalTime ) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = event->dtStart(); newDateTime.setDate( date ); } // in seconds const int durationInSeconds = event->dtStart().secsTo( event->dtEnd() ); const int durationInDays = event->dtStart().daysTo( event->dtEnd() ); event->setDtStart( newDateTime ); if ( newDateTime.isDateOnly() ) { event->setDtEnd( newDateTime.addDays( durationInDays ) ); } else { event->setDtEnd( newDateTime.addSecs( durationInSeconds ) ); } } else if ( inc->type() == Incidence::TypeTodo ) { Todo::Ptr aTodo = inc.staticCast<Todo>(); const bool pasteAtDtStart = ( pasteOptions & FlagTodosPasteAtDtStart ); if ( pasteOptions & FlagPasteAtOriginalTime ) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = pasteAtDtStart ? aTodo->dtStart() : aTodo->dtDue(); newDateTime.setDate( date ); } if ( pasteAtDtStart ) { aTodo->setDtStart( newDateTime ); } else { aTodo->setDtDue( newDateTime ); } } else if ( inc->type() == Incidence::TypeJournal ) { if ( pasteOptions & FlagPasteAtOriginalTime ) { // Set date and preserve time and timezone stuff const QDate date = newDateTime.date(); newDateTime = inc->dtStart(); newDateTime.setDate( date ); } inc->setDtStart( newDateTime ); } else { kDebug() << "Trying to paste unknown incidence of type" << int( inc->type() ); } } return inc; }
void CompatPre410::setCreatedToDtStamp( const Incidence::Ptr &incidence, const KDateTime &dtstamp ) { if ( dtstamp.isValid() ) { incidence->setCreated( dtstamp ); } }
KDateTime Recurrence::getPreviousDateTime( const KDateTime &afterDateTime ) const { KDateTime prevDT = afterDateTime; // prevent infinite loops, e.g. when an exrule extinguishes an rrule (e.g. // the exrule is identical to the rrule). If an occurrence is found, break // out of the loop by returning that KDateTime int loop = 0; while ( loop < 1000 ) { // Outline of the algo: // 1) Find the next date/time after preDateTime when the event could recur // 1.1) Use the next occurrence from the explicit RDATE lists // 1.2) Add the next recurrence for each of the RRULEs // 2) Take the earliest recurrence of these = KDateTime nextDT // 3) If that date/time is not excluded, either explicitly by an EXDATE or // by an EXRULE, return nextDT as the next date/time of the recurrence // 4) If it's excluded, start all at 1), but starting at nextDT (instead // of preDateTime). Loop at most 1000 times. ++loop; // First, get the next recurrence from the RDate lists DateTimeList dates; if ( prevDT > startDateTime() ) { dates << startDateTime(); } int i = d->mRDateTimes.findLT( prevDT ); if ( i >= 0 ) { dates << d->mRDateTimes[i]; } KDateTime kdt( startDateTime() ); for ( i = d->mRDates.count(); --i >= 0; ) { kdt.setDate( d->mRDates[i] ); if ( kdt < prevDT ) { dates << kdt; break; } } // Add the previous occurrences from all RRULEs. int end; for ( i = 0, end = d->mRRules.count(); i < end; ++i ) { KDateTime dt = d->mRRules[i]->getPreviousDate( prevDT ); if ( dt.isValid() ) { dates << dt; } } // Take the last of these (all others can't be used later on) dates.sortUnique(); if ( dates.isEmpty() ) { return KDateTime(); } prevDT = dates.last(); // Check if that date/time is excluded explicitly or by an exrule: if ( !d->mExDates.containsSorted( prevDT.date() ) && !d->mExDateTimes.containsSorted( prevDT ) ) { bool allowed = true; for ( i = 0, end = d->mExRules.count(); i < end; ++i ) { allowed = allowed && !( d->mExRules[i]->recursAt( prevDT ) ); } if ( allowed ) { return prevDT; } } } // Couldn't find a valid occurrences in 1000 loops, something is wrong! return KDateTime(); }
QString KTnef::msTNEFToVPart( const QByteArray &tnef ) { bool bOk = false; KTNEFParser parser; QByteArray b( tnef ); QBuffer buf( &b ); MemoryCalendar::Ptr cal( new MemoryCalendar( KDateTime::UTC ) ); KABC::Addressee addressee; ICalFormat calFormat; Event::Ptr event( new Event() ); if ( parser.openDevice( &buf ) ) { KTNEFMessage *tnefMsg = parser.message(); //QMap<int,KTNEFProperty*> props = parser.message()->properties(); // Everything depends from property PR_MESSAGE_CLASS // (this is added by KTNEFParser): QString msgClass = tnefMsg->findProp( 0x001A, QString(), true ).toUpper(); if ( !msgClass.isEmpty() ) { // Match the old class names that might be used by Outlook for // compatibility with Microsoft Mail for Windows for Workgroups 3.1. bool bCompatClassAppointment = false; bool bCompatMethodRequest = false; bool bCompatMethodCancled = false; bool bCompatMethodAccepted = false; bool bCompatMethodAcceptedCond = false; bool bCompatMethodDeclined = false; if ( msgClass.startsWith( QLatin1String( "IPM.MICROSOFT SCHEDULE." ) ) ) { bCompatClassAppointment = true; if ( msgClass.endsWith( QLatin1String( ".MTGREQ" ) ) ) { bCompatMethodRequest = true; } if ( msgClass.endsWith( QLatin1String( ".MTGCNCL" ) ) ) { bCompatMethodCancled = true; } if ( msgClass.endsWith( QLatin1String( ".MTGRESPP" ) ) ) { bCompatMethodAccepted = true; } if ( msgClass.endsWith( QLatin1String( ".MTGRESPA" ) ) ) { bCompatMethodAcceptedCond = true; } if ( msgClass.endsWith( QLatin1String( ".MTGRESPN" ) ) ) { bCompatMethodDeclined = true; } } bool bCompatClassNote = ( msgClass == "IPM.MICROSOFT MAIL.NOTE" ); if ( bCompatClassAppointment || "IPM.APPOINTMENT" == msgClass ) { // Compose a vCal bool bIsReply = false; QString prodID = "-//Microsoft Corporation//Outlook "; prodID += tnefMsg->findNamedProp( "0x8554", "9.0" ); prodID += "MIMEDIR/EN\n"; prodID += "VERSION:2.0\n"; calFormat.setApplication( "Outlook", prodID ); iTIPMethod method; if ( bCompatMethodRequest ) { method = iTIPRequest; } else if ( bCompatMethodCancled ) { method = iTIPCancel; } else if ( bCompatMethodAccepted || bCompatMethodAcceptedCond || bCompatMethodDeclined ) { method = iTIPReply; bIsReply = true; } else { // pending(khz): verify whether "0x0c17" is the right tag ??? // // at the moment we think there are REQUESTS and UPDATES // // but WHAT ABOUT REPLIES ??? // // if ( tnefMsg->findProp(0x0c17) == "1" ) { bIsReply = true; } method = iTIPRequest; } /// ### FIXME Need to get this attribute written ScheduleMessage schedMsg( event, method, ScheduleMessage::Unknown ); QString sSenderSearchKeyEmail( tnefMsg->findProp( 0x0C1D ) ); if ( !sSenderSearchKeyEmail.isEmpty() ) { int colon = sSenderSearchKeyEmail.indexOf( ':' ); // May be e.g. "SMTP:[email protected]" if ( sSenderSearchKeyEmail.indexOf( ':' ) == -1 ) { sSenderSearchKeyEmail.remove( 0, colon+1 ); } } QString s( tnefMsg->findProp( 0x8189 ) ); const QStringList attendees = s.split( ';' ); if ( attendees.count() ) { for ( QStringList::const_iterator it = attendees.begin(); it != attendees.end(); ++it ) { // Skip all entries that have no '@' since these are // no mail addresses if ( (*it).indexOf( '@' ) == -1 ) { s = (*it).trimmed(); Attendee::Ptr attendee( new Attendee( s, s, true ) ); if ( bIsReply ) { if ( bCompatMethodAccepted ) { attendee->setStatus( Attendee::Accepted ); } if ( bCompatMethodDeclined ) { attendee->setStatus( Attendee::Declined ); } if ( bCompatMethodAcceptedCond ) { attendee->setStatus( Attendee::Tentative ); } } else { attendee->setStatus( Attendee::NeedsAction ); attendee->setRole( Attendee::ReqParticipant ); } event->addAttendee( attendee ); } } } else { // Oops, no attendees? // This must be old style, let us use the PR_SENDER_SEARCH_KEY. s = sSenderSearchKeyEmail; if ( !s.isEmpty() ) { Attendee::Ptr attendee( new Attendee( QString(), QString(), true ) ); if ( bIsReply ) { if ( bCompatMethodAccepted ) { attendee->setStatus( Attendee::Accepted ); } if ( bCompatMethodAcceptedCond ) { attendee->setStatus( Attendee::Declined ); } if ( bCompatMethodDeclined ) { attendee->setStatus( Attendee::Tentative ); } } else { attendee->setStatus( Attendee::NeedsAction ); attendee->setRole( Attendee::ReqParticipant ); } event->addAttendee( attendee ); } } s = tnefMsg->findProp( 0x3ff8 ); // look for organizer property if ( s.isEmpty() && !bIsReply ) { s = sSenderSearchKeyEmail; } // TODO: Use the common name? if ( !s.isEmpty() ) { event->setOrganizer( s ); } s = tnefMsg->findProp( 0x819b ).remove( QChar( '-' ) ).remove( QChar( ':' ) ); event->setDtStart( KDateTime::fromString( s ) ); // ## Format?? s = tnefMsg->findProp( 0x819c ).remove( QChar( '-' ) ).remove( QChar( ':' ) ); event->setDtEnd( KDateTime::fromString( s ) ); s = tnefMsg->findProp( 0x810d ); event->setLocation( s ); // is it OK to set this to OPAQUE always ?? //vPart += "TRANSP:OPAQUE\n"; ###FIXME, portme! //vPart += "SEQUENCE:0\n"; // is "0x0023" OK - or should we look for "0x0003" ?? s = tnefMsg->findProp( 0x0023 ); event->setUid( s ); // PENDING(khz): is this value in local timezone? Must it be // adjusted? Most likely this is a bug in the server or in // Outlook - we ignore it for now. s = tnefMsg->findProp( 0x8202 ).remove( QChar( '-' ) ).remove( QChar( ':' ) ); // ### kcal always uses currentDateTime() // event->setDtStamp( QDateTime::fromString( s ) ); s = tnefMsg->findNamedProp( "Keywords" ); event->setCategories( s ); s = tnefMsg->findProp( 0x1000 ); event->setDescription( s ); s = tnefMsg->findProp( 0x0070 ); event->setSummary( s ); s = tnefMsg->findProp( 0x0026 ); event->setPriority( s.toInt() ); // is reminder flag set ? if ( !tnefMsg->findProp( 0x8503 ).isEmpty() ) { Alarm::Ptr alarm( new Alarm( event.data() ) ); // TODO: fix when KCalCore::Alarm is fixed KDateTime highNoonTime = pureISOToLocalQDateTime( tnefMsg->findProp( 0x8502 ). remove( QChar( '-' ) ).remove( QChar( ':' ) ) ); KDateTime wakeMeUpTime = pureISOToLocalQDateTime( tnefMsg->findProp( 0x8560, "" ). remove( QChar( '-' ) ).remove( QChar( ':' ) ) ); alarm->setTime( wakeMeUpTime ); if ( highNoonTime.isValid() && wakeMeUpTime.isValid() ) { alarm->setStartOffset( Duration( highNoonTime, wakeMeUpTime ) ); } else { // default: wake them up 15 minutes before the appointment alarm->setStartOffset( Duration( 15 * 60 ) ); } alarm->setDisplayAlarm( i18n( "Reminder" ) ); // Sorry: the different action types are not known (yet) // so we always set 'DISPLAY' (no sounds, no images...) event->addAlarm( alarm ); } //ensure we have a uid for this event if ( event->uid().isEmpty() ) { event->setUid( CalFormat::createUniqueId() ); } cal->addEvent( event ); bOk = true; // we finished composing a vCal } else if ( bCompatClassNote || "IPM.CONTACT" == msgClass ) { addressee.setUid( stringProp( tnefMsg, attMSGID ) ); addressee.setFormattedName( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME ) ); addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL1EMAILADDRESS ), true ); addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL2EMAILADDRESS ), false ); addressee.insertEmail( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_EMAIL3EMAILADDRESS ), false ); addressee.insertCustom( "KADDRESSBOOK", "X-IMAddress", sNamedProp( tnefMsg, MAPI_TAG_CONTACT_IMADDRESS ) ); addressee.insertCustom( "KADDRESSBOOK", "X-SpousesName", stringProp( tnefMsg, MAPI_TAG_PR_SPOUSE_NAME ) ); addressee.insertCustom( "KADDRESSBOOK", "X-ManagersName", stringProp( tnefMsg, MAPI_TAG_PR_MANAGER_NAME ) ); addressee.insertCustom( "KADDRESSBOOK", "X-AssistantsName", stringProp( tnefMsg, MAPI_TAG_PR_ASSISTANT ) ); addressee.insertCustom( "KADDRESSBOOK", "X-Department", stringProp( tnefMsg, MAPI_TAG_PR_DEPARTMENT_NAME ) ); addressee.insertCustom( "KADDRESSBOOK", "X-Office", stringProp( tnefMsg, MAPI_TAG_PR_OFFICE_LOCATION ) ); addressee.insertCustom( "KADDRESSBOOK", "X-Profession", stringProp( tnefMsg, MAPI_TAG_PR_PROFESSION ) ); QString s = tnefMsg->findProp( MAPI_TAG_PR_WEDDING_ANNIVERSARY ). remove( QChar( '-' ) ).remove( QChar( ':' ) ); if ( !s.isEmpty() ) { addressee.insertCustom( "KADDRESSBOOK", "X-Anniversary", s ); } addressee.setUrl( KUrl( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_WEBPAGE ) ) ); // collect parts of Name entry addressee.setFamilyName( stringProp( tnefMsg, MAPI_TAG_PR_SURNAME ) ); addressee.setGivenName( stringProp( tnefMsg, MAPI_TAG_PR_GIVEN_NAME ) ); addressee.setAdditionalName( stringProp( tnefMsg, MAPI_TAG_PR_MIDDLE_NAME ) ); addressee.setPrefix( stringProp( tnefMsg, MAPI_TAG_PR_DISPLAY_NAME_PREFIX ) ); addressee.setSuffix( stringProp( tnefMsg, MAPI_TAG_PR_GENERATION ) ); addressee.setNickName( stringProp( tnefMsg, MAPI_TAG_PR_NICKNAME ) ); addressee.setRole( stringProp( tnefMsg, MAPI_TAG_PR_TITLE ) ); addressee.setOrganization( stringProp( tnefMsg, MAPI_TAG_PR_COMPANY_NAME ) ); /* the MAPI property ID of this (multiline) )field is unknown: vPart += stringProp(tnefMsg, "\n","NOTE", ... , "" ); */ KABC::Address adr; adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_PO_BOX ) ); adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STREET ) ); adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_CITY ) ); adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_STATE_OR_PROVINCE ) ); adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_POSTAL_CODE ) ); adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_HOME_ADDRESS_COUNTRY ) ); adr.setType( KABC::Address::Home ); addressee.insertAddress( adr ); adr.setPostOfficeBox( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOBOX ) ); adr.setStreet( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTREET ) ); adr.setLocality( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCITY ) ); adr.setRegion( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSSTATE ) ); adr.setPostalCode( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSPOSTALCODE ) ); adr.setCountry( sNamedProp( tnefMsg, MAPI_TAG_CONTACT_BUSINESSADDRESSCOUNTRY ) ); adr.setType( KABC::Address::Work ); addressee.insertAddress( adr ); adr.setPostOfficeBox( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_PO_BOX ) ); adr.setStreet( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STREET ) ); adr.setLocality( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_CITY ) ); adr.setRegion( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_STATE_OR_PROVINCE ) ); adr.setPostalCode( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_POSTAL_CODE ) ); adr.setCountry( stringProp( tnefMsg, MAPI_TAG_PR_OTHER_ADDRESS_COUNTRY ) ); adr.setType( KABC::Address::Dom ); addressee.insertAddress( adr ); // problem: the 'other' address was stored by KOrganizer in // a line looking like the following one: // vPart += "\nADR;TYPE=dom;TYPE=intl;TYPE=parcel;TYPE=postal;TYPE=work;" // "TYPE=home:other_pobox;;other_str1\nother_str2;other_loc;other_region;" // "other_pocode;other_country" QString nr; nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_TELEPHONE_NUMBER ); addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Home ) ); nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_TELEPHONE_NUMBER ); addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Work ) ); nr = stringProp( tnefMsg, MAPI_TAG_PR_MOBILE_TELEPHONE_NUMBER ); addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Cell ) ); nr = stringProp( tnefMsg, MAPI_TAG_PR_HOME_FAX_NUMBER ); addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home ) ); nr = stringProp( tnefMsg, MAPI_TAG_PR_BUSINESS_FAX_NUMBER ); addressee.insertPhoneNumber( KABC::PhoneNumber( nr, KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work ) ); s = tnefMsg->findProp( MAPI_TAG_PR_BIRTHDAY ). remove( QChar( '-' ) ).remove( QChar( ':' ) ); if ( !s.isEmpty() ) { addressee.setBirthday( QDateTime::fromString( s ) ); } bOk = ( !addressee.isEmpty() ); } else if ( "IPM.NOTE" == msgClass ) { } // else if ... and so on ... } } // Compose return string // KDAB_TODO: Interesting, without the explicit QString the toString call is // reported to be ambigious with toString( const Incidence::Ptr & ). const QString iCal = calFormat.toString( cal, QString() ); if ( !iCal.isEmpty() ) { // This was an iCal return iCal; } // Not an iCal - try a vCard KABC::VCardConverter converter; return QString::fromUtf8( converter.createVCard( addressee ) ); }