diff options
Diffstat (limited to 'kresources/kolab/kcal/incidence.cpp')
-rw-r--r-- | kresources/kolab/kcal/incidence.cpp | 1039 |
1 files changed, 0 insertions, 1039 deletions
diff --git a/kresources/kolab/kcal/incidence.cpp b/kresources/kolab/kcal/incidence.cpp deleted file mode 100644 index ddc31491b..000000000 --- a/kresources/kolab/kcal/incidence.cpp +++ /dev/null @@ -1,1039 +0,0 @@ -/* - This file is part of the kolab resource - the implementation of the - Kolab storage format. See www.kolab.org for documentation on this. - - Copyright (c) 2004 Bo Thorsen <bo@sonofthor.dk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - In addition, as a special exception, the copyright holders give - permission to link the code of this program with any edition of - the TQt library by Trolltech AS, Norway (or with modified versions - of TQt that use the same license as TQt), and distribute linked - combinations including the two. You must obey the GNU General - Public License in all respects for all of the code used other than - TQt. If you modify this file, you may extend this exception to - your version of the file, but you are not obligated to do so. If - you do not wish to do so, delete this exception statement from - your version. -*/ - -#include "incidence.h" -#include "resourcekolab.h" - -#include <tqfile.h> -#include <tqvaluelist.h> - -#include <libkcal/journal.h> -#include <korganizer/version.h> -#include <libemailfunctions/email.h> - -#include <kdebug.h> -#include <kmdcodec.h> -#include <kurl.h> -#include <kio/netaccess.h> - -using namespace Kolab; - - -Incidence::Incidence( KCal::ResourceKolab *res, const TQString &subResource, TQ_UINT32 sernum, - const TQString& tz ) - : KolabBase( tz ), mFloatingStatus( Unset ), mHasAlarm( false ), - mResource( res ), - mSubResource( subResource ), - mSernum( sernum ) -{ -} - -Incidence::~Incidence() -{ -} - -void Incidence::setSummary( const TQString& summary ) -{ - mSummary = summary; -} - -TQString Incidence::summary() const -{ - return mSummary; -} - -void Incidence::setLocation( const TQString& location ) -{ - mLocation = location; -} - -TQString Incidence::location() const -{ - return mLocation; -} - -void Incidence::setOrganizer( const Email& organizer ) -{ - mOrganizer = organizer; -} - -KolabBase::Email Incidence::organizer() const -{ - return mOrganizer; -} - -void Incidence::setStartDate( const TQDateTime& startDate ) -{ - mStartDate = startDate; - if ( mFloatingStatus == AllDay ) - kdDebug() << "ERROR: Time on start date but no time on the event\n"; - mFloatingStatus = HasTime; -} - -void Incidence::setStartDate( const TQDate& startDate ) -{ - mStartDate = startDate; - if ( mFloatingStatus == HasTime ) - kdDebug() << "ERROR: No time on start date but time on the event\n"; - mFloatingStatus = AllDay; -} - -void Incidence::setStartDate( const TQString& startDate ) -{ - if ( startDate.length() > 10 ) - // This is a date + time - setStartDate( stringToDateTime( startDate ) ); - else - // This is only a date - setStartDate( stringToDate( startDate ) ); -} - -TQDateTime Incidence::startDate() const -{ - return mStartDate; -} - -void Incidence::setAlarm( float alarm ) -{ - mAlarm = alarm; - mHasAlarm = true; -} - -float Incidence::alarm() const -{ - return mAlarm; -} - -Incidence::Recurrence Incidence::recurrence() const -{ - return mRecurrence; -} - -void Incidence::addAttendee( const Attendee& attendee ) -{ - mAttendees.append( attendee ); -} - -TQValueList<Incidence::Attendee>& Incidence::attendees() -{ - return mAttendees; -} - -const TQValueList<Incidence::Attendee>& Incidence::attendees() const -{ - return mAttendees; -} - -void Incidence::setInternalUID( const TQString& iuid ) -{ - mInternalUID = iuid; -} - -TQString Incidence::internalUID() const -{ - return mInternalUID; -} - -bool Incidence::loadAttendeeAttribute( TQDomElement& element, - Attendee& attendee ) -{ - for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - TQString tagName = e.tagName(); - - if ( tagName == "display-name" ) { - // Quote the text in case it contains commas or other quotable chars. - TQString tusername = KPIM::quoteNameIfNecessary( e.text() ); - - TQString tname, temail; - // ignore the return value because it will always be false since - // tusername does not contain "@domain". - KPIM::getNameAndMail( tusername, tname, temail ); - attendee.displayName = tname; - } - else if ( tagName == "smtp-address" ) - attendee.smtpAddress = e.text(); - else if ( tagName == "status" ) - attendee.status = e.text(); - else if ( tagName == "request-response" ) - // This sets reqResp to false, if the text is "false". Otherwise it - // sets it to true. This means the default setting is true. - attendee.requestResponse = ( e.text().lower() != "false" ); - else if ( tagName == "invitation-sent" ) - // Like above, only this defaults to false - attendee.invitationSent = ( e.text().lower() != "true" ); - else if ( tagName == "role" ) - attendee.role = e.text(); - else if ( tagName == "delegated-to" ) - attendee.delegate = e.text(); - else if ( tagName == "delegated-from" ) - attendee.delegator = e.text(); - else - // TODO: Unhandled tag - save for later storage - kdDebug() << "Warning: Unhandled tag " << e.tagName() << endl; - } else - kdDebug() << "Node is not a comment or an element???" << endl; - } - - return true; -} - -void Incidence::saveAttendeeAttribute( TQDomElement& element, - const Attendee& attendee ) const -{ - TQDomElement e = element.ownerDocument().createElement( "attendee" ); - element.appendChild( e ); - writeString( e, "display-name", attendee.displayName ); - writeString( e, "smtp-address", attendee.smtpAddress ); - writeString( e, "status", attendee.status ); - writeString( e, "request-response", - ( attendee.requestResponse ? "true" : "false" ) ); - writeString( e, "invitation-sent", - ( attendee.invitationSent ? "true" : "false" ) ); - writeString( e, "role", attendee.role ); - writeString( e, "delegated-to", attendee.delegate ); - writeString( e, "delegated-from", attendee.delegator ); -} - -void Incidence::saveAttendees( TQDomElement& element ) const -{ - TQValueList<Attendee>::ConstIterator it = mAttendees.begin(); - for ( ; it != mAttendees.end(); ++it ) - saveAttendeeAttribute( element, *it ); -} - -void Incidence::saveAttachments( TQDomElement& element ) const -{ - KCal::Attachment::List::ConstIterator it = mAttachments.begin(); - for ( ; it != mAttachments.end(); ++it ) { - KCal::Attachment *a = (*it); - if ( a->isUri() ) { - writeString( element, "link-attachment", a->uri() ); - } else if ( a->isBinary() ) { - writeString( element, "inline-attachment", a->label() ); - } - } -} - -void Incidence::saveAlarms( TQDomElement& element ) const -{ - if ( mAlarms.isEmpty() ) return; - - TQDomElement list = element.ownerDocument().createElement( "advanced-alarms" ); - element.appendChild( list ); - for ( KCal::Alarm::List::ConstIterator it = mAlarms.constBegin(); it != mAlarms.constEnd(); ++it ) { - KCal::Alarm* a = *it; - TQDomElement e = list.ownerDocument().createElement( "alarm" ); - list.appendChild( e ); - - writeString( e, "enabled", a->enabled() ? "1" : "0" ); - if ( a->hasStartOffset() ) { - writeString( e, "start-offset", TQString::number( a->startOffset().asSeconds()/60 ) ); - } - if ( a->hasEndOffset() ) { - writeString( e, "end-offset", TQString::number( a->endOffset().asSeconds()/60 ) ); - } - if ( a->repeatCount() ) { - writeString( e, "repeat-count", TQString::number( a->repeatCount() ) ); - writeString( e, "repeat-interval", TQString::number( a->snoozeTime() ) ); - } - - switch ( a->type() ) { - case KCal::Alarm::Invalid: - break; - case KCal::Alarm::Display: - e.setAttribute( "type", "display" ); - writeString( e, "text", a->text() ); - break; - case KCal::Alarm::Procedure: - e.setAttribute( "type", "procedure" ); - writeString( e, "program", a->programFile() ); - writeString( e, "arguments", a->programArguments() ); - break; - case KCal::Alarm::Email: - { - e.setAttribute( "type", "email" ); - TQDomElement addresses = e.ownerDocument().createElement( "addresses" ); - e.appendChild( addresses ); - for ( TQValueList<KCal::Person>::ConstIterator it = a->mailAddresses().constBegin(); it != a->mailAddresses().constEnd(); ++it ) { - writeString( addresses, "address", (*it).fullName() ); - } - writeString( e, "subject", a->mailSubject() ); - writeString( e, "mail-text", a->mailText() ); - TQDomElement attachments = e.ownerDocument().createElement( "attachments" ); - e.appendChild( attachments ); - for ( TQStringList::ConstIterator it = a->mailAttachments().constBegin(); it != a->mailAttachments().constEnd(); ++it ) { - writeString( attachments, "attachment", *it ); - } - break; - } - case KCal::Alarm::Audio: - e.setAttribute( "type", "audio" ); - writeString( e, "file", a->audioFile() ); - break; - default: - kdWarning() << "Unhandled alarm type:" << a->type() << endl; - break; - } - } -} - -void Incidence::saveRecurrence( TQDomElement& element ) const -{ - TQDomElement e = element.ownerDocument().createElement( "recurrence" ); - element.appendChild( e ); - e.setAttribute( "cycle", mRecurrence.cycle ); - if ( !mRecurrence.type.isEmpty() ) - e.setAttribute( "type", mRecurrence.type ); - writeString( e, "interval", TQString::number( mRecurrence.interval ) ); - for( TQStringList::ConstIterator it = mRecurrence.days.begin(); it != mRecurrence.days.end(); ++it ) { - writeString( e, "day", *it ); - } - if ( !mRecurrence.dayNumber.isEmpty() ) - writeString( e, "daynumber", mRecurrence.dayNumber ); - if ( !mRecurrence.month.isEmpty() ) - writeString( e, "month", mRecurrence.month ); - if ( !mRecurrence.rangeType.isEmpty() ) { - TQDomElement range = element.ownerDocument().createElement( "range" ); - e.appendChild( range ); - range.setAttribute( "type", mRecurrence.rangeType ); - TQDomText t = element.ownerDocument().createTextNode( mRecurrence.range ); - range.appendChild( t ); - } - for( TQValueList<TQDate>::ConstIterator it = mRecurrence.exclusions.begin(); - it != mRecurrence.exclusions.end(); ++it ) { - writeString( e, "exclusion", dateToString( *it ) ); - } -} - -void Incidence::loadRecurrence( const TQDomElement& element ) -{ - mRecurrence.interval = 0; - mRecurrence.cycle = element.attribute( "cycle" ); - mRecurrence.type = element.attribute( "type" ); - for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - TQString tagName = e.tagName(); - - if ( tagName == "interval" ) { - //kolab/issue4229, sometimes the interval value can be empty - if ( e.text().isEmpty() || e.text().toInt() <= 0 ) { - mRecurrence.interval = 1; - } else { - mRecurrence.interval = e.text().toInt(); - } - } - else if ( tagName == "day" ) // can be present multiple times - mRecurrence.days.append( e.text() ); - else if ( tagName == "daynumber" ) - mRecurrence.dayNumber = e.text(); - else if ( tagName == "month" ) - mRecurrence.month = e.text(); - else if ( tagName == "range" ) { - mRecurrence.rangeType = e.attribute( "type" ); - mRecurrence.range = e.text(); - } else if ( tagName == "exclusion" ) { - mRecurrence.exclusions.append( stringToDate( e.text() ) ); - } else - // TODO: Unhandled tag - save for later storage - kdDebug() << "Warning: Unhandled tag " << e.tagName() << endl; - } - } -} - -static void loadAddressesHelper( const TQDomElement& element, KCal::Alarm* a ) -{ - for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - TQString tagName = e.tagName(); - - if ( tagName == "address" ) { - a->addMailAddress( KCal::Person( e.text() ) ); - } else { - kdWarning() << "Unhandled tag" << tagName << endl; - } - } - } -} - -static void loadAttachmentsHelper( const TQDomElement& element, KCal::Alarm* a ) -{ - for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - TQString tagName = e.tagName(); - - if ( tagName == "attachment" ) { - a->addMailAttachment( e.text() ); - } else { - kdWarning() << "Unhandled tag" << tagName << endl; - } - } - } -} - -static void loadAlarmHelper( const TQDomElement& element, KCal::Alarm* a ) -{ - for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - TQString tagName = e.tagName(); - - if ( tagName == "start-offset" ) { - a->setStartOffset( e.text().toInt()*60 ); - } else if ( tagName == "end-offset" ) { - a->setEndOffset( e.text().toInt()*60 ); - } else if ( tagName == "repeat-count" ) { - a->setRepeatCount( e.text().toInt() ); - } else if ( tagName == "repeat-interval" ) { - a->setSnoozeTime( e.text().toInt() ); - } else if ( tagName == "text" ) { - a->setText( e.text() ); - } else if ( tagName == "program" ) { - a->setProgramFile( e.text() ); - } else if ( tagName == "arguments" ) { - a->setProgramArguments( e.text() ); - } else if ( tagName == "addresses" ) { - loadAddressesHelper( e, a ); - } else if ( tagName == "subject" ) { - a->setMailSubject( e.text() ); - } else if ( tagName == "mail-text" ) { - a->setMailText( e.text() ); - } else if ( tagName == "attachments" ) { - loadAttachmentsHelper( e, a ); - } else if ( tagName == "file" ) { - a->setAudioFile( e.text() ); - } else if ( tagName == "enabled" ) { - a->setEnabled( e.text().toInt() != 0 ); - } else { - kdWarning() << "Unhandled tag" << tagName << endl; - } - } - } -} - -void Incidence::loadAlarms( const TQDomElement& element ) -{ - for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - TQString tagName = e.tagName(); - - if ( tagName == "alarm" ) { - KCal::Alarm *a = new KCal::Alarm( 0 ); - a->setEnabled( true ); // default to enabled, unless some XML attribute says otherwise. - TQString type = e.attribute( "type" ); - if ( type == "display" ) { - a->setType( KCal::Alarm::Display ); - } else if ( type == "procedure" ) { - a->setType( KCal::Alarm::Procedure ); - } else if ( type == "email" ) { - a->setType( KCal::Alarm::Email ); - } else if ( type == "audio" ) { - a->setType( KCal::Alarm::Audio ); - } else { - kdWarning() << "Unhandled alarm type:" << type << endl; - } - - loadAlarmHelper( e, a ); - mAlarms << a; - } else { - kdWarning() << "Unhandled tag" << tagName << endl; - } - } - } -} - -bool Incidence::loadAttribute( TQDomElement& element ) -{ - TQString tagName = element.tagName(); - - if ( tagName == "summary" ) - setSummary( element.text() ); - else if ( tagName == "location" ) - setLocation( element.text() ); - else if ( tagName == "organizer" ) { - Email email; - if ( loadEmailAttribute( element, email ) ) { - setOrganizer( email ); - return true; - } else - return false; - } else if ( tagName == "start-date" ) - setStartDate( element.text() ); - else if ( tagName == "recurrence" ) - loadRecurrence( element ); - else if ( tagName == "attendee" ) { - Attendee attendee; - if ( loadAttendeeAttribute( element, attendee ) ) { - addAttendee( attendee ); - return true; - } else - return false; - } else if ( tagName == "link-attachment" ) { - mAttachments.push_back( new KCal::Attachment( element.text() ) ); - } else if ( tagName == "alarm" ) - // Alarms should be minutes before. Libkcal uses event time + alarm time - setAlarm( - element.text().toInt() ); - else if ( tagName == "advanced-alarms" ) - loadAlarms( element ); - else if ( tagName == "x-kde-internaluid" ) - setInternalUID( element.text() ); - else if ( tagName == "x-custom" ) - loadCustomAttributes( element ); - else { - bool ok = KolabBase::loadAttribute( element ); - if ( !ok ) { - // Unhandled tag - save for later storage - //kdDebug() << "Saving unhandled tag " << element.tagName() << endl; - Custom c; - c.key = TQCString( "X-TDE-KolabUnhandled-" ) + element.tagName().latin1(); - c.value = element.text(); - mCustomList.append( c ); - } - } - // We handled this - return true; -} - -bool Incidence::saveAttributes( TQDomElement& element ) const -{ - // Save the base class elements - KolabBase::saveAttributes( element ); - - if ( mFloatingStatus == HasTime ) - writeString( element, "start-date", dateTimeToString( startDate() ) ); - else - writeString( element, "start-date", dateToString( startDate().date() ) ); - writeString( element, "summary", summary() ); - writeString( element, "location", location() ); - saveEmailAttribute( element, organizer(), "organizer" ); - if ( !mRecurrence.cycle.isEmpty() ) - saveRecurrence( element ); - saveAttendees( element ); - saveAttachments( element ); - if ( mHasAlarm ) { - // Alarms should be minutes before. Libkcal uses event time + alarm time - int alarmTime = tqRound( -alarm() ); - writeString( element, "alarm", TQString::number( alarmTime ) ); - } - saveAlarms( element ); - writeString( element, "x-kde-internaluid", internalUID() ); - saveCustomAttributes( element ); - return true; -} - -void Incidence::saveCustomAttributes( TQDomElement& element ) const -{ - TQValueList<Custom>::ConstIterator it = mCustomList.begin(); - for ( ; it != mCustomList.end(); ++it ) { - TQString key = (*it).key; - Q_ASSERT( !key.isEmpty() ); - if ( key.startsWith( "X-TDE-KolabUnhandled-" ) ) { - key = key.mid( strlen( "X-TDE-KolabUnhandled-" ) ); - writeString( element, key, (*it).value ); - } else { - // Let's use attributes so that other tag-preserving-code doesn't need sub-elements - TQDomElement e = element.ownerDocument().createElement( "x-custom" ); - element.appendChild( e ); - e.setAttribute( "key", key ); - e.setAttribute( "value", (*it).value ); - } - } -} - -void Incidence::loadCustomAttributes( TQDomElement& element ) -{ - Custom custom; - custom.key = element.attribute( "key" ).latin1(); - custom.value = element.attribute( "value" ); - mCustomList.append( custom ); -} - -static KCal::Attendee::PartStat attendeeStringToStatus( const TQString& s ) -{ - if ( s == "none" ) - return KCal::Attendee::NeedsAction; - if ( s == "tentative" ) - return KCal::Attendee::Tentative; - if ( s == "accepted" ) - return KCal::Attendee::Accepted; - if ( s == "declined" ) - return KCal::Attendee::Declined; - if ( s == "delegated" ) - return KCal::Attendee::Delegated; - - // Default: - return KCal::Attendee::None; -} - -static TQString attendeeStatusToString( KCal::Attendee::PartStat status ) -{ - switch( status ) { - case KCal::Attendee::NeedsAction: - return "none"; - case KCal::Attendee::Accepted: - return "accepted"; - case KCal::Attendee::Declined: - return "declined"; - case KCal::Attendee::Tentative: - return "tentative"; - case KCal::Attendee::Delegated: - return "delegated"; - case KCal::Attendee::Completed: - case KCal::Attendee::InProcess: - // These don't have any meaning in the Kolab format, so just use: - return "accepted"; - } - - // Default for the case that there are more added later: - return "accepted"; -} - -static KCal::Attendee::Role attendeeStringToRole( const TQString& s ) -{ - if ( s == "optional" ) - return KCal::Attendee::OptParticipant; - if ( s == "resource" ) - return KCal::Attendee::NonParticipant; - return KCal::Attendee::ReqParticipant; -} - -static TQString attendeeRoleToString( KCal::Attendee::Role role ) -{ - switch( role ) { - case KCal::Attendee::ReqParticipant: - return "required"; - case KCal::Attendee::OptParticipant: - return "optional"; - case KCal::Attendee::Chair: - // We don't have the notion of chair, so use - return "required"; - case KCal::Attendee::NonParticipant: - // In Kolab, a non-participant is a resource - return "resource"; - } - - // Default for the case that there are more added later: - return "required"; -} - -static const char *s_weekDayName[] = -{ - "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" -}; - -static const char *s_monthName[] = -{ - "january", "february", "march", "april", "may", "june", "july", - "august", "september", "october", "november", "december" -}; - -void Incidence::setRecurrence( KCal::Recurrence* recur ) -{ - mRecurrence.interval = recur->frequency(); - switch ( recur->recurrenceType() ) { - case KCal::Recurrence::rMinutely: // Not handled by the kolab XML - mRecurrence.cycle = "minutely"; - break; - case KCal::Recurrence::rHourly: // Not handled by the kolab XML - mRecurrence.cycle = "hourly"; - break; - case KCal::Recurrence::rDaily: - mRecurrence.cycle = "daily"; - break; - case KCal::Recurrence::rWeekly: // every X weeks - mRecurrence.cycle = "weekly"; - { - TQBitArray arr = recur->days(); - for ( uint idx = 0 ; idx < 7 ; ++idx ) - if ( arr.testBit( idx ) ) - mRecurrence.days.append( s_weekDayName[idx] ); - } - break; - case KCal::Recurrence::rMonthlyPos: { - mRecurrence.cycle = "monthly"; - mRecurrence.type = "weekday"; - TQValueList<KCal::RecurrenceRule::WDayPos> monthPositions = recur->monthPositions(); - if ( !monthPositions.isEmpty() ) { - KCal::RecurrenceRule::WDayPos monthPos = monthPositions.first(); - // TODO: Handle multiple days in the same week - mRecurrence.dayNumber = TQString::number( monthPos.pos() ); - mRecurrence.days.append( s_weekDayName[ monthPos.day()-1 ] ); - // Not (properly) handled(?): monthPos.negative (nth days before end of month) - } - break; - } - case KCal::Recurrence::rMonthlyDay: { - mRecurrence.cycle = "monthly"; - mRecurrence.type = "daynumber"; - TQValueList<int> monthDays = recur->monthDays(); - // ####### Kolab XML limitation: only the first month day is used - if ( !monthDays.isEmpty() ) - mRecurrence.dayNumber = TQString::number( monthDays.first() ); - break; - } - case KCal::Recurrence::rYearlyMonth: // (day n of Month Y) - { - mRecurrence.cycle = "yearly"; - mRecurrence.type = "monthday"; - TQValueList<int> rmd = recur->yearDates(); - int day = !rmd.isEmpty() ? rmd.first() : recur->startDate().day(); - mRecurrence.dayNumber = TQString::number( day ); - TQValueList<int> months = recur->yearMonths(); - if ( !months.isEmpty() ) - mRecurrence.month = s_monthName[ months.first() - 1 ]; // #### Kolab XML limitation: only one month specified - break; - } - case KCal::Recurrence::rYearlyDay: // YearlyDay (day N of the year). Not supported by Outlook - mRecurrence.cycle = "yearly"; - mRecurrence.type = "yearday"; - mRecurrence.dayNumber = TQString::number( recur->yearDays().first() ); - break; - case KCal::Recurrence::rYearlyPos: // (weekday X of week N of month Y) - mRecurrence.cycle = "yearly"; - mRecurrence.type = "weekday"; - TQValueList<int> months = recur->yearMonths(); - if ( !months.isEmpty() ) - mRecurrence.month = s_monthName[ months.first() - 1 ]; // #### Kolab XML limitation: only one month specified - TQValueList<KCal::RecurrenceRule::WDayPos> monthPositions = recur->yearPositions(); - if ( !monthPositions.isEmpty() ) { - KCal::RecurrenceRule::WDayPos monthPos = monthPositions.first(); - // TODO: Handle multiple days in the same week - mRecurrence.dayNumber = TQString::number( monthPos.pos() ); - mRecurrence.days.append( s_weekDayName[ monthPos.day()-1 ] ); - - //mRecurrence.dayNumber = TQString::number( *recur->yearNums().getFirst() ); - // Not handled: monthPos.negative (nth days before end of month) - } - break; - } - int howMany = recur->duration(); - if ( howMany > 0 ) { - mRecurrence.rangeType = "number"; - mRecurrence.range = TQString::number( howMany ); - } else if ( howMany == 0 ) { - mRecurrence.rangeType = "date"; - mRecurrence.range = dateToString( recur->endDate() ); - } else { - mRecurrence.rangeType = "none"; - } -} - -void Incidence::setFields( const KCal::Incidence* incidence ) -{ - KolabBase::setFields( incidence ); - - if ( incidence->doesFloat() ) { - // This is a floating event. Don't timezone move this one - mFloatingStatus = AllDay; - setStartDate( incidence->dtStart().date() ); - } else { - mFloatingStatus = HasTime; - setStartDate( localToUTC( incidence->dtStart() ) ); - } - - setSummary( incidence->summary() ); - setLocation( incidence->location() ); - - // Alarm - mHasAlarm = false; // Will be set to true, if we actually have one - if ( incidence->isAlarmEnabled() ) { - const KCal::Alarm::List& alarms = incidence->alarms(); - if ( !alarms.isEmpty() ) { - const KCal::Alarm* alarm = alarms.first(); - if ( alarm->hasStartOffset() ) { - int dur = alarm->startOffset().asSeconds(); - setAlarm( (float)dur / 60.0 ); - } - } - } - - Email org( incidence->organizer().name(), incidence->organizer().email() ); - setOrganizer( org ); - - // Attendees: - KCal::Attendee::List attendees = incidence->attendees(); - KCal::Attendee::List::ConstIterator it; - for ( it = attendees.begin(); it != attendees.end(); ++it ) { - KCal::Attendee* kcalAttendee = *it; - Attendee attendee; - - attendee.displayName = kcalAttendee->name(); - attendee.smtpAddress = kcalAttendee->email(); - attendee.status = attendeeStatusToString( kcalAttendee->status() ); - attendee.requestResponse = kcalAttendee->RSVP(); - // TODO: KCal::Attendee::mFlag is not accessible - // attendee.invitationSent = kcalAttendee->mFlag; - // DF: Hmm? mFlag is set to true and never used at all.... Did you mean another field? - attendee.role = attendeeRoleToString( kcalAttendee->role() ); - attendee.delegate = kcalAttendee->delegate(); - attendee.delegator = kcalAttendee->delegator(); - - addAttendee( attendee ); - } - - mAttachments.clear(); - - // Attachments - KCal::Attachment::List attachments = incidence->attachments(); - KCal::Attachment::List::ConstIterator it2; - for ( it2 = attachments.begin(); it2 != attachments.end(); ++it2 ) { - KCal::Attachment *a = *it2; - mAttachments.push_back( a ); - } - - mAlarms.clear(); - - // Alarms - const KCal::Alarm::List alarms = incidence->alarms(); - for ( KCal::Alarm::List::ConstIterator it = alarms.begin(); it != alarms.end(); ++it ) { - mAlarms.push_back( *it ); - } - - if ( incidence->doesRecur() ) { - setRecurrence( incidence->recurrence() ); - mRecurrence.exclusions = incidence->recurrence()->exDates(); - } - - // Handle the scheduling ID - if ( incidence->schedulingID() == incidence->uid() ) { - // There is no scheduling ID - setInternalUID( TQString() ); - } else { - // We've internally been using a different uid, so save that as the - // temporary (internal) uid and restore the original uid, the one that - // is used in the folder and the outside world - setUid( incidence->schedulingID() ); - setInternalUID( incidence->uid() ); - } - - if ( incidence->pilotId() != 0 ) - setPilotSyncId( incidence->pilotId() ); - - setPilotSyncStatus( incidence->syncStatus() ); - - // Unhandled tags and other custom properties (see libkcal/customproperties.h) - const TQMap<TQCString, TQString> map = incidence->customProperties(); - TQMap<TQCString, TQString>::ConstIterator cit = map.begin(); - for ( ; cit != map.end() ; ++cit ) { - Custom c; - c.key = cit.key(); - c.value = cit.data(); - mCustomList.append( c ); - } -} - -static TQBitArray daysListToBitArray( const TQStringList& days ) -{ - TQBitArray arr( 7 ); - arr.fill( false ); - for( TQStringList::ConstIterator it = days.begin(); it != days.end(); ++it ) { - for ( uint i = 0; i < 7 ; ++i ) - if ( *it == s_weekDayName[i] ) - arr.setBit( i, true ); - } - return arr; -} - - -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 && mAlarms.isEmpty() ) { - KCal::Alarm* alarm = incidence->newAlarm(); - alarm->setStartOffset( tqRound( mAlarm * 60.0 ) ); - alarm->setEnabled( true ); - alarm->setType( KCal::Alarm::Display ); - } else if ( !mAlarms.isEmpty() ) { - for ( KCal::Alarm::List::ConstIterator it = mAlarms.constBegin(); it != mAlarms.constEnd(); ++it ) { - KCal::Alarm *alarm = *it; - alarm->setParent( incidence ); - incidence->addAlarm( alarm ); - } - } - - if ( organizer().displayName.isEmpty() ) - incidence->setOrganizer( organizer().smtpAddress ); - else - incidence->setOrganizer( organizer().displayName + "<" - + organizer().smtpAddress + ">" ); - - incidence->clearAttendees(); - TQValueList<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" ) { - TQBitArray 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() ); - } - if ( hasPilotSyncId() ) - incidence->setPilotId( pilotSyncId() ); - if ( hasPilotSyncStatus() ) - incidence->setSyncStatus( pilotSyncStatus() ); - - for( TQValueList<Custom>::ConstIterator it = mCustomList.constBegin(); it != mCustomList.constEnd(); ++it ) { - incidence->setNonKDECustomProperty( (*it).key, (*it).value ); - } - -} - -void Incidence::loadAttachments() -{ - TQStringList attachments; - if ( mResource->kmailListAttachments( attachments, mSubResource, mSernum ) ) { - for ( TQStringList::ConstIterator it = attachments.constBegin(); it != attachments.constEnd(); ++it ) { - TQByteArray data; - KURL url; - if ( mResource->kmailGetAttachment( url, mSubResource, mSernum, *it ) && !url.isEmpty() ) { - TQFile f( url.path() ); - if ( f.open( IO_ReadOnly ) ) { - data = f.readAll(); - TQString mimeType; - if ( !mResource->kmailAttachmentMimetype( mimeType, mSubResource, mSernum, *it ) ) - mimeType = "application/octet-stream"; - KCal::Attachment *a = new KCal::Attachment( KCodecs::base64Encode( data ).data(), mimeType ); - a->setLabel( *it ); - mAttachments.append( a ); - f.close(); - } - f.remove(); - } - } - } -} - -TQString Incidence::productID() const -{ - return TQString( "KOrganizer %1, Kolab resource" ).arg( korgVersion ); -} - -// Unhandled KCal::Incidence fields: -// revision, status (unused), priority (done in tasks), attendee.uid, -// mComments, mReadOnly - |