diff options
Diffstat (limited to 'kresources/kolab/kcal')
-rw-r--r-- | kresources/kolab/kcal/CMakeLists.txt | 57 | ||||
-rw-r--r-- | kresources/kolab/kcal/Makefile.am | 27 | ||||
-rw-r--r-- | kresources/kolab/kcal/event.cpp | 223 | ||||
-rw-r--r-- | kresources/kolab/kcal/event.h | 102 | ||||
-rw-r--r-- | kresources/kolab/kcal/incidence.cpp | 1039 | ||||
-rw-r--r-- | kresources/kolab/kcal/incidence.h | 175 | ||||
-rw-r--r-- | kresources/kolab/kcal/journal.cpp | 184 | ||||
-rw-r--r-- | kresources/kolab/kcal/journal.h | 103 | ||||
-rw-r--r-- | kresources/kolab/kcal/kolab.desktop | 52 | ||||
-rw-r--r-- | kresources/kolab/kcal/resourcekolab.cpp | 1342 | ||||
-rw-r--r-- | kresources/kolab/kcal/resourcekolab.h | 284 | ||||
-rw-r--r-- | kresources/kolab/kcal/resourcekolab_plugin.cpp | 49 | ||||
-rw-r--r-- | kresources/kolab/kcal/task.cpp | 461 | ||||
-rw-r--r-- | kresources/kolab/kcal/task.h | 143 |
14 files changed, 0 insertions, 4241 deletions
diff --git a/kresources/kolab/kcal/CMakeLists.txt b/kresources/kolab/kcal/CMakeLists.txt deleted file mode 100644 index 70750ed19..000000000 --- a/kresources/kolab/kcal/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../shared - ${CMAKE_CURRENT_SOURCE_DIR}/../kcal - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/libtdepim - ${TDE_INCLUDE_DIR} - ${TQT_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### other data ################################ - -install( - FILES kolab.desktop - DESTINATION ${SERVICES_INSTALL_DIR}/kresources/kcal ) - -install( - FILES ${CMAKE_CURRENT_SOURCE_DIR}/../uninstall.desktop - DESTINATION ${SERVICES_INSTALL_DIR}/kresources/kcal - RENAME imap.desktop) - - -##### kcal_kolab (module) ####################### - -tde_add_kpart( kcal_kolab AUTOMOC - SOURCES - resourcekolab_plugin.cpp - LINK kcalkolab-shared - DESTINATION ${PLUGIN_INSTALL_DIR} -) - - -##### kcalkolab (shared) ######################## - -tde_add_library( kcalkolab SHARED AUTOMOC - SOURCES - incidence.cpp event.cpp task.cpp journal.cpp resourcekolab.cpp - VERSION 0.0.0 - LINK resourcekolabshared-static kgroupwarebase-shared - DESTINATION ${LIB_INSTALL_DIR} -) diff --git a/kresources/kolab/kcal/Makefile.am b/kresources/kolab/kcal/Makefile.am deleted file mode 100644 index 4b0193ba5..000000000 --- a/kresources/kolab/kcal/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -METASOURCES = AUTO - -INCLUDES = -I$(top_srcdir)/kresources/kolab/shared -I$(top_srcdir) \ - -I$(top_builddir)/libtdepim $(all_includes) - -# The kolab wizard links to this library too -lib_LTLIBRARIES = libkcalkolab.la - -libkcalkolab_la_SOURCES = incidence.cpp event.cpp task.cpp journal.cpp resourcekolab.cpp -libkcalkolab_la_LDFLAGS = $(all_libraries) -no-undefined -libkcalkolab_la_LIBADD = $(top_builddir)/libkcal/libkcal.la \ - $(top_builddir)/kresources/kolab/shared/libresourcekolabshared.la \ - -lkresources - -kde_module_LTLIBRARIES = kcal_kolab.la - -kcal_kolab_la_SOURCES = resourcekolab_plugin.cpp -kcal_kolab_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined -kcal_kolab_la_LIBADD = libkcalkolab.la - -servicedir = $(kde_servicesdir)/kresources/kcal -service_DATA = kolab.desktop - -install-data-local: $(srcdir)/../uninstall.desktop - $(mkinstalldirs) $(DESTDIR)$(servicedir) - $(INSTALL_DATA) $(srcdir)/../uninstall.desktop $(DESTDIR)$(servicedir)/imap.desktop - diff --git a/kresources/kolab/kcal/event.cpp b/kresources/kolab/kcal/event.cpp deleted file mode 100644 index c15c567d8..000000000 --- a/kresources/kolab/kcal/event.cpp +++ /dev/null @@ -1,223 +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 "event.h" - -#include <libkcal/event.h> -#include <kdebug.h> - -using namespace Kolab; - - -KCal::Event* Event::xmlToEvent( const TQString& xml, const TQString& tz, KCal::ResourceKolab* res, - const TQString& subResource, TQ_UINT32 sernum ) -{ - Event event( res, subResource, sernum, tz ); - event.load( xml ); - KCal::Event* kcalEvent = new KCal::Event(); - event.saveTo( kcalEvent ); - return kcalEvent; -} - -TQString Event::eventToXML( KCal::Event* kcalEvent, const TQString& tz ) -{ - Event event( 0, TQString(), 0, tz, kcalEvent ); - return event.saveXML(); -} - -Event::Event( KCal::ResourceKolab *res, const TQString &subResource, TQ_UINT32 sernum, - const TQString& tz, KCal::Event* event ) - : Incidence( res, subResource, sernum, tz ), - mShowTimeAs( KCal::Event::Opaque ), mHasEndDate( false ) -{ - if ( event ) - setFields( event ); -} - -Event::~Event() -{ -} - -void Event::setTransparency( KCal::Event::Transparency transparency ) -{ - mShowTimeAs = transparency; -} - -KCal::Event::Transparency Event::transparency() const -{ - return mShowTimeAs; -} - -void Event::setEndDate( const TQDateTime& date ) -{ - mEndDate = date; - mHasEndDate = true; - if ( mFloatingStatus == AllDay ) - kdDebug() << "ERROR: Time on end date but no time on the event\n"; - mFloatingStatus = HasTime; -} - -void Event::setEndDate( const TQDate& date ) -{ - mEndDate = date; - mHasEndDate = true; - if ( mFloatingStatus == HasTime ) - kdDebug() << "ERROR: No time on end date but time on the event\n"; - mFloatingStatus = AllDay; -} - -void Event::setEndDate( const TQString& endDate ) -{ - if ( endDate.length() > 10 ) - // This is a date + time - setEndDate( stringToDateTime( endDate ) ); - else - // This is only a date - setEndDate( stringToDate( endDate ) ); -} - -TQDateTime Event::endDate() const -{ - return mEndDate; -} - -bool Event::loadAttribute( TQDomElement& element ) -{ - // This method doesn't handle the color-label tag yet - TQString tagName = element.tagName(); - - if ( tagName == "show-time-as" ) { - // TODO: Support tentative and outofoffice - if ( element.text() == "free" ) - setTransparency( KCal::Event::Transparent ); - else - setTransparency( KCal::Event::Opaque ); - } else if ( tagName == "end-date" ) - setEndDate( element.text() ); - else - return Incidence::loadAttribute( element ); - - // We handled this - return true; -} - -bool Event::saveAttributes( TQDomElement& element ) const -{ - // Save the base class elements - Incidence::saveAttributes( element ); - - // TODO: Support tentative and outofoffice - if ( transparency() == KCal::Event::Transparent ) - writeString( element, "show-time-as", "free" ); - else - writeString( element, "show-time-as", "busy" ); - if ( mHasEndDate ) { - if ( mFloatingStatus == HasTime ) - writeString( element, "end-date", dateTimeToString( endDate() ) ); - else - writeString( element, "end-date", dateToString( endDate().date() ) ); - } - - return true; -} - - -bool Event::loadXML( const TQDomDocument& document ) -{ - TQDomElement top = document.documentElement(); - - if ( top.tagName() != "event" ) { - tqWarning( "XML error: Top tag was %s instead of the expected event", - top.tagName().ascii() ); - return false; - } - - for ( TQDomNode n = top.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - loadAttribute( e ); - } else - kdDebug() << "Node is not a comment or an element???" << endl; - } - - loadAttachments(); - return true; -} - -TQString Event::saveXML() const -{ - TQDomDocument document = domTree(); - TQDomElement element = document.createElement( "event" ); - element.setAttribute( "version", "1.0" ); - saveAttributes( element ); - document.appendChild( element ); - return document.toString(); -} - -void Event::setFields( const KCal::Event* event ) -{ - Incidence::setFields( event ); - - // note: if hasEndDate() is false and hasDuration() is true - // dtEnd() returns start+duration - if ( event->hasEndDate() || event->hasDuration() ) { - if ( event->doesFloat() ) { - // This is a floating event. Don't timezone move this one - mFloatingStatus = AllDay; - setEndDate( event->dtEnd().date() ); - } else { - mFloatingStatus = HasTime; - setEndDate( localToUTC( event->dtEnd() ) ); - } - } else { - mHasEndDate = false; - } - setTransparency( event->transparency() ); -} - -void Event::saveTo( KCal::Event* event ) -{ - Incidence::saveTo( event ); - - event->setHasEndDate( mHasEndDate ); - if ( mHasEndDate ) { - if ( mFloatingStatus == AllDay ) - // This is a floating event. Don't timezone move this one - event->setDtEnd( endDate() ); - else - event->setDtEnd( utcToLocal( endDate() ) ); - } - event->setTransparency( transparency() ); -} diff --git a/kresources/kolab/kcal/event.h b/kresources/kolab/kcal/event.h deleted file mode 100644 index 57aa3358f..000000000 --- a/kresources/kolab/kcal/event.h +++ /dev/null @@ -1,102 +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. -*/ - -#ifndef KOLAB_EVENT_H -#define KOLAB_EVENT_H - -#include "incidence.h" - -#include <libkcal/event.h> - -class TQDomElement; - - -namespace Kolab { - -/** - * This class represents an event, and knows how to load/save it - * from/to XML, and from/to a KCal::Event. - * The instances of this class are temporary, only used to convert - * one to the other. - */ -class Event : public Incidence { -public: - /// Use this to parse an xml string to a event entry - /// The caller is responsible for deleting the returned event - static KCal::Event* xmlToEvent( const TQString& xml, const TQString& tz, KCal::ResourceKolab* res = 0, - const TQString& subResource = TQString(), TQ_UINT32 sernum = 0 ); - - /// Use this to get an xml string describing this event entry - static TQString eventToXML( KCal::Event*, const TQString& tz ); - - /// Create a event object and - explicit Event( KCal::ResourceKolab *res, const TQString &subResource, TQ_UINT32 sernum, - const TQString& tz, KCal::Event* event = 0 ); - virtual ~Event(); - - void saveTo( KCal::Event* event ); - - virtual TQString type() const { return "Event"; } - - virtual void setTransparency( KCal::Event::Transparency transparency ); - virtual KCal::Event::Transparency transparency() const; - - virtual void setEndDate( const TQDateTime& date ); - virtual void setEndDate( const TQDate& date ); - virtual void setEndDate( const TQString& date ); - virtual TQDateTime endDate() const; - - // Load the attributes of this class - virtual bool loadAttribute( TQDomElement& ); - - // Save the attributes of this class - virtual bool saveAttributes( TQDomElement& ) const; - - // Load this event by reading the XML file - virtual bool loadXML( const TQDomDocument& xml ); - - // Serialize this event to an XML string - virtual TQString saveXML() const; - -protected: - // Read all known fields from this ical incidence - void setFields( const KCal::Event* ); - - KCal::Event::Transparency mShowTimeAs; - TQDateTime mEndDate; - bool mHasEndDate; -}; - -} - -#endif // KOLAB_EVENT_H 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 - diff --git a/kresources/kolab/kcal/incidence.h b/kresources/kolab/kcal/incidence.h deleted file mode 100644 index 926ec1e4f..000000000 --- a/kresources/kolab/kcal/incidence.h +++ /dev/null @@ -1,175 +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. -*/ - -#ifndef KOLAB_INCIDENCE_H -#define KOLAB_INCIDENCE_H - -#include <kolabbase.h> - -class TQDomElement; - -namespace KCal { - class Incidence; - class Recurrence; - class Alarm; - class Attachment; - class ResourceKolab; -} - -namespace Kolab { - -/** - * This abstract class represents an incidence which has the shared - * fields, of events and tasks and knows how to load/save these - * from/to XML, and from/to a KCal::Incidence. - */ -class Incidence : public KolabBase { -public: - struct Recurrence { - TQString cycle; - TQString type; - int interval; - TQStringList days; // list of days-of-the-week - TQString dayNumber; - TQString month; - TQString rangeType; - TQString range; // date or number or nothing - TQValueList<TQDate> exclusions; - }; - - struct Attendee : Email { - Attendee() : requestResponse( true ), invitationSent( false ) {} - TQString status; - bool requestResponse; - bool invitationSent; - TQString role; - TQString delegate; - TQString delegator; - }; - - explicit Incidence( KCal::ResourceKolab *res, const TQString &subResource, TQ_UINT32 sernum, - const TQString& tz ); - virtual ~Incidence(); - - void saveTo( KCal::Incidence* incidence ); - - virtual void setSummary( const TQString& summary ); - virtual TQString summary() const; - - virtual void setLocation( const TQString& location ); - virtual TQString location() const; - - virtual void setOrganizer( const Email& organizer ); - virtual Email organizer() const; - - virtual void setStartDate( const TQDateTime& startDate ); - virtual void setStartDate( const TQDate& startDate ); - virtual void setStartDate( const TQString& startDate ); - virtual TQDateTime startDate() const; - - virtual void setAlarm( float alarm ); - virtual float alarm() const; - - virtual void setRecurrence( KCal::Recurrence* recur ); - virtual Recurrence recurrence() const; - - virtual void addAttendee( const Attendee& attendee ); - TQValueList<Attendee>& attendees(); - const TQValueList<Attendee>& attendees() const; - - /** - * The internal uid is used as the uid inside KOrganizer whenever - * two or more events with the same uid appear, which KOrganizer - * can't handle. To avoid keep that interal uid from changing all the - * time, it is persisted in the XML between a save and the next load. - */ - void setInternalUID( const TQString& iuid ); - TQString internalUID() const; - - // Load the attributes of this class - virtual bool loadAttribute( TQDomElement& ); - - // Save the attributes of this class - virtual bool saveAttributes( TQDomElement& ) const; - -protected: - enum FloatingStatus { Unset, AllDay, HasTime }; - - // Read all known fields from this ical incidence - void setFields( const KCal::Incidence* ); - - bool loadAttendeeAttribute( TQDomElement&, Attendee& ); - void saveAttendeeAttribute( TQDomElement& element, - const Attendee& attendee ) const; - void saveAttendees( TQDomElement& element ) const; - void saveAttachments( TQDomElement& element ) const; - - void loadAlarms( const TQDomElement& element ); - void saveAlarms( TQDomElement& element ) const; - - void loadRecurrence( const TQDomElement& element ); - void saveRecurrence( TQDomElement& element ) const; - void saveCustomAttributes( TQDomElement& element ) const; - void loadCustomAttributes( TQDomElement& element ); - - void loadAttachments(); - - TQString productID() const; - - TQString mSummary; - TQString mLocation; - Email mOrganizer; - TQDateTime mStartDate; - FloatingStatus mFloatingStatus; - float mAlarm; - bool mHasAlarm; - Recurrence mRecurrence; - TQValueList<Attendee> mAttendees; - TQValueList<KCal::Alarm*> mAlarms; - TQValueList<KCal::Attachment*> mAttachments; - TQString mInternalUID; - - struct Custom { - TQCString key; - TQString value; - }; - TQValueList<Custom> mCustomList; - - KCal::ResourceKolab *mResource; - TQString mSubResource; - TQ_UINT32 mSernum; -}; - -} - -#endif // KOLAB_INCIDENCE_H diff --git a/kresources/kolab/kcal/journal.cpp b/kresources/kolab/kcal/journal.cpp deleted file mode 100644 index acfc4e71d..000000000 --- a/kresources/kolab/kcal/journal.cpp +++ /dev/null @@ -1,184 +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 "journal.h" - -#include <libkcal/journal.h> -#include <korganizer/version.h> -#include <kdebug.h> - -using namespace Kolab; - - -KCal::Journal* Journal::xmlToJournal( const TQString& xml, const TQString& tz ) -{ - Journal journal( tz ); - journal.load( xml ); - KCal::Journal* kcalJournal = new KCal::Journal(); - journal.saveTo( kcalJournal ); - return kcalJournal; -} - -TQString Journal::journalToXML( KCal::Journal* kcalJournal, const TQString& tz ) -{ - Journal journal( tz, kcalJournal ); - return journal.saveXML(); -} - -Journal::Journal( const TQString& tz, KCal::Journal* journal ) - : KolabBase( tz ) -{ - if ( journal ) - setFields( journal ); -} - -Journal::~Journal() -{ -} - -void Journal::setSummary( const TQString& summary ) -{ - mSummary = summary; -} - -TQString Journal::summary() const -{ - return mSummary; -} - -void Journal::setStartDate( const TQDateTime& startDate ) -{ - mStartDate = startDate; -} - -TQDateTime Journal::startDate() const -{ - return mStartDate; -} - -void Journal::setEndDate( const TQDateTime& endDate ) -{ - mEndDate = endDate; -} - -TQDateTime Journal::endDate() const -{ - return mEndDate; -} - -bool Journal::loadAttribute( TQDomElement& element ) -{ - TQString tagName = element.tagName(); - - if ( tagName == "summary" ) - setSummary( element.text() ); - else if ( tagName == "start-date" ) - setStartDate( stringToDateTime( element.text() ) ); - else - // Not handled here - return KolabBase::loadAttribute( element ); - - // We handled this - return true; -} - -bool Journal::saveAttributes( TQDomElement& element ) const -{ - // Save the base class elements - KolabBase::saveAttributes( element ); - - writeString( element, "summary", summary() ); - writeString( element, "start-date", dateTimeToString( startDate() ) ); - - return true; -} - - -bool Journal::loadXML( const TQDomDocument& document ) -{ - TQDomElement top = document.documentElement(); - - if ( top.tagName() != "journal" ) { - tqWarning( "XML error: Top tag was %s instead of the expected Journal", - top.tagName().ascii() ); - return false; - } - - for ( TQDomNode n = top.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - if ( !loadAttribute( e ) ) { - // Unhandled tag - save for later storage - //tqDebug( "Unhandled tag: %s", e.toCString().data() ); - } - } else - tqDebug( "Node is not a comment or an element???" ); - } - - return true; -} - -TQString Journal::saveXML() const -{ - TQDomDocument document = domTree(); - TQDomElement element = document.createElement( "journal" ); - element.setAttribute( "version", "1.0" ); - saveAttributes( element ); - document.appendChild( element ); - return document.toString(); -} - -void Journal::saveTo( KCal::Journal* journal ) -{ - KolabBase::saveTo( journal ); - - journal->setSummary( summary() ); - journal->setDtStart( utcToLocal( startDate() ) ); -} - -void Journal::setFields( const KCal::Journal* journal ) -{ - // Set baseclass fields - KolabBase::setFields( journal ); - - // Set our own fields - setSummary( journal->summary() ); - setStartDate( localToUTC( journal->dtStart() ) ); -} - -TQString Journal::productID() const -{ - return TQString( "KOrganizer " ) + korgVersion + ", Kolab resource"; -} diff --git a/kresources/kolab/kcal/journal.h b/kresources/kolab/kcal/journal.h deleted file mode 100644 index cd583c6ca..000000000 --- a/kresources/kolab/kcal/journal.h +++ /dev/null @@ -1,103 +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. -*/ - -#ifndef KOLAB_JOURNAL_H -#define KOLAB_JOURNAL_H - -#include <kolabbase.h> - -class TQDomElement; - -namespace KCal { - class Journal; -} - -namespace Kolab { - -/** - * This class represents a journal entry, and knows how to load/save it - * from/to XML, and from/to a KCal::Journal. - * The instances of this class are temporary, only used to convert - * one to the other. - */ -class Journal : public KolabBase { -public: - /// Use this to parse an xml string to a journal entry - /// The caller is responsible for deleting the returned journal - static KCal::Journal* xmlToJournal( const TQString& xml, const TQString& tz ); - - /// Use this to get an xml string describing this journal entry - static TQString journalToXML( KCal::Journal*, const TQString& tz ); - - explicit Journal( const TQString& tz, KCal::Journal* journal = 0 ); - virtual ~Journal(); - - virtual TQString type() const { return "Journal"; } - - void saveTo( KCal::Journal* journal ); - - virtual void setSummary( const TQString& summary ); - virtual TQString summary() const; - - virtual void setStartDate( const TQDateTime& startDate ); - virtual TQDateTime startDate() const; - - virtual void setEndDate( const TQDateTime& endDate ); - virtual TQDateTime endDate() const; - - // Load the attributes of this class - virtual bool loadAttribute( TQDomElement& ); - - // Save the attributes of this class - virtual bool saveAttributes( TQDomElement& ) const; - - // Load this journal by reading the XML file - virtual bool loadXML( const TQDomDocument& xml ); - - // Serialize this journal to an XML string - virtual TQString saveXML() const; - -protected: - // Read all known fields from this ical journal - void setFields( const KCal::Journal* ); - - TQString productID() const; - - TQString mSummary; - TQDateTime mStartDate; - TQDateTime mEndDate; -}; - -} - -#endif // KOLAB_JOURNAL_H diff --git a/kresources/kolab/kcal/kolab.desktop b/kresources/kolab/kcal/kolab.desktop deleted file mode 100644 index 40bcacb00..000000000 --- a/kresources/kolab/kcal/kolab.desktop +++ /dev/null @@ -1,52 +0,0 @@ -[Desktop Entry] -Name=Calendar on IMAP Server via KMail -Name[af]=Kalender op IMAP bediener via KMail -Name[bg]=Календар на Ñървър IMAP през KMail -Name[br]=Deiziadur en ur servijer IMAP gant KMail -Name[ca]=Calendari sobre servidor IMAP mitjançant KMail -Name[cs]=Kalendář na IMAP serveru pÅ™es KMail -Name[da]=Kalender pÃ¥ IMAP-server via KMail -Name[de]=Kalender auf einem IMAP-Server via KMail -Name[el]=ΗμεÏολόγιο σε εξυπηÏετητή IMAP μÎσω του KMail -Name[es]=Calendario en servidor IMAP por medio de KMail -Name[et]=Kalender IMAP-serveris (KMaili vahendusel) -Name[eu]=Egutegia IMAP zerbitzarian KMail-en bidez -Name[fa]=تقویم روی کارساز IMAP از طریق KMail -Name[fi]=Kalenteri IMAP-palvelimella KMailin avulla -Name[fr]=Agenda sur serveur IMAP (via KMail) -Name[fy]=Aginda op IMAP-tsjinner fia KMail -Name[ga]=Féilire ar Fhreastalaà IMAP via KMail -Name[gl]=Calendario no servidor IMAP mediante KMail -Name[hu]=IMAP-kiszolgálón tárolt naptár a KMailen keresztül -Name[is]=Dagatal á IMAP þjóni gegnum KMail -Name[it]=Calendario su server IMAP via KMail -Name[ja]=KMail 経由 IMAP サーãƒã®ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼ -Name[kk]=KMail арқылы IMAP Ñерверіндегі күнтізбе -Name[km]=ប្រážáž·áž‘ិន​លើ​ម៉ាស៊ីន​បម្រើ IMAP ážáž¶áž˜â€‹ážšáž™áŸˆ KMail -Name[lt]=Kalendorius IMAP serveryje per KMail -Name[mk]=Календар на IMAP-Ñервер преку КПошта -Name[ms]=Kalendar pada pelayan IMAP melalui KMail -Name[nb]=Kalender pÃ¥ IMAP-tjener via KMail -Name[nds]=Kalenner op IMAP-Server över KMail -Name[ne]=केडीई मेल मारà¥à¤«à¤¤ IMAP सरà¥à¤à¤°à¤®à¤¾ कà¥à¤¯à¤¾à¤²à¥‡à¤¨à¥à¤¡à¤° -Name[nl]=Agenda op IMAP-server via KMail -Name[nn]=Kalender pÃ¥ IMAP-tenar via KMail -Name[pl]=Kalendarz na serwerze IMAP za poÅ›rednictwem KMail -Name[pt]=Calendário em Servidor IMAP via KMail -Name[pt_BR]=Calendário em Servidor IMAP via KMail -Name[ru]=Календарь на Ñервере IMAP через KMail -Name[sk]=Kalendár na IMAP serveri pomocou KMail -Name[sl]=Koledar na strežniku IMAP preko KMaila -Name[sr]=Календар на IMAP Ñерверу преко KMail-а -Name[sr@Latn]=Kalendar na IMAP serveru preko KMail-a -Name[sv]=Kalender pÃ¥ IMAP-server via Kmail -Name[ta]=IMAP சேவையக வழியாக கேஅஞà¯à®šà®²à®¿à®²à¯ நாடà¯à®•à®¾à®Ÿà¯à®Ÿà®¿ -Name[tr]=KMail Aracılığı ile IMAP Sunucusunda Takvim -Name[uk]=Календар на Ñервері IMAP через KMail -Name[zh_CN]=通过 KMail 访问 IMAP æœåŠ¡å™¨ä¸Šçš„日历 -Name[zh_TW]=é€éŽ KMail å–å¾— IMAP 伺æœå™¨ä¸Šçš„行事曆 -X-TDE-Library=kcal_kolab -Type=Service -ServiceTypes=KResources/Plugin -X-TDE-ResourceFamily=calendar -X-TDE-ResourceType=imap diff --git a/kresources/kolab/kcal/resourcekolab.cpp b/kresources/kolab/kcal/resourcekolab.cpp deleted file mode 100644 index 44c13fd2b..000000000 --- a/kresources/kolab/kcal/resourcekolab.cpp +++ /dev/null @@ -1,1342 +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> - 2004 Till Adam <till@klaralvdalens-datakonsult.se> - - 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 "resourcekolab.h" -#include "event.h" -#include "task.h" -#include "journal.h" - -#include <kio/observer.h> -#include <kio/uiserver_stub.h> -#include <kapplication.h> -#include <dcopclient.h> -#include <libtdepim/kincidencechooser.h> -#include <kabc/locknull.h> -#include <kmainwindow.h> -#include <klocale.h> -#include <kinputdialog.h> -#include <ktempfile.h> -#include <kmdcodec.h> - -#include <tqfile.h> -#include <tqobject.h> -#include <tqtimer.h> -#include <tqapplication.h> - -#include <assert.h> - -using namespace KCal; -using namespace Kolab; - -static const char* kmailCalendarContentsType = "Calendar"; -static const char* kmailTodoContentsType = "Task"; -static const char* kmailJournalContentsType = "Journal"; -static const char* eventAttachmentMimeType = "application/x-vnd.kolab.event"; -static const char* todoAttachmentMimeType = "application/x-vnd.kolab.task"; -static const char* journalAttachmentMimeType = "application/x-vnd.kolab.journal"; -static const char* incidenceInlineMimeType = "text/calendar"; - - -ResourceKolab::ResourceKolab( const TDEConfig *config ) - : ResourceCalendar( config ), ResourceKolabBase( "ResourceKolab-libkcal" ), - mCalendar( TQString::fromLatin1("UTC") ), mOpen( false ),mResourceChangedTimer( 0, - "mResourceChangedTimer" ), mBatchAddingInProgress( false ) -{ - if ( !config ) { - setResourceName( i18n( "Kolab Server" ) ); - } - setType( "imap" ); - connect( &mResourceChangedTimer, TQT_SIGNAL( timeout() ), - this, TQT_SLOT( slotEmitResourceChanged() ) ); -} - -ResourceKolab::~ResourceKolab() -{ - // The resource is deleted on exit (StdAddressBook's KStaticDeleter), - // and it wasn't closed before that, so close here to save the config. - if ( mOpen ) { - close(); - } -} - -void ResourceKolab::loadSubResourceConfig( TDEConfig& config, - const TQString& name, - const TQString& label, - bool writable, - bool alarmRelevant, - ResourceMap& subResource ) -{ - TDEConfigGroup group( &config, name ); - bool active = group.readBoolEntry( "Active", true ); - subResource.insert( name, Kolab::SubResource( active, writable, - alarmRelevant, label ) ); -} - -bool ResourceKolab::openResource( TDEConfig& config, const char* contentType, - ResourceMap& map ) -{ - // Read the subresource entries from KMail - TQValueList<KMailICalIface::SubResource> subResources; - if ( !kmailSubresources( subResources, contentType ) ) - return false; - map.clear(); - TQValueList<KMailICalIface::SubResource>::ConstIterator it; - for ( it = subResources.begin(); it != subResources.end(); ++it ) - loadSubResourceConfig( config, (*it).location, (*it).label, (*it).writable, - (*it).alarmRelevant, map ); - return true; -} - -bool ResourceKolab::doOpen() -{ - if ( mOpen ) - // Already open - return true; - mOpen = true; - - TDEConfig config( configFile() ); - config.setGroup( "General" ); - mProgressDialogIncidenceLimit = config.readNumEntry("ProgressDialogIncidenceLimit", 200); - - return openResource( config, kmailCalendarContentsType, mEventSubResources ) - && openResource( config, kmailTodoContentsType, mTodoSubResources ) - && openResource( config, kmailJournalContentsType, mJournalSubResources ); -} - -static void writeResourceConfig( TDEConfig& config, ResourceMap& map ) -{ - ResourceMap::ConstIterator it; - for ( it = map.begin(); it != map.end(); ++it ) { - config.setGroup( it.key() ); - config.writeEntry( "Active", it.data().active() ); - } -} - -void ResourceKolab::doClose() -{ - if ( !mOpen ) - // Not open - return; - mOpen = false; - - writeConfig(); -} - -bool ResourceKolab::loadSubResource( const TQString& subResource, - const char* mimetype ) -{ - int count = 0; - if ( !kmailIncidencesCount( count, mimetype, subResource ) ) { - kdError(5650) << "Communication problem in ResourceKolab::load()\n"; - return false; - } - - if ( !count ) - return true; - - const int nbMessages = 200; // read 200 mails at a time (see kabc resource) - - const TQString labelTxt = !strcmp(mimetype, "application/x-vnd.kolab.task") ? i18n( "Loading tasks..." ) - : !strcmp(mimetype, "application/x-vnd.kolab.journal") ? i18n( "Loading journals..." ) - : i18n( "Loading events..." ); - const bool useProgress = tqApp && tqApp->type() != TQApplication::Tty && count > mProgressDialogIncidenceLimit; - if ( useProgress ) - (void)::Observer::self(); // ensure kio_uiserver is running - UIServer_stub uiserver( "kio_uiserver", "UIServer" ); - int progressId = 0; - if ( useProgress ) { - progressId = uiserver.newJob( kapp->dcopClient()->appId(), true ); - uiserver.totalFiles( progressId, count ); - uiserver.infoMessage( progressId, labelTxt ); - uiserver.transferring( progressId, labelTxt ); - } - - for ( int startIndex = 0; startIndex < count; startIndex += nbMessages ) { - TQMap<TQ_UINT32, TQString> lst; - if ( !kmailIncidences( lst, mimetype, subResource, startIndex, nbMessages ) ) { - kdError(5650) << "Communication problem in ResourceKolab::load()\n"; - if ( progressId ) - uiserver.jobFinished( progressId ); - return false; - } - - { // for RAII scoping below - TemporarySilencer t( this ); - for( TQMap<TQ_UINT32, TQString>::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { - addIncidence( mimetype, it.data(), subResource, it.key() ); - } - } - if ( progressId ) { - uiserver.processedFiles( progressId, startIndex ); - uiserver.percent( progressId, 100 * startIndex / count ); - } - -// if ( progress.wasCanceled() ) { -// uiserver.jobFinished( progressId ); -// return false; -// } - } - - if ( progressId ) - uiserver.jobFinished( progressId ); - return true; -} - -bool ResourceKolab::doLoad() -{ - if (!mUidMap.isEmpty() ) { - emit resourceLoaded( this ); - return true; - } - mUidMap.clear(); - - bool result = loadAllEvents() & loadAllTodos() & loadAllJournals(); - if ( result ) { - emit resourceLoaded( this ); - } else { - // FIXME: anyone know if the resource correctly calls loadError() - // if it has one? - } - - return result; -} - -bool ResourceKolab::doLoadAll( ResourceMap& map, const char* mimetype ) -{ - bool rc = true; - for ( ResourceMap::ConstIterator it = map.begin(); it != map.end(); ++it ) { - if ( !it.data().active() ) - // This resource is disabled - continue; - - rc &= loadSubResource( it.key(), mimetype ); - } - return rc; -} - -bool ResourceKolab::loadAllEvents() -{ - removeIncidences( "Event" ); - mCalendar.deleteAllEvents(); - bool kolabStyle = doLoadAll( mEventSubResources, eventAttachmentMimeType ); - bool icalStyle = doLoadAll( mEventSubResources, incidenceInlineMimeType ); - return kolabStyle && icalStyle; -} - -bool ResourceKolab::loadAllTodos() -{ - removeIncidences( "Todo" ); - mCalendar.deleteAllTodos(); - bool kolabStyle = doLoadAll( mTodoSubResources, todoAttachmentMimeType ); - bool icalStyle = doLoadAll( mTodoSubResources, incidenceInlineMimeType ); - - return kolabStyle && icalStyle; -} - -bool ResourceKolab::loadAllJournals() -{ - removeIncidences( "Journal" ); - mCalendar.deleteAllJournals(); - bool kolabStyle = doLoadAll( mJournalSubResources, journalAttachmentMimeType ); - bool icalStyle = doLoadAll( mJournalSubResources, incidenceInlineMimeType ); - - return kolabStyle && icalStyle; -} - -void ResourceKolab::removeIncidences( const TQCString& incidenceType ) -{ - Kolab::UidMap::Iterator mapIt = mUidMap.begin(); - while ( mapIt != mUidMap.end() ) - { - Kolab::UidMap::Iterator it = mapIt++; - // Check the type of this uid: event, todo or journal. - // Need to look up in mCalendar for that. Given the implementation of incidence(uid), - // better call event(uid), todo(uid) etc. directly. - - // A faster but hackish way would probably be to check the type of the resource, - // like mEventSubResources.find( it.data().resource() ) != mEventSubResources.end() ? - const TQString& uid = it.key(); - if ( incidenceType == "Event" && mCalendar.event( uid ) ) - mUidMap.remove( it ); - else if ( incidenceType == "Todo" && mCalendar.todo( uid ) ) - mUidMap.remove( it ); - else if ( incidenceType == "Journal" && mCalendar.journal( uid ) ) - mUidMap.remove( it ); - } -} - -bool ResourceKolab::doSave() -{ - return true; - /* - return kmailTriggerSync( kmailCalendarContentsType ) - && kmailTriggerSync( kmailTodoContentsType ) - && kmailTriggerSync( kmailJournalContentsType ); - */ -} -void ResourceKolab::incidenceUpdatedSilent( KCal::IncidenceBase* incidencebase ) -{ - const TQString uid = incidencebase->uid(); - //kdDebug() << k_funcinfo << uid << endl; - - if ( mUidsPendingUpdate.contains( uid ) || mUidsPendingAdding.contains( uid ) ) { - /* We are currently processing this event ( removing and readding or - * adding it ). If so, ignore this update. Keep the last of these around - * and process once we hear back from KMail on this event. */ - mPendingUpdates.remove( uid ); - mPendingUpdates.insert( uid, incidencebase ); - return; - } - - { // start optimization - /** - KOrganizer and libkcal like calling two Incidence::updated() - for only one user change. That's because after a change, - IncidenceChanger calls incidence->setRevision( rev++ ); - which also calls Incidence::updated(). - - Lets ignore the first updated() and only send to kmail - the second. This makes things faster. - */ - - //IncidenceBase doesn't have revision(), downcast needed. - Incidence *i = dynamic_cast<Incidence*>( incidencebase ); - - if ( i ) { - bool ignoreThisUpdate = false; - - if ( !mLastKnownRevisions.contains( uid ) ) { - mLastKnownRevisions[uid] = i->revision(); - } - - // update the last known revision - if ( mLastKnownRevisions[uid] < i->revision() ) { - mLastKnownRevisions[uid] = i->revision(); - } else { - ignoreThisUpdate = true; - } - - if ( ignoreThisUpdate ) { - return; - } - } - } // end optimization - - TQString subResource; - TQ_UINT32 sernum = 0; - if ( mUidMap.contains( uid ) ) { - subResource = mUidMap[ uid ].resource(); - sernum = mUidMap[ uid ].serialNumber(); - mUidsPendingUpdate.append( uid ); - } - - sendKMailUpdate( incidencebase, subResource, sernum ); -} -void ResourceKolab::incidenceUpdated( KCal::IncidenceBase* incidencebase ) -{ - if ( incidencebase->isReadOnly() ) { - return; - } - - incidencebase->setSyncStatusSilent( KCal::Event::SYNCMOD ); - incidencebase->setLastModified( TQDateTime::currentDateTime() ); - - // we should probably update the revision number here, - // or internally in the Event itself when certain things change. - // need to verify with ical documentation. - incidenceUpdatedSilent( incidencebase ); -} - -void ResourceKolab::resolveConflict( KCal::Incidence* inc, const TQString& subresource, TQ_UINT32 sernum ) -{ - if ( !inc ) { - return; - } - - if ( !mResolveConflict ) { - // we should do no conflict resolution - delete inc; - return; - } - const TQString origUid = inc->uid(); - Incidence* local = mCalendar.incidence( origUid ); - Incidence* localIncidence = 0; - Incidence* addedIncidence = 0; - Incidence* result = 0; - if ( local ) { - if ( *local == *inc ) { - // real duplicate, remove the second one - result = local; - } else { - KIncidenceChooser* ch = new KIncidenceChooser(); - ch->setIncidence( local ,inc ); - if ( KIncidenceChooser::chooseMode == KIncidenceChooser::ask ) { - connect ( this, TQT_SIGNAL( useGlobalMode() ), ch, TQT_SLOT ( useGlobalMode() ) ); - if ( ch->exec() ) { - if ( KIncidenceChooser::chooseMode != KIncidenceChooser::ask ) { - emit useGlobalMode() ; - } - } - } - result = ch->getIncidence(); - delete ch; - } - } else { - // nothing there locally, just take the new one. Can't Happen (TM) - result = inc; - } - if ( result == local ) { - delete inc; - localIncidence = local; - } else if ( result == inc ) { - addedIncidence = inc; - } else if ( result == 0 ) { // take both - addedIncidence = inc; - addedIncidence->setSummary( i18n("Copy of: %1").arg( addedIncidence->summary() ) ); - addedIncidence->setUid( CalFormat::createUniqueId() ); - localIncidence = local; - } - const bool silent = mSilent; - mSilent = false; - if ( !localIncidence ) { - deleteIncidence( local ); // remove local from kmail - } - mUidsPendingDeletion.append( origUid ); - if ( addedIncidence ) { - sendKMailUpdate( addedIncidence, subresource, sernum ); - } else { - kmailDeleteIncidence( subresource, sernum );// remove new from kmail - } - mSilent = silent; -} -void ResourceKolab::addIncidence( const char* mimetype, const TQString& data, - const TQString& subResource, TQ_UINT32 sernum ) -{ - // This uses pointer comparison, so it only works if we use the static - // objects defined in the top of the file - if ( mimetype == eventAttachmentMimeType ) - addEvent( data, subResource, sernum ); - else if ( mimetype == todoAttachmentMimeType ) - addTodo( data, subResource, sernum ); - else if ( mimetype == journalAttachmentMimeType ) - addJournal( data, subResource, sernum ); - else if ( mimetype == incidenceInlineMimeType ) { - Incidence *inc = mFormat.fromString( data ); - addIncidence( inc, subResource, sernum ); - } -} - - -bool ResourceKolab::sendKMailUpdate( KCal::IncidenceBase* incidencebase, const TQString& subresource, - TQ_UINT32 sernum ) -{ - const TQString& type = incidencebase->type(); - const char* mimetype = 0; - TQString data; - bool isXMLStorageFormat = kmailStorageFormat( subresource ) == KMailICalIface::StorageXML; - if ( type == "Event" ) { - if( isXMLStorageFormat ) { - mimetype = eventAttachmentMimeType; - data = Kolab::Event::eventToXML( static_cast<KCal::Event *>(incidencebase), - mCalendar.timeZoneId() ); - } else { - mimetype = incidenceInlineMimeType; - data = mFormat.createScheduleMessage( static_cast<KCal::Event *>(incidencebase), - Scheduler::Request ); - } - } else if ( type == "Todo" ) { - if( isXMLStorageFormat ) { - mimetype = todoAttachmentMimeType; - data = Kolab::Task::taskToXML( static_cast<KCal::Todo *>(incidencebase), - mCalendar.timeZoneId() ); - } else { - mimetype = incidenceInlineMimeType; - data = mFormat.createScheduleMessage( static_cast<KCal::Todo *>(incidencebase), - Scheduler::Request ); - } - } else if ( type == "Journal" ) { - if( isXMLStorageFormat ) { - mimetype = journalAttachmentMimeType; - data = Kolab::Journal::journalToXML( static_cast<KCal::Journal *>(incidencebase ), - mCalendar.timeZoneId() ); - } else { - mimetype = incidenceInlineMimeType; - data = mFormat.createScheduleMessage( static_cast<KCal::Journal *>(incidencebase), - Scheduler::Request ); - } - } else { - kdWarning(5006) << "Can't happen: unhandled type=" << type << endl; - } - -// kdDebug() << k_funcinfo << "Data string:\n" << data << endl; - - KCal::Incidence* incidence = static_cast<KCal::Incidence *>( incidencebase ); - - KCal::Attachment::List atts = incidence->attachments(); - TQStringList attURLs, attMimeTypes, attNames; - TQValueList<KTempFile*> tmpFiles; - for ( KCal::Attachment::List::ConstIterator it = atts.constBegin(); it != atts.constEnd(); ++it ) { - if ( (*it)->isUri() ) { - continue; - } - KTempFile *tempFile = new KTempFile; - if ( tempFile->status() == 0 ) { // open ok - const TQByteArray decoded = (*it)->decodedData() ; - - tempFile->file()->writeBlock( decoded.data(), decoded.count() ); - KURL url; - url.setPath( tempFile->name() ); - attURLs.append( url.url() ); - attMimeTypes.append( (*it)->mimeType() ); - attNames.append( (*it)->label() ); - tempFile->close(); - tmpFiles.append( tempFile ); - } else { - kdWarning(5006) << "Cannot open temporary file for attachment"; - } - } - TQStringList deletedAtts; - if ( kmailListAttachments( deletedAtts, subresource, sernum ) ) { - for ( TQStringList::ConstIterator it = attNames.constBegin(); it != attNames.constEnd(); ++it ) { - deletedAtts.remove( *it ); - } - } - CustomHeaderMap customHeaders; - if ( incidence->schedulingID() != incidence->uid() ) { - customHeaders.insert( "X-Kolab-SchedulingID", incidence->schedulingID() ); - } - - TQString subject = incidencebase->uid(); - if ( !isXMLStorageFormat ) subject.prepend( "iCal " ); // conform to the old style - - // behold, sernum is an in-parameter - const bool rc = kmailUpdate( subresource, sernum, data, mimetype, subject, customHeaders, attURLs, attMimeTypes, attNames, deletedAtts ); - // update the serial number - if ( mUidMap.contains( incidencebase->uid() ) ) { - mUidMap[ incidencebase->uid() ].setSerialNumber( sernum ); - } - - for( TQValueList<KTempFile *>::Iterator it = tmpFiles.begin(); it != tmpFiles.end(); ++it ) { - (*it)->setAutoDelete( true ); - delete (*it); - } - - return rc; -} - -bool ResourceKolab::addIncidence( KCal::Incidence* incidence, const TQString& _subresource, - TQ_UINT32 sernum ) -{ - Q_ASSERT( incidence ); - if ( !incidence ) { - return false; - } - - kdDebug() << "Resourcekolab, adding incidence " - << incidence->summary() - << "; subresource = " << _subresource - << "; sernum = " << sernum - << "; mBatchAddingInProgress = " << mBatchAddingInProgress - << endl; - - TQString uid = incidence->uid(); - TQString subResource = _subresource; - - Kolab::ResourceMap *map = &mEventSubResources; // don't use a ref here! - - const TQString& type = incidence->type(); - if ( type == "Event" ) { - map = &mEventSubResources; - } else if ( type == "Todo" ) { - map = &mTodoSubResources; - } else if ( type == "Journal" ) { - map = &mJournalSubResources; - } else { - kdWarning() << "unknown type " << type << endl; - } - - if ( !mSilent ) { /* We got this one from the user, tell KMail. */ - // Find out if this event was previously stored in KMail - bool newIncidence = _subresource.isEmpty(); - if ( newIncidence ) { - ResourceType type = Incidences; - // Add a description of the incidence - TQString text = "<b><font size=\"+1\">"; - if ( incidence->type() == "Event" ) { - type = Events; - text += i18n( "Choose the folder where you want to store this event" ); - } else if ( incidence->type() == "Todo" ) { - type = Tasks; - text += i18n( "Choose the folder where you want to store this task" ); - } else { - text += i18n( "Choose the folder where you want to store this incidence" ); - } - text += "<font></b><br>"; - if ( !incidence->summary().isEmpty() ) - text += i18n( "<b>Summary:</b> %1" ).arg( incidence->summary() ) + "<br>"; - if ( !incidence->location().isEmpty() ) - text += i18n( "<b>Location:</b> %1" ).arg( incidence->location() ); - text += "<br>"; - if ( !incidence->doesFloat() ) - text += i18n( "<b>Start:</b> %1, %2" ) - .arg( incidence->dtStartDateStr(), incidence->dtStartTimeStr() ); - else - text += i18n( "<b>Start:</b> %1" ).arg( incidence->dtStartDateStr() ); - text += "<br>"; - if ( incidence->type() == "Event" ) { - Event* event = static_cast<Event*>( incidence ); - if ( event->hasEndDate() ) { - if ( !event->doesFloat() ) { - text += i18n( "<b>End:</b> %1, %2" ) - .arg( event->dtEndDateStr(), event->dtEndTimeStr() ); - } else { - text += i18n( "<b>End:</b> %1" ).arg( event->dtEndDateStr() ); - } - } - text += "<br>"; - } - - // Lets not warn the user 100 times that there's no writable resource - // and not ask 100 times which resource to use - if ( !mBatchAddingInProgress || !mLastUsedResources.contains( type ) ) { - subResource = findWritableResource( type, *map, text ); - mLastUsedResources[type] = subResource; - } else { - subResource = mLastUsedResources[type]; - } - - if ( subResource.isEmpty() ) { - switch( mErrorCode ) { - case NoWritableFound: - setException( new ErrorFormat( ErrorFormat::NoWritableFound ) ); - break; - case UserCancel: - setException( new ErrorFormat( ErrorFormat::UserCancel ) ); - break; - case NoError: - break; - } - } - } - - if ( subResource.isEmpty() ) { - endAddingIncidences(); // cleanup - kdDebug(5650) << "ResourceKolab: subResource is empty" << endl; - return false; - } - - mNewIncidencesMap.insert( uid, subResource ); - - if ( !sendKMailUpdate( incidence, subResource, sernum ) ) { - kdError(5650) << "Communication problem in ResourceKolab::addIncidence()\n"; - endAddingIncidences(); // cleanup - return false; - } else { - // KMail is doing it's best to add the event now, put a sticker on it, - // so we know it's one of our transient ones - mUidsPendingAdding.append( uid ); - - /* Add to the cache immediately if this is a new event coming from - * KOrganizer. It relies on the incidence being in the calendar when - * addIncidence returns. */ - if ( newIncidence || sernum == 0 ) { - mCalendar.addIncidence( incidence ); - incidence->registerObserver( this ); - } - } - } else { /* KMail told us */ - const bool ourOwnUpdate = mUidsPendingUpdate.contains( uid ); - kdDebug( 5650 ) << "addIncidence: ourOwnUpdate " << ourOwnUpdate << endl; - /* Check if we updated this one, which means kmail deleted and added it. - * We know the new state, so lets just not do much at all. The old incidence - * in the calendar remains valid, but the serial number changed, so we need to - * update that */ - if ( ourOwnUpdate ) { - mUidsPendingUpdate.remove( uid ); - mUidMap.remove( uid ); - mUidMap[ uid ] = StorageReference( subResource, sernum ); - } else { - /* This is a real add, from KMail, we didn't trigger this ourselves. - * If this uid already exists in this folder, do conflict resolution, - * unless the folder is read-only, in which case the user should not be - * offered a means of putting mails in a folder she'll later be unable to - * upload. Skip the incidence, in this case. */ - if ( mUidMap.contains( uid ) ) { - if ( mUidMap[ uid ].resource() == subResource ) { - if ( (*map)[ subResource ].writable() ) { - kdDebug( 5650 ) << "lets resolve the conflict " << endl; - resolveConflict( incidence, subResource, sernum ); - } else { - kdWarning( 5650 ) << "Duplicate event in a read-only folder detected! " - "Please inform the owner of the folder. " << endl; - } - return true; - } else { - // duplicate uid in a different folder, do the internal-uid tango - incidence->setSchedulingID( uid ); - - incidence->setUid( CalFormat::createUniqueId( ) ); - uid = incidence->uid(); - - /* Will be needed when kmail triggers a delete, so we don't delete the inocent - * incidence that's sharing the uid with this one */ - mOriginalUID2fakeUID[tqMakePair( incidence->schedulingID(), subResource )] = uid; - } - } - /* Add to the cache if the add didn't come from KOrganizer, in which case - * we've already added it, and listen to updates from KOrganizer for it. */ - if ( !mUidsPendingAdding.contains( uid ) ) { - mCalendar.addIncidence( incidence ); - incidence->registerObserver( this ); - } - if ( !subResource.isEmpty() && sernum != 0 ) { - mUidMap[ uid ] = StorageReference( subResource, sernum ); - incidence->setReadOnly( !(*map)[ subResource ].writable() ); - } - } - /* Check if there are updates for this uid pending and if so process them. */ - if ( KCal::IncidenceBase *update = mPendingUpdates.find( uid ) ) { - mSilent = false; // we do want to tell KMail - mPendingUpdates.remove( uid ); - incidenceUpdated( update ); - } else { - /* If the uid was added by KMail, KOrganizer needs to be told, so - * schedule emitting of the resourceChanged signal. */ - if ( !mUidsPendingAdding.contains( uid ) ) { - if ( !ourOwnUpdate ) mResourceChangedTimer.changeInterval( 100 ); - } else { - mUidsPendingAdding.remove( uid ); - } - } - - mNewIncidencesMap.remove( uid ); - } - return true; -} - -bool ResourceKolab::addEvent( KCal::Event *event ) -{ - return addEvent( event, TQString() ); -} - -bool ResourceKolab::addEvent( KCal::Event *event, const TQString &subResource ) -{ - if ( mUidMap.contains( event->uid() ) ) { - return true; //noop - } else { - return addIncidence( event, subResource, 0 ); - } -} - -void ResourceKolab::addEvent( const TQString& xml, const TQString& subresource, - TQ_UINT32 sernum ) -{ - KCal::Event* event = Kolab::Event::xmlToEvent( xml, mCalendar.timeZoneId(), this, subresource, sernum ); - Q_ASSERT( event ); - if ( event ) { - addIncidence( event, subresource, sernum ); - } -} - -bool ResourceKolab::deleteIncidence( KCal::Incidence* incidence ) -{ - if ( incidence->isReadOnly() ) { - return false; - } - - const TQString uid = incidence->uid(); - if( !mUidMap.contains( uid ) ) return false; // Odd - /* The user told us to delete, tell KMail */ - if ( !mSilent ) { - kmailDeleteIncidence( mUidMap[ uid ].resource(), - mUidMap[ uid ].serialNumber() ); - mUidsPendingDeletion.append( uid ); - incidence->unRegisterObserver( this ); - mCalendar.deleteIncidence( incidence ); - mUidMap.remove( uid ); - } else { - assert( false ); // If this still happens, something is very wrong - } - return true; -} - -bool ResourceKolab::deleteEvent( KCal::Event* event ) -{ - return deleteIncidence( event ); -} - -KCal::Event* ResourceKolab::event( const TQString& uid ) -{ - return mCalendar.event(uid); -} - -KCal::Event::List ResourceKolab::rawEvents( EventSortField sortField, SortDirection sortDirection ) -{ - return mCalendar.rawEvents( sortField, sortDirection ); -} - -KCal::Event::List ResourceKolab::rawEventsForDate( const TQDate& date, - EventSortField sortField, - SortDirection sortDirection ) -{ - return mCalendar.rawEventsForDate( date, sortField, sortDirection ); -} - -KCal::Event::List ResourceKolab::rawEventsForDate( const TQDateTime& qdt ) -{ - return mCalendar.rawEventsForDate( qdt ); -} - -KCal::Event::List ResourceKolab::rawEvents( const TQDate& start, - const TQDate& end, - bool inclusive ) -{ - return mCalendar.rawEvents( start, end, inclusive ); -} - -bool ResourceKolab::addTodo( KCal::Todo *todo ) -{ - return addTodo( todo, TQString() ); -} - -bool ResourceKolab::addTodo( KCal::Todo *todo, const TQString &subResource ) -{ - if ( mUidMap.contains( todo->uid() ) ) { - return true; //noop - } else { - return addIncidence( todo, subResource, 0 ); - } -} - -void ResourceKolab::addTodo( const TQString& xml, const TQString& subresource, - TQ_UINT32 sernum ) -{ - KCal::Todo* todo = Kolab::Task::xmlToTask( xml, mCalendar.timeZoneId(), this, subresource, sernum ); - Q_ASSERT( todo ); - if ( todo ) { - addIncidence( todo, subresource, sernum ); - } -} - -bool ResourceKolab::deleteTodo( KCal::Todo* todo ) -{ - return deleteIncidence( todo ); -} - -KCal::Todo* ResourceKolab::todo( const TQString& uid ) -{ - return mCalendar.todo( uid ); -} - -KCal::Todo::List ResourceKolab::rawTodos( TodoSortField sortField, SortDirection sortDirection ) -{ - return mCalendar.rawTodos( sortField, sortDirection ); -} - -KCal::Todo::List ResourceKolab::rawTodosForDate( const TQDate& date ) -{ - return mCalendar.rawTodosForDate( date ); -} - -bool ResourceKolab::addJournal( KCal::Journal *journal ) -{ - return addJournal( journal, TQString() ); -} - -bool ResourceKolab::addJournal( KCal::Journal *journal, const TQString &subResource ) -{ - if ( mUidMap.contains( journal->uid() ) ) - return true; //noop - else - return addIncidence( journal, subResource, 0 ); -} - -void ResourceKolab::addJournal( const TQString& xml, const TQString& subresource, - TQ_UINT32 sernum ) -{ - KCal::Journal* journal = - Kolab::Journal::xmlToJournal( xml, mCalendar.timeZoneId() ); - Q_ASSERT( journal ); - if( journal ) { - addIncidence( journal, subresource, sernum ); - } -} - -bool ResourceKolab::deleteJournal( KCal::Journal* journal ) -{ - return deleteIncidence( journal ); -} - -KCal::Journal* ResourceKolab::journal( const TQString& uid ) -{ - return mCalendar.journal(uid); -} - -KCal::Journal::List ResourceKolab::rawJournals( JournalSortField sortField, SortDirection sortDirection ) -{ - return mCalendar.rawJournals( sortField, sortDirection ); -} - -KCal::Journal::List ResourceKolab::rawJournalsForDate( const TQDate &date ) -{ - return mCalendar.rawJournalsForDate( date ); -} - -KCal::Alarm::List ResourceKolab::relevantAlarms( const KCal::Alarm::List &alarms ) -{ - KCal::Alarm::List relevantAlarms; - KCal::Alarm::List::ConstIterator it( alarms.begin() ); - while ( it != alarms.end() ) { - KCal::Alarm *a = (*it); - ++it; - const TQString &uid = a->parent()->uid(); - if ( mUidMap.contains( uid ) ) { - const TQString &sr = mUidMap[ uid ].resource(); - Kolab::SubResource *subResource = 0; - if ( mEventSubResources.contains( sr ) ) - subResource = &( mEventSubResources[ sr ] ); - else if ( mTodoSubResources.contains( sr ) ) - subResource = &( mTodoSubResources[ sr ] ); - assert( subResource ); - if ( subResource->alarmRelevant() ) - relevantAlarms.append ( a ); - else { - kdDebug(5650) << "Alarm skipped, not relevant." << endl; - } - } - } - return relevantAlarms; -} - - - -KCal::Alarm::List ResourceKolab::alarms( const TQDateTime& from, - const TQDateTime& to ) -{ - return relevantAlarms( mCalendar.alarms( from, to ) ); -} - -KCal::Alarm::List ResourceKolab::alarmsTo( const TQDateTime& to ) -{ - return relevantAlarms( mCalendar.alarmsTo(to) ); -} - -void ResourceKolab::setTimeZoneId( const TQString& tzid ) -{ - mCalendar.setTimeZoneId( tzid ); - mFormat.setTimeZone( mCalendar.timeZoneId(), !mCalendar.isLocalTime() ); -} - -bool ResourceKolab::fromKMailAddIncidence( const TQString& type, - const TQString& subResource, - TQ_UINT32 sernum, - int format, - const TQString& data ) -{ - bool rc = true; - TemporarySilencer t( this ); // RAII - if ( type != kmailCalendarContentsType && type != kmailTodoContentsType - && type != kmailJournalContentsType ) { - // Not ours - return false; - } - - if ( !subresourceActive( subResource ) ) { - return true; - } - - if ( format == KMailICalIface::StorageXML ) { - // If this data file is one of ours, load it here - if ( type == kmailCalendarContentsType ) { - addEvent( data, subResource, sernum ); - } else if ( type == kmailTodoContentsType ) { - addTodo( data, subResource, sernum ); - } else if ( type == kmailJournalContentsType ) { - addJournal( data, subResource, sernum ); - } else { - rc = false; - } - } else { - Incidence *inc = mFormat.fromString( data ); - if ( inc ) { - addIncidence( inc, subResource, sernum ); - } else { - rc = false; - } - } - return rc; -} - -void ResourceKolab::fromKMailDelIncidence( const TQString& type, - const TQString& subResource, - const TQString& uid ) -{ - if ( type != kmailCalendarContentsType && type != kmailTodoContentsType - && type != kmailJournalContentsType ) - // Not ours - return; - if ( !subresourceActive( subResource ) ) return; - - // Can't be in both, by contract - if ( mUidsPendingDeletion.find( uid ) != mUidsPendingDeletion.end() ) { - mUidsPendingDeletion.remove( mUidsPendingDeletion.find( uid ) ); - } else if ( mUidsPendingUpdate.contains( uid ) ) { - // It's good to know if was deleted, but we are waiting on a new one to - // replace it, so let's just sit tight. - } else { - TQString uidToUse; - - TQPair<TQString, TQString> p( uid, subResource ); - if ( mOriginalUID2fakeUID.contains( p ) ) { - // Incidence with the same uid in a different folder... - // use the UID that addIncidence(...) generated - uidToUse = mOriginalUID2fakeUID[p]; - } else { - uidToUse = uid; - } - - // We didn't trigger this, so KMail did, remove the reference to the uid - KCal::Incidence* incidence = mCalendar.incidence( uidToUse ); - if( incidence ) { - incidence->unRegisterObserver( this ); - mCalendar.deleteIncidence( incidence ); - } - mUidMap.remove( uidToUse ); - mOriginalUID2fakeUID.remove( p ); - mResourceChangedTimer.changeInterval( 100 ); - } -} - -void ResourceKolab::fromKMailRefresh( const TQString& type, - const TQString& /*subResource*/ ) -{ - // TODO: Only load the specified subResource - if ( type == "Calendar" ) - loadAllEvents(); - else if ( type == "Task" ) - loadAllTodos(); - else if ( type == "Journal" ) - loadAllJournals(); - else - kdWarning(5006) << "KCal Kolab resource: fromKMailRefresh: unknown type " << type << endl; - mResourceChangedTimer.changeInterval( 100 ); -} - -void ResourceKolab::fromKMailAddSubresource( const TQString& type, - const TQString& subResource, - const TQString& label, - bool writable, bool alarmRelevant ) -{ - ResourceMap* map = 0; - const char* mimetype = 0; - if ( type == kmailCalendarContentsType ) { - map = &mEventSubResources; - mimetype = eventAttachmentMimeType; - } else if ( type == kmailTodoContentsType ) { - map = &mTodoSubResources; - mimetype = todoAttachmentMimeType; - } else if ( type == kmailJournalContentsType ) { - map = &mJournalSubResources; - mimetype = journalAttachmentMimeType; - } else - // Not ours - return; - - if ( map->contains( subResource ) ) - // Already registered - return; - - TDEConfig config( configFile() ); - config.setGroup( subResource ); - - bool active = config.readBoolEntry( subResource, true ); - (*map)[ subResource ] = Kolab::SubResource( active, writable, - alarmRelevant, label ); - loadSubResource( subResource, mimetype ); - emit signalSubresourceAdded( this, type, subResource, label ); -} - -void ResourceKolab::fromKMailDelSubresource( const TQString& type, - const TQString& subResource ) -{ - ResourceMap* map = subResourceMap( type ); - if ( !map ) // not ours - return; - if ( map->contains( subResource ) ) - map->erase( subResource ); - else - // Not registered - return; - - // Delete from the config file - TDEConfig config( configFile() ); - config.deleteGroup( subResource ); - config.sync(); - - unloadSubResource( subResource ); - - emit signalSubresourceRemoved( this, type, subResource ); -} - -TQStringList ResourceKolab::subresources() const -{ - // Workaround: The ResourceView in KOrganizer wants to know this - // before it opens the resource :-( Make sure we are open - const_cast<ResourceKolab*>( this )->doOpen(); - return ( mEventSubResources.keys() - + mTodoSubResources.keys() - + mJournalSubResources.keys() ); -} - -const TQString -ResourceKolab::labelForSubresource( const TQString& subresource ) const -{ - if ( mEventSubResources.contains( subresource ) ) - return mEventSubResources[ subresource ].label(); - if ( mTodoSubResources.contains( subresource ) ) - return mTodoSubResources[ subresource ].label(); - if ( mJournalSubResources.contains( subresource ) ) - return mJournalSubResources[ subresource ].label(); - return subresource; -} - -void ResourceKolab::fromKMailAsyncLoadResult( const TQMap<TQ_UINT32, TQString>& map, - const TQString& type, - const TQString& folder ) -{ - TemporarySilencer t( this ); - for( TQMap<TQ_UINT32, TQString>::ConstIterator it = map.begin(); it != map.end(); ++it ) - addIncidence( type.latin1(), it.data(), folder, it.key() ); -} - -bool ResourceKolab::subresourceActive( const TQString& subresource ) const -{ - // Workaround: The ResourceView in KOrganizer wants to know this - // before it opens the resource :-( Make sure we are open - const_cast<ResourceKolab*>( this )->doOpen(); - - if ( mEventSubResources.contains( subresource ) ) - return mEventSubResources[ subresource ].active(); - if ( mTodoSubResources.contains( subresource ) ) - return mTodoSubResources[ subresource ].active(); - if ( mJournalSubResources.contains( subresource ) ) - return mJournalSubResources[ subresource ].active(); - - // Safe default bet: - kdDebug(5650) << "subresourceActive( " << subresource << " ): Safe bet\n"; - - return true; -} - -void ResourceKolab::setSubresourceActive( const TQString &subresource, bool v ) -{ - ResourceMap *map = 0; - const char* mimeType = 0; - if ( mEventSubResources.contains( subresource ) ) { - map = &mEventSubResources; - mimeType = eventAttachmentMimeType; - } - if ( mTodoSubResources.contains( subresource ) ) { - map = &mTodoSubResources; - mimeType = todoAttachmentMimeType; - } - if ( mJournalSubResources.contains( subresource ) ) { - map = &mJournalSubResources; - mimeType = journalAttachmentMimeType; - } - - if ( map && ( ( *map )[ subresource ].active() != v ) ) { - ( *map )[ subresource ].setActive( v ); - if ( v ) { - loadSubResource( subresource, mimeType ); - } else { - unloadSubResource( subresource ); - } - mResourceChangedTimer.changeInterval( 100 ); - } - TQTimer::singleShot( 0, this, TQT_SLOT(writeConfig()) ); -} - -bool ResourceKolab::subresourceWritable( const TQString& subresource ) const -{ - // Workaround: The ResourceView in KOrganizer wants to know this - // before it opens the resource :-( Make sure we are open - const_cast<ResourceKolab*>( this )->doOpen(); - - if ( mEventSubResources.contains( subresource ) ) - return mEventSubResources[ subresource ].writable(); - if ( mTodoSubResources.contains( subresource ) ) - return mTodoSubResources[ subresource ].writable(); - if ( mJournalSubResources.contains( subresource ) ) - return mJournalSubResources[ subresource ].writable(); - - return false; //better a safe default -} - -void ResourceKolab::slotEmitResourceChanged() -{ - kdDebug(5650) << "KCal Kolab resource: emitting resource changed " << endl; - mResourceChangedTimer.stop(); - emit resourceChanged( this ); -} - -KABC::Lock* ResourceKolab::lock() -{ - return new KABC::LockNull( true ); -} - -Kolab::ResourceMap* ResourceKolab::subResourceMap( const TQString& contentsType ) -{ - if ( contentsType == kmailCalendarContentsType ) { - return &mEventSubResources; - } else if ( contentsType == kmailTodoContentsType ) { - return &mTodoSubResources; - } else if ( contentsType == kmailJournalContentsType ) { - return &mJournalSubResources; - } - // Not ours - return 0; -} - - -/*virtual*/ -bool ResourceKolab::addSubresource( const TQString& resource, const TQString& parent ) -{ - kdDebug(5650) << "KCal Kolab resource - adding subresource: " << resource << endl; - TQString contentsType = kmailCalendarContentsType; - if ( !parent.isEmpty() ) { - if ( mEventSubResources.contains( parent ) ) - contentsType = kmailCalendarContentsType; - else if ( mTodoSubResources.contains( parent ) ) - contentsType = kmailTodoContentsType; - else if ( mJournalSubResources.contains( parent ) ) - contentsType = kmailJournalContentsType; - } else { - TQStringList contentTypeChoices; - contentTypeChoices << i18n("Calendar") << i18n("Tasks") << i18n("Journals"); - const TQString caption = i18n("Which kind of subresource should this be?"); - const TQString choice = KInputDialog::getItem( caption, TQString(), contentTypeChoices ); - if ( choice == contentTypeChoices[0] ) - contentsType = kmailCalendarContentsType; - else if ( choice == contentTypeChoices[1] ) - contentsType = kmailTodoContentsType; - else if ( choice == contentTypeChoices[2] ) - contentsType = kmailJournalContentsType; - } - - return kmailAddSubresource( resource, parent, contentsType ); -} - -/*virtual*/ -bool ResourceKolab::removeSubresource( const TQString& resource ) -{ - kdDebug(5650) << "KCal Kolab resource - removing subresource: " << resource << endl; - return kmailRemoveSubresource( resource ); -} - -/*virtual*/ -TQString ResourceKolab::subresourceIdentifier( Incidence *incidence ) -{ - TQString uid = incidence->uid(); - if ( mUidMap.contains( uid ) ) - return mUidMap[ uid ].resource(); - else - if ( mNewIncidencesMap.contains( uid ) ) - return mNewIncidencesMap[ uid ]; - else - return TQString(); -} - - -bool ResourceKolab::unloadSubResource( const TQString& subResource ) -{ - const bool silent = mSilent; - mSilent = true; - Kolab::UidMap::Iterator mapIt = mUidMap.begin(); - TQPtrList<KCal::Incidence> incidences; - while ( mapIt != mUidMap.end() ) - { - Kolab::UidMap::Iterator it = mapIt++; - const StorageReference ref = it.data(); - if ( ref.resource() != subResource ) continue; - // FIXME incidence() is expensive - KCal::Incidence* incidence = mCalendar.incidence( it.key() ); - if( incidence ) { - // register all observers first before actually deleting them - // in case of inter-incidence relations the other part will get - // the change notification otherwise - incidence->unRegisterObserver( this ); - incidences.append( incidence ); - } - mUidMap.remove( it ); - } - TQPtrListIterator<KCal::Incidence> it( incidences ); - for ( ; it.current(); ++it ) { - mCalendar.deleteIncidence( it.current() ); - } - mSilent = silent; - return true; -} - -TQString ResourceKolab::subresourceType( const TQString &resource ) -{ - if ( mEventSubResources.contains( resource ) ) - return "event"; - if ( mTodoSubResources.contains( resource ) ) - return "todo"; - if ( mJournalSubResources.contains( resource ) ) - return "journal"; - return TQString(); -} - -void ResourceKolab::writeConfig() -{ - TDEConfig config( configFile() ); - writeResourceConfig( config, mEventSubResources ); - writeResourceConfig( config, mTodoSubResources ); - writeResourceConfig( config, mJournalSubResources ); -} - -void ResourceKolab::beginAddingIncidences() -{ - mBatchAddingInProgress = true; -} - -void ResourceKolab::endAddingIncidences() -{ - mBatchAddingInProgress = false; - mLastUsedResources.clear(); -} - -#include "resourcekolab.moc" diff --git a/kresources/kolab/kcal/resourcekolab.h b/kresources/kolab/kcal/resourcekolab.h deleted file mode 100644 index fdf952cc3..000000000 --- a/kresources/kolab/kcal/resourcekolab.h +++ /dev/null @@ -1,284 +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> - 2004 Till Adam <till@klaralvdalens-datakonsult.se> - - 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. -*/ - -#ifndef KCAL_RESOURCEKOLAB_H -#define KCAL_RESOURCEKOLAB_H - -#include <tqtimer.h> - -#include <tdepimmacros.h> -#include <libkcal/calendarlocal.h> -#include <libkcal/icalformat.h> -#include <libkcal/resourcecalendar.h> -#include "../shared/resourcekolabbase.h" - -namespace KCal { - -struct TemporarySilencer; - -class KDE_EXPORT ResourceKolab : public KCal::ResourceCalendar, - public KCal::IncidenceBase::Observer, - public Kolab::ResourceKolabBase -{ - Q_OBJECT - - friend struct TemporarySilencer; - -public: - ResourceKolab( const TDEConfig* ); - virtual ~ResourceKolab(); - - /// Load resource data. - bool doLoad(); - - /// Save resource data. - bool doSave(); - - /// Open the notes resource. - bool doOpen(); - /// Close the notes resource. - void doClose(); - - // The libkcal functions. See the resource for descriptions - KDE_DEPRECATED bool addEvent( KCal::Event *event ); - bool addEvent( KCal::Event *event, const TQString &subResource ); - bool deleteEvent( KCal::Event * ); - KCal::Event* event( const TQString &UniqueStr ); - KCal::Event::List rawEvents( EventSortField sortField = EventSortUnsorted, SortDirection sortDirection = SortDirectionAscending ); - KCal::Event::List rawEventsForDate( - const TQDate& date, - EventSortField sortField=EventSortUnsorted, - SortDirection sortDirection=SortDirectionAscending ); - KCal::Event::List rawEventsForDate( const TQDateTime& qdt ); - KCal::Event::List rawEvents( const TQDate& start, const TQDate& end, - bool inclusive = false ); - - KDE_DEPRECATED bool addTodo( KCal::Todo * todo ); - bool addTodo( KCal::Todo *todo, const TQString &subResource ); - bool deleteTodo( KCal::Todo * ); - KCal::Todo* todo( const TQString &uid ); - KCal::Todo::List rawTodos( TodoSortField sortField = TodoSortUnsorted, SortDirection sortDirection = SortDirectionAscending ); - KCal::Todo::List rawTodosForDate( const TQDate& date ); - - KDE_DEPRECATED bool addJournal( KCal::Journal * ); - bool addJournal( KCal::Journal *, const TQString &subResource ); - bool deleteJournal( KCal::Journal * ); - KCal::Journal* journal( const TQString &uid ); - KCal::Journal::List rawJournals( JournalSortField sortField = JournalSortUnsorted, SortDirection sortDirection = SortDirectionAscending ); - KCal::Journal::List rawJournalsForDate( const TQDate &date ); - - KCal::Alarm::List alarms( const TQDateTime& from, const TQDateTime& to ); - KCal::Alarm::List alarmsTo( const TQDateTime& to ); - - void setTimeZoneId( const TQString& tzid ); - - bool deleteIncidence( KCal::Incidence* i ); - - /// The ResourceKolabBase methods called by KMail - bool fromKMailAddIncidence( const TQString& type, const TQString& subResource, - TQ_UINT32 sernum, int format, const TQString& data ); - void fromKMailDelIncidence( const TQString& type, const TQString& subResource, - const TQString& uid ); - void fromKMailRefresh( const TQString& type, const TQString& subResource ); - - /// Listen to KMail changes in the amount of sub resources - void fromKMailAddSubresource( const TQString& type, const TQString& subResource, - const TQString& label, bool writable, - bool alarmRelevant ); - void fromKMailDelSubresource( const TQString& type, const TQString& subResource ); - - void fromKMailAsyncLoadResult( const TQMap<TQ_UINT32, TQString>& map, - const TQString& type, - const TQString& folder ); - - /** Return the list of subresources. */ - TQStringList subresources() const; - - bool canHaveSubresources() const { return true; } - - /** Is this subresource active? */ - bool subresourceActive( const TQString& ) const; - /** (De)activate the subresource */ - virtual void setSubresourceActive( const TQString &, bool ); - - /** Is this subresource writable? */ - bool subresourceWritable( const TQString& ) const; - - /** What is the label for this subresource? */ - virtual const TQString labelForSubresource( const TQString& resource ) const; - - virtual TQString subresourceIdentifier( Incidence *incidence ); - - virtual bool addSubresource( const TQString& resource, const TQString& parent ); - virtual bool removeSubresource( const TQString& resource ); - - virtual TQString subresourceType( const TQString &resource ); - - KABC::Lock* lock(); - - void beginAddingIncidences(); - - void endAddingIncidences(); - -signals: - void useGlobalMode(); -protected slots: - void slotEmitResourceChanged(); - void writeConfig(); - -protected: - /** - * Return list of alarms which are relevant for the current user. These - * are the ones coming from folders which the user has "Administer" rights - * for, as per ACL */ - KCal::Alarm::List relevantAlarms( const KCal::Alarm::List &alarms ); - -private: - void removeIncidences( const TQCString& incidenceType ); - void resolveConflict( KCal::Incidence*, const TQString& subresource, TQ_UINT32 sernum ); - void addIncidence( const char* mimetype, const TQString& xml, - const TQString& subResource, TQ_UINT32 sernum ); - - - /** - Caller guarantees i is not null. - */ - bool addIncidence( KCal::Incidence *i, const TQString& subresource, - TQ_UINT32 sernum ); - - void addEvent( const TQString& xml, const TQString& subresource, - TQ_UINT32 sernum ); - void addTodo( const TQString& xml, const TQString& subresource, - TQ_UINT32 sernum ); - void addJournal( const TQString& xml, const TQString& subresource, - TQ_UINT32 sernum ); - - - bool loadAllEvents(); - bool loadAllTodos(); - bool loadAllJournals(); - - bool doLoadAll( Kolab::ResourceMap& map, const char* mimetype ); - - /// Reimplemented from IncidenceBase::Observer to know when an incidence was changed - void incidenceUpdated( KCal::IncidenceBase* ); - void incidenceUpdatedSilent( KCal::IncidenceBase* incidencebase); - - bool openResource( TDEConfig& config, const char* contentType, - Kolab::ResourceMap& map ); - void loadSubResourceConfig( TDEConfig& config, const TQString& name, - const TQString& label, bool writable, - bool alarmRelevant, Kolab::ResourceMap& subResource ); - bool loadSubResource( const TQString& subResource, const char* mimetype ); - bool unloadSubResource( const TQString& subResource ); - - TQString configFile() const { - return ResourceKolabBase::configFile( "kcal" ); - } - - Kolab::ResourceMap* subResourceMap( const TQString& contentsType ); - - bool sendKMailUpdate( KCal::IncidenceBase* incidence, const TQString& _subresource, - TQ_UINT32 sernum ); - - - KCal::CalendarLocal mCalendar; - - // The list of subresources - Kolab::ResourceMap mEventSubResources, mTodoSubResources, mJournalSubResources; - - bool mOpen; // If the resource is open, this is true - TQDict<KCal::IncidenceBase> mPendingUpdates; - TQTimer mResourceChangedTimer; - ICalFormat mFormat; - - /** - This map contains the association between a new added incidence - and the subresource it belongs to. - That's needed to return the correct mapping in subresourceIdentifier(). - - We can't trust on mUidMap here, because it contains only non-pending uids. - */ - TQMap<TQString, TQString> mNewIncidencesMap; - int mProgressDialogIncidenceLimit; - - /** - * If a user has a subresource for viewing another user's folder then it can happen - * that addIncidence(...) adds an incidence with an already existing UID. - * - * When this happens, addIncidence(...) sets a new random UID and stores the - * original UID using incidence->setSchedulingID(uid) because KCal doesn't - * allow two incidences to have the same UID. - * - * This map keeps track of the generated UIDs (which are local) so we can delete the - * right incidence inside fromKMailDelIncidence(...) whenever we sync. - * - * The key is originalUID,subResource and the value is the fake UID. - */ - TQMap< TQPair<TQString, TQString>, TQString > mOriginalUID2fakeUID; - - bool mBatchAddingInProgress; - TQMap<Kolab::ResourceType,TQString> mLastUsedResources; - - /** - Indexed by uid, it holds the last known revision of an incidence. - If we receive an update where the incidence still has the same - revision as the last known, we ignore it and don't send it to kmail, - because shortly after, IncidenceChanger will increment the revision - and that will trigger another update. - - If we didn't discard the first update, kmail would have been updated twice. - */ - TQMap<TQString,int> mLastKnownRevisions; - -}; - -struct TemporarySilencer { - TemporarySilencer( ResourceKolab *_resource ) - { - resource = _resource; - oldValue = resource->mSilent; - resource->mSilent = true; - } - ~TemporarySilencer() - { - resource->mSilent = oldValue; - } - ResourceKolab *resource; - bool oldValue; -}; - -} - -#endif // KCAL_RESOURCEKOLAB_H diff --git a/kresources/kolab/kcal/resourcekolab_plugin.cpp b/kresources/kolab/kcal/resourcekolab_plugin.cpp deleted file mode 100644 index eb56897ae..000000000 --- a/kresources/kolab/kcal/resourcekolab_plugin.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - This file is part of libkabc and/or kaddressbook. - Copyright (c) 2002 - 2004 Klarälvdalens Datakonsult AB - <info@klaralvdalens-datakonsult.se> - - 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 "resourcekolab.h" - -class KolabFactory : public KRES::PluginFactoryBase -{ -public: - KRES::Resource *resource( const TDEConfig *config ) - { - return new KCal::ResourceKolab( config ); - } - - KRES::ConfigWidget *configWidget( TQWidget* ) - { - return 0; - } -}; - -K_EXPORT_COMPONENT_FACTORY(kcal_kolab,KolabFactory) diff --git a/kresources/kolab/kcal/task.cpp b/kresources/kolab/kcal/task.cpp deleted file mode 100644 index fe75845db..000000000 --- a/kresources/kolab/kcal/task.cpp +++ /dev/null @@ -1,461 +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 "task.h" - -#include <libkcal/todo.h> -#include <kdebug.h> - -using namespace Kolab; - -// Kolab Storage Specification: -// "The priority can be a number between 1 and 5, with 1 being the highest priority." -// iCalendar (RFC 2445): -// "The priority is specified as an integer in the range -// zero to nine. A value of zero specifies an -// undefined priority. A value of one is the -// highest priority. A value of nine is the lowest -// priority." - -static int kcalPriorityToKolab( const int kcalPriority ) -{ - if ( kcalPriority >= 0 && kcalPriority <= 9 ) { - // We'll map undefined (0) to 3 (default) - // 0 1 2 3 4 5 6 7 8 9 - static const int priorityMap[10] = { 3, 1, 1, 2, 2, 3, 3, 4, 4, 5 }; - return priorityMap[kcalPriority]; - } - else { - kdWarning() << "kcalPriorityToKolab(): Got invalid priority " << kcalPriority << endl; - return 3; - } -} - -static int kolabPrioritytoKCal( const int kolabPriority ) -{ - if ( kolabPriority >= 1 && kolabPriority <= 5 ) { - // 1 2 3 4 5 - static const int priorityMap[5] = { 1, 3, 5, 7, 9 }; - return priorityMap[kolabPriority - 1]; - } - else { - kdWarning() << "kolabPrioritytoKCal(): Got invalid priority " << kolabPriority << endl; - return 5; - } -} - -KCal::Todo* Task::xmlToTask( const TQString& xml, const TQString& tz, KCal::ResourceKolab *res, - const TQString& subResource, TQ_UINT32 sernum ) -{ - Task task( res, subResource, sernum, tz ); - task.load( xml ); - KCal::Todo* todo = new KCal::Todo(); - task.saveTo( todo ); - return todo; -} - -TQString Task::taskToXML( KCal::Todo* todo, const TQString& tz ) -{ - Task task( 0, TQString(), 0, tz, todo ); - return task.saveXML(); -} - -Task::Task( KCal::ResourceKolab *res, const TQString &subResource, TQ_UINT32 sernum, - const TQString& tz, KCal::Todo* task ) - : Incidence( res, subResource, sernum, tz ), - mPriority( 5 ), mPercentCompleted( 0 ), - mStatus( KCal::Incidence::StatusNone ), - mHasStartDate( false ), mHasDueDate( false ), - mHasCompletedDate( false ) -{ - if ( task ) - setFields( task ); -} - -Task::~Task() -{ -} - -void Task::setPriority( int priority ) -{ - mPriority = priority; -} - -int Task::priority() const -{ - return mPriority; -} - -void Task::setPercentCompleted( int percent ) -{ - mPercentCompleted = percent; -} - -int Task::percentCompleted() const -{ - return mPercentCompleted; -} - -void Task::setStatus( KCal::Incidence::Status status ) -{ - mStatus = status; -} - -KCal::Incidence::Status Task::status() const -{ - return mStatus; -} - -void Task::setParent( const TQString& parentUid ) -{ - mParent = parentUid; -} - -TQString Task::parent() const -{ - return mParent; -} - -void Task::setDueDate( const TQDateTime& date ) -{ - mDueDate = date; - mHasDueDate = true; - mFloatingStatus = HasTime; -} - -void Task::setDueDate( const TQDate &date ) -{ - mDueDate = date; - mHasDueDate = true; - mFloatingStatus = AllDay; -} - - -void Task::setDueDate( const TQString &date ) -{ - if ( date.length() > 10 ) { - // This is a date + time - setDueDate( stringToDateTime( date ) ); - } else { - // This is only a date - setDueDate( stringToDate( date ) ); - } -} - -TQDateTime Task::dueDate() const -{ - return mDueDate; -} - -void Task::setHasStartDate( bool v ) -{ - mHasStartDate = v; -} - -bool Task::hasStartDate() const -{ - return mHasStartDate; -} - -bool Task::hasDueDate() const -{ - return mHasDueDate; -} - -void Task::setCompletedDate( const TQDateTime& date ) -{ - mCompletedDate = date; - mHasCompletedDate = true; -} - -TQDateTime Task::completedDate() const -{ - return mCompletedDate; -} - -bool Task::hasCompletedDate() const -{ - return mHasCompletedDate; -} - -bool Task::loadAttribute( TQDomElement& element ) -{ - TQString tagName = element.tagName(); - - if ( tagName == "priority" ) { - bool ok; - mKolabPriorityFromDom = element.text().toInt( &ok ); - if ( !ok || mKolabPriorityFromDom < 1 || mKolabPriorityFromDom > 5 ) { - kdWarning() << "loadAttribute(): Invalid \"priority\" value: " << element.text() << endl; - mKolabPriorityFromDom = -1; - } - } else if ( tagName == "x-kcal-priority" ) { - bool ok; - mKCalPriorityFromDom = element.text().toInt( &ok ); - if ( !ok || mKCalPriorityFromDom < 0 || mKCalPriorityFromDom > 9 ) { - kdWarning() << "loadAttribute(): Invalid \"x-kcal-priority\" value: " << element.text() << endl; - mKCalPriorityFromDom = -1; - } - } else if ( tagName == "completed" ) { - bool ok; - int percent = element.text().toInt( &ok ); - if ( !ok || percent < 0 || percent > 100 ) - percent = 0; - setPercentCompleted( percent ); - } else if ( tagName == "status" ) { - if ( element.text() == "in-progress" ) - setStatus( KCal::Incidence::StatusInProcess ); - else if ( element.text() == "completed" ) - setStatus( KCal::Incidence::StatusCompleted ); - else if ( element.text() == "waiting-on-someone-else" ) - setStatus( KCal::Incidence::StatusNeedsAction ); - else if ( element.text() == "deferred" ) - // Guessing a status here - setStatus( KCal::Incidence::StatusCanceled ); - else - // Default - setStatus( KCal::Incidence::StatusNone ); - } else if ( tagName == "due-date" ) { - setDueDate( element.text() ); - } else if ( tagName == "parent" ) { - setParent( element.text() ); - } else if ( tagName == "x-completed-date" ) { - setCompletedDate( stringToDateTime( element.text() ) ); - } else if ( tagName == "start-date" ) { - setHasStartDate( true ); - setStartDate( element.text() ); - } else - return Incidence::loadAttribute( element ); - - // We handled this - return true; -} - -bool Task::saveAttributes( TQDomElement& element ) const -{ - // Save the base class elements - Incidence::saveAttributes( element ); - - // We need to save x-kcal-priority as well, since the Kolab priority can only save values from - // 1 to 5, but we have values from 0 to 9, and do not want to loose them - writeString( element, "priority", TQString::number( kcalPriorityToKolab( priority() ) ) ); - writeString( element, "x-kcal-priority", TQString::number( priority() ) ); - - writeString( element, "completed", TQString::number( percentCompleted() ) ); - - switch( status() ) { - case KCal::Incidence::StatusInProcess: - writeString( element, "status", "in-progress" ); - break; - case KCal::Incidence::StatusCompleted: - writeString( element, "status", "completed" ); - break; - case KCal::Incidence::StatusNeedsAction: - writeString( element, "status", "waiting-on-someone-else" ); - break; - case KCal::Incidence::StatusCanceled: - writeString( element, "status", "deferred" ); - break; - case KCal::Incidence::StatusNone: - writeString( element, "status", "not-started" ); - break; - case KCal::Incidence::StatusTentative: - case KCal::Incidence::StatusConfirmed: - case KCal::Incidence::StatusDraft: - case KCal::Incidence::StatusFinal: - case KCal::Incidence::StatusX: - // All of these are saved as StatusNone. - writeString( element, "status", "not-started" ); - break; - } - - if ( hasDueDate() ) { - if ( mFloatingStatus == HasTime ) { - writeString( element, "due-date", dateTimeToString( dueDate() ) ); - } else { - writeString( element, "due-date", dateToString( dueDate().date() ) ); - } - } - - if ( !parent().isNull() ) { - writeString( element, "parent", parent() ); - } - - if ( hasCompletedDate() && percentCompleted() == 100 ) { - writeString( element, "x-completed-date", dateTimeToString( completedDate() ) ); - } - - return true; -} - - -bool Task::loadXML( const TQDomDocument& document ) -{ - mKolabPriorityFromDom = -1; - mKCalPriorityFromDom = -1; - - TQDomElement top = document.documentElement(); - - if ( top.tagName() != "task" ) { - tqWarning( "XML error: Top tag was %s instead of the expected task", - top.tagName().ascii() ); - return false; - } - setHasStartDate( false ); // todo's don't necessarily have one - - for ( TQDomNode n = top.firstChild(); !n.isNull(); n = n.nextSibling() ) { - if ( n.isComment() ) - continue; - if ( n.isElement() ) { - TQDomElement e = n.toElement(); - if ( !loadAttribute( e ) ) - // 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; - } - - loadAttachments(); - decideAndSetPriority(); - return true; -} - -TQString Task::saveXML() const -{ - TQDomDocument document = domTree(); - TQDomElement element = document.createElement( "task" ); - element.setAttribute( "version", "1.0" ); - saveAttributes( element ); - if ( !hasStartDate() && startDate().isValid() ) { - // events and journals always have a start date, but tasks don't. - // Remove the entry done by the inherited save above, because we - // don't have one. - TQDomNodeList l = element.elementsByTagName( "start-date" ); - Q_ASSERT( l.count() == 1 ); - element.removeChild( l.item( 0 ) ); - } - document.appendChild( element ); - return document.toString(); -} - -void Task::setFields( const KCal::Todo* task ) -{ - Incidence::setFields( task ); - - setPriority( task->priority() ); - setPercentCompleted( task->percentComplete() ); - setStatus( task->status() ); - setHasStartDate( task->hasStartDate() ); - - if ( task->hasDueDate() ) { - setDueDate( localToUTC( task->dtDue() ) ); - if ( task->doesFloat() ) { - // This is a floating task. Don't timezone move this one - mFloatingStatus = AllDay; - setDueDate( task->dtDue().date() ); - } else { - mFloatingStatus = HasTime; - setDueDate( localToUTC( task->dtDue() ) ); - } - } else { - mHasDueDate = false; - } - - if ( task->relatedTo() ) { - setParent( task->relatedTo()->uid() ); - } else if ( !task->relatedToUid().isEmpty() ) { - setParent( task->relatedToUid( ) ); - } else { - setParent( TQString() ); - } - - if ( task->hasCompletedDate() && task->percentComplete() == 100 ) { - setCompletedDate( localToUTC( task->completed() ) ); - } else { - mHasCompletedDate = false; - } -} - -void Task::decideAndSetPriority() -{ - // If we have both Kolab and KCal values in the XML, we prefer the KCal value, but only if the - // values are still in sync - if ( mKolabPriorityFromDom != -1 && mKCalPriorityFromDom != -1 ) { - const bool inSync = ( kcalPriorityToKolab( mKCalPriorityFromDom ) == mKolabPriorityFromDom ); - if ( inSync ) { - setPriority( mKCalPriorityFromDom ); - } - else { - // Out of sync, some other client changed the Kolab priority, so we have to ignore our - // KCal priority - setPriority( kolabPrioritytoKCal( mKolabPriorityFromDom ) ); - } - } - - // Only KCal priority set, use that. - else if ( mKolabPriorityFromDom == -1 && mKCalPriorityFromDom != -1 ) { - kdWarning() << "decideAndSetPriority(): No Kolab priority found, only the KCal priority!" << endl; - setPriority( mKCalPriorityFromDom ); - } - - // Only Kolab priority set, use that - else if ( mKolabPriorityFromDom != -1 && mKCalPriorityFromDom == -1 ) { - setPriority( kolabPrioritytoKCal( mKolabPriorityFromDom ) ); - } - - // No priority set, use the default - else { - // According the RFC 2445, we should use 0 here, for undefined priority, but AFAIK KOrganizer - // doesn't support that, so we'll use 5. - setPriority( 5 ); - } -} - -void Task::saveTo( KCal::Todo* task ) -{ - Incidence::saveTo( task ); - - task->setPriority( priority() ); - task->setPercentComplete( percentCompleted() ); - task->setStatus( status() ); - task->setHasStartDate( hasStartDate() ); - task->setHasDueDate( hasDueDate() ); - if ( hasDueDate() ) - task->setDtDue( utcToLocal( dueDate() ) ); - - if ( !parent().isNull() ) - task->setRelatedToUid( parent() ); - - if ( hasCompletedDate() && task->percentComplete() == 100 ) - task->setCompleted( utcToLocal( mCompletedDate ) ); -} diff --git a/kresources/kolab/kcal/task.h b/kresources/kolab/kcal/task.h deleted file mode 100644 index 38a12a70e..000000000 --- a/kresources/kolab/kcal/task.h +++ /dev/null @@ -1,143 +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. -*/ - -#ifndef KOLAB_TASK_H -#define KOLAB_TASK_H - -#include <incidence.h> - -#include <libkcal/incidence.h> - -class TQDomElement; - -namespace KCal { - class Todo; - class ResourceKolab; -} - -namespace Kolab { - -/** - * This class represents a task, and knows how to load/save it - * from/to XML, and from/to a KCal::Todo. - * The instances of this class are temporary, only used to convert - * one to the other. - */ -class Task : public Incidence { -public: - /// Use this to parse an xml string to a task entry - /// The caller is responsible for deleting the returned task - static KCal::Todo* xmlToTask( const TQString& xml, const TQString& tz, KCal::ResourceKolab *res = 0, - const TQString& subResource = TQString(), TQ_UINT32 sernum = 0 ); - - /// Use this to get an xml string describing this task entry - static TQString taskToXML( KCal::Todo*, const TQString& tz ); - - explicit Task( KCal::ResourceKolab *res, const TQString& subResource, TQ_UINT32 sernum, - const TQString& tz, KCal::Todo* todo = 0 ); - virtual ~Task(); - - virtual TQString type() const { return "Task"; } - - void saveTo( KCal::Todo* todo ); - - virtual void setPriority( int priority ); - virtual int priority() const; - - virtual void setPercentCompleted( int percent ); - virtual int percentCompleted() const; - - virtual void setStatus( KCal::Incidence::Status status ); - virtual KCal::Incidence::Status status() const; - - virtual void setParent( const TQString& parentUid ); - virtual TQString parent() const; - - virtual void setHasStartDate( bool ); - virtual bool hasStartDate() const; - - virtual void setDueDate( const TQDateTime &date ); - virtual void setDueDate( const TQString &date ); - virtual void setDueDate( const TQDate &date ); - virtual TQDateTime dueDate() const; - virtual bool hasDueDate() const; - - virtual void setCompletedDate( const TQDateTime& date ); - virtual TQDateTime completedDate() const; - virtual bool hasCompletedDate() const; - - // Load the attributes of this class - virtual bool loadAttribute( TQDomElement& ); - - // Save the attributes of this class - virtual bool saveAttributes( TQDomElement& ) const; - - // Load this task by reading the XML file - virtual bool loadXML( const TQDomDocument& xml ); - - // Serialize this task to an XML string - virtual TQString saveXML() const; - -protected: - // Read all known fields from this ical todo - void setFields( const KCal::Todo* ); - - // This sets the priority of this task by looking at mKolabPriorityFromDom and - // mKCalPriorityFromDom. - void decideAndSetPriority(); - - // This is the KCal priority, not the Kolab priority. - // See kcalPriorityToKolab() and kolabPrioritytoKCal(). - int mPriority; - - // Those priority values are the raw values read by loadAttribute(). - // They will be converted later in decideAndSetPriority(). - int mKolabPriorityFromDom; - int mKCalPriorityFromDom; - - int mPercentCompleted; - KCal::Incidence::Status mStatus; - TQString mParent; - - bool mHasStartDate; - - bool mHasDueDate; - TQDateTime mDueDate; - - bool mHasCompletedDate; - TQDateTime mCompletedDate; -}; - -} - -#endif // KOLAB_TASK_H |