summaryrefslogtreecommitdiffstats
path: root/kresources/newexchange
diff options
context:
space:
mode:
Diffstat (limited to 'kresources/newexchange')
-rw-r--r--kresources/newexchange/Incidence.mapping177
-rw-r--r--kresources/newexchange/Makefile.am45
-rw-r--r--kresources/newexchange/Person.mapping184
-rw-r--r--kresources/newexchange/exchangeaddressbookadaptor.cpp95
-rw-r--r--kresources/newexchange/exchangeaddressbookadaptor.h102
-rw-r--r--kresources/newexchange/exchangecalendaradaptor.cpp183
-rw-r--r--kresources/newexchange/exchangecalendaradaptor.h99
-rw-r--r--kresources/newexchange/exchangeconvertercalendar.cpp820
-rw-r--r--kresources/newexchange/exchangeconvertercalendar.h63
-rw-r--r--kresources/newexchange/exchangeconvertercontact.cpp615
-rw-r--r--kresources/newexchange/exchangeconvertercontact.h53
-rw-r--r--kresources/newexchange/exchangeglobals.cpp286
-rw-r--r--kresources/newexchange/exchangeglobals.h70
-rw-r--r--kresources/newexchange/kabc_newexchange.desktop52
-rw-r--r--kresources/newexchange/kabc_newexchange_final.desktop49
-rw-r--r--kresources/newexchange/kabc_resourceexchange.cpp48
-rw-r--r--kresources/newexchange/kabc_resourceexchange.h42
-rw-r--r--kresources/newexchange/kabc_resourceexchange_plugin.cpp27
-rw-r--r--kresources/newexchange/kcal_newexchange.desktop52
-rw-r--r--kresources/newexchange/kcal_newexchange_final.desktop49
-rw-r--r--kresources/newexchange/kcal_resourceexchange.cpp54
-rw-r--r--kresources/newexchange/kcal_resourceexchange.h45
-rw-r--r--kresources/newexchange/kcal_resourceexchange_plugin.cpp28
23 files changed, 3238 insertions, 0 deletions
diff --git a/kresources/newexchange/Incidence.mapping b/kresources/newexchange/Incidence.mapping
new file mode 100644
index 000000000..ef0914b56
--- /dev/null
+++ b/kresources/newexchange/Incidence.mapping
@@ -0,0 +1,177 @@
+GENERAL Properties (for all types):
+===================================
+
+WebDAV property | Incidence:: method
+---------------------------------------------+----------------------
+DAV:contentclass | "urn:content-classes:appointment" / :task / :message
+DAV:getcontenttype | "message/rfc822"
+http://schemas.microsoft.com/mapi/proptag/0x001A001F | "IPM.Appointment" / .Task / .Journal/.Post
+http://schemas.microsoft.com/exchange/outlookmessageclass | "IPM.Appointment"
+DAV:getetag | FINGERPRINT
+DAV:href | CUSTOM
+DAV:creationdate | created()
+DAV:getlastmodified | lastModified()
+DAV:isreadonly | isReadOnly()
+http://schemas.microsoft.com/repl/repl-uid | schedulingID()
+ |
+DAV:uid | uid()
+urn:schemas:mailheader:subject | summary()
+urn:schemas:httpmail:subject | summary() (welches der beiden?)
+urn:schemas:httpmail:textdescription | description()
+urn:schemas:httpmail:date | ? (datestamp, no method in libkcal!)
+DAV:comment | comments()
+ |
+urn:schemas-microsoft-com:office:office#Keywords | categories()
+ |
+http://schemas.microsoft.com/exchange/sensitivity | secrecy()
+urn:schemas:httpmail:priority | priority()
+ |
+urn:schemas:httpmail:from | organizer()
+urn:schemas:httpmail:to | attendees(), required
+urn:schemas:httpmail:cc | attendees(), optional
+ | resources ???
+ |
+urn:schemas:httpmail:hasattachment | attachments() ???
+
+
+
+
+Event:
+======
+See
+-) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_exch2k_urn_content-classes_appointment.asp
+-) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_cdo_schema_dav.asp
+-) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_cdo_schema_httpmail.asp
+
+h="http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/"
+
+
+WebDAV property | Incidence:: method
+---------------------------------------------+----------------------
+urn:schemas:calendar:created | created() ?, siehe DAV:creationdate
+urn:schemas:calendar:lastmodified | lastModified() ?, siehe DAV:getlastmodified
+urn:schemas:calendar:dtstamp | ??
+urn:schemas:calendar:sequence | revision()
+ |
+urn:schemas:calendar:location | location()
+ |
+//urn:schemas:calendar:organizer | organizer()
+//urn:schemas:calendar:method | ??
+//urn:schemas:calendar:responserequested | ??
+//urn:schemas:calendar:meetingstatus | ??
+//urn:schemas:calendar:replytime | ??
+
+urn:schemas:calendar:busystatus | status()
+urn:schemas:calendar:transparent | transparency(): Event::Transparent, Event::Opaque
+ |
+urn:schemas:calendar:timezone | ??
+urn:schemas:calendar:alldayevent | doesFloat()
+urn:schemas:calendar:dtstart | dtStart()
+urn:schemas:calendar:dtend | dtEnd()
+urn:schemas:calendar:duration | duration()
+ |
+urn:schemas:calendar:rrule | recurrence(), doesRecur()
+urn:schemas:calendar:rdate | --
+urn:schemas:calendar:exrule | --
+urn:schemas:calendar:exdate | recurrence()->exDates(), recurrence()->exDateTimes()
+urn:schemas:calendar:recurrenceid | recurrenceId() ?? (protected?)
+urn:schemas:calendar:instancetype | ??
+ |
+urn:schemas:calendar:reminderoffset | alarms()
+ |
+urn:schemas:calendar:resources | resources()
+ |
+? | custom items?
+
+
+No correspondence:
+==================
+urn:schemas:calendar:timezoneid
+urn:schemas:calendar:geolatitude
+urn:schemas:calendar:geolongitude
+urn:schemas:calendar:contacturl
+urn:schemas:calendar:descriptionurl
+urn:schemas:calendar:locationurl
+urn:schemas:httpmail:htmldescription
+urn:schemas:httpmail:priority
+urn:schemas:calendar:recurrenceidrange
+urn:schemas:contacts:billinginformation
+http://schemas.microsoft.com/exchange/companies
+http://schemas.microsoft.com/exchange/mileage
+urn:schemas:httpmail:normalizedsubject
+DAV:displayname
+DAV:id
+
+
+Incidence::pilotId()
+Incidence::syncStatus()
+Incidence::relatedToUid()
+
+
+
+
+
+Task:
+=====
+For the mapping of the MAPI properties and the hex codes to access them via
+WebDAV, see http://www.cdolive.com/cdo10.htm
+
+h1="http://schemas.microsoft.com/mapi/id/{00062003-0000-0000-C000-000000000046}/" (CdoPropSetID2)
+h2="http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/" (CdoPropSetID4)
+b='urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/'
+oder:
+b="urn:schemas-microsoft-com:datatypes"
+
+
+WebDAV property | Incidence:: method
+---------------------------------------------+----------------------
+?? -------------------------- | revision()
+----------------------------- | location()
+----------------------------- | status()
+----------------------------- | doesFloat()
+ |
+h1:0x00008104 b:dt="dateTime.tz" | dtStart() (or h2:0x00008516), z.B. 2003-09-11T18:45:00.00Z
+h1:0x00008105 b:dt="dateTime.tz" | dtDue() (or h2:0x00008517)
+h1:0x00008106 | duration()
+ |
+h1:0x0000811C b:dt="boolean" | isCompleted() (0/1)
+h1:0x00008102 b:dt='float' | percentComplete(), 0.0-1.0
+h1:0x0000810f b:dt="dateTime.tz" | completed()
+----------------------------- | hasCompletedDate()
+ |
+h1:0x00008126 b:dt="boolean" | doesRecur()
+----------------------------- | recurrence()
+----------------------------- | recurrence()->exDates(), recurrence()->exDateTimes()
+----------------------------- | recurrenceId() ?? (protected?)
+ |
+h2:0x00008503 b:dt="boolean" (reminder set: 0/1) | alarms()
+h2:0x00008502 b:dt="dateTime.tz" | ? (reminder date/time)
+h2:0x0000851E | ReminderPlaySound
+h2:0x0000851F | ReminderSoundFile
+ |
+h1:0x00008101 b:dt='int' | status: 0_Open, 1_InProgress, 2_Completed, 3_WaitingForSomeoneElse, 4_Deferred
+ |
+
+
+No correspondence:
+==================
+Incidence::pilotId()
+Incidence::syncStatus()
+Incidence::relatedToUid()
+Incidence::custom()
+
+h1:0x00008103 TeamTask (b:dt="boolean")
+h1:0x00008110 ActualWork: In minutes
+h1:0x00008111 TotalWork: In minutes
+h1:0x00008129 assignment
+
+
+Journal:
+========
+
+#define E2K_NS_OUTLOOK_JOURNAL E2K_NS_MAPI_ID "{0006200A-0000-0000-C000-000000000046}/"
+
+WebDAV property | Journal:: method
+----------------------------------------------------------+---------------------------------
+urn:schemas:httpmail:importance | ?
+urn:schemas:httpmail:date | dtStart()
diff --git a/kresources/newexchange/Makefile.am b/kresources/newexchange/Makefile.am
new file mode 100644
index 000000000..317e9863c
--- /dev/null
+++ b/kresources/newexchange/Makefile.am
@@ -0,0 +1,45 @@
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/kresources/lib \
+ -I$(top_builddir)/kresources/lib $(all_includes)
+
+lib_LTLIBRARIES = libkabc_newexchange.la libkcal_newexchange.la
+noinst_LTLIBRARIES = libknewexchange.la
+
+libknewexchange_la_SOURCES = exchangeglobals.cpp exchangeconvertercalendar.cpp exchangeconvertercontact.cpp
+
+libkcal_newexchange_la_SOURCES = exchangecalendaradaptor.cpp kcal_resourceexchange.cpp
+libkcal_newexchange_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) \
+ -version-info 1:0:0 -no-undefined
+libkcal_newexchange_la_LIBADD = \
+ libknewexchange.la ../lib/libkgroupwaredav.la \
+ $(top_builddir)/libkcal/libkcal.la $(top_builddir)/libkdepim/libkdepim.la \
+ -lkabc
+
+libkabc_newexchange_la_SOURCES = kabc_resourceexchange.cpp exchangeaddressbookadaptor.cpp
+libkabc_newexchange_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) \
+ -version-info 1:0:0 -no-undefined
+libkabc_newexchange_la_LIBADD = \
+ libknewexchange.la ../lib/libkgroupwaredav.la \
+ $(top_builddir)/libkcal/libkcal.la $(top_builddir)/libkdepim/libkdepim.la \
+ -lkabc
+
+kde_module_LTLIBRARIES = kcal_newexchange.la kabc_newexchange.la
+
+kcal_newexchange_la_SOURCES = kcal_resourceexchange_plugin.cpp
+kcal_newexchange_la_LDFLAGS = $(all_libraries) -module -no-undefined $(KDE_PLUGIN)
+kcal_newexchange_la_LIBADD = libkcal_newexchange.la
+
+kabc_newexchange_la_SOURCES = kabc_resourceexchange_plugin.cpp
+kabc_newexchange_la_LDFLAGS = $(all_libraries) -module -no-undefined $(KDE_PLUGIN)
+kabc_newexchange_la_LIBADD = libkabc_newexchange.la
+
+
+kcal_servicedir = $(kde_servicesdir)/kresources/kcal
+kcal_service_DATA = kcal_newexchange.desktop
+
+kabc_servicedir = $(kde_servicesdir)/kresources/kabc
+kabc_service_DATA = kabc_newexchange.desktop
+
+METASOURCES = AUTO
+
+kcal_resourceexchange.lo kabc_resourceexchange.lo: ../lib/kresources_groupwareprefs.h
+
diff --git a/kresources/newexchange/Person.mapping b/kresources/newexchange/Person.mapping
new file mode 100644
index 000000000..d7571e773
--- /dev/null
+++ b/kresources/newexchange/Person.mapping
@@ -0,0 +1,184 @@
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_cdo_schema_contacts_c.asp
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/e2k3/e2k3/_exch2k_urn_content-classes_person.asp
+
+/* KDE4: addressee does not have any creation or modification date :-(( */
+/* KDE4: read-only not supported by libkabc */
+
+WebDAV property | Addressee:: method
+---------------------------------------------+----------------------
+DAV:contentclass | "urn:content-classes:appointment"
+http://schemas.microsoft.com/exchange/outlookmessageclass | "IPM.Contact"
+DAV:getetag | FINGERPRINT
+DAV:href | CUSTOM
+DAV:creationdate | created()
+DAV:getlastmodified | lastModified()
+DAV:isreadonly | isReadOnly()
+//urn:schemas:calendar:dtstamp | ??
+//urn:schemas:calendar:sequence | revision()
+//http://schemas.microsoft.com/repl/uid | schedulingID()
+
+urn:schemas:contacts:cn | uid()
+urn:schemas:contacts:uid | uid()
+ |
+urn:schemas:contacts:fileas (niceName) | formattedName()
+//urn:schemas:contacts:cn | formattedName()
+urn:schemas:contacts:givenName | givenName()
+urn:schemas:contacts:initials | -
+urn:schemas:contacts:middlename | additionalName()
+urn:schemas:contacts:namesuffix | suffix()
+urn:schemas:contacts:personaltitle | prefix()
+urn:schemas:contacts:sn (surname) | familyName()
+ |
+urn:schemas:contacts:title | role() / title()
+ |
+urn:schemas:contacts:o (org.) | organization()
+urn:schemas:contacts:department | custom( "KADDRESSBOOK", "X-Department" )
+urn:schemas:contacts:roomnumber | custom( "KADDRESSBOOK", "X-Office" )
+urn:schemas:contacts:profession | custom( "KADDRESSBOOK", "X-Profession" )
+urn:schemas:contacts:manager | custom( "KADDRESSBOOK", "X-ManagersName" )
+urn:schemas:contacts:secretarycn | custom( "KADDRESSBOOK", "X-AssistantsName" )
+ |
+urn:schemas:contacts:email1 | emails();
+urn:schemas:contacts:email2 | -"-
+urn:schemas:contacts:email3 | -"-
+ |
+urn:schemas:contacts:personalHomePage | -
+urn:schemas:contacts:businesshomepage | url()
+ |
+urn:schemas:calendar:fburl | KCal::FreeBusyUrlStore::self()->readUrl( addr.preferredEmail() )
+ |
+urn:schemas-microsoft-com:office:office#Keywords | categories()
+ |
+DAV:sensitivity | secrecy()
+ |
+urn:schemas:contacts:telephoneNumber | phoneNumber( Home )
+urn:schemas:contacts:telephonenumber2 | phoneNumber( Home )
+urn:schemas:contacts:officetelephonenumber | phoneNumber( Work )
+urn:schemas:contacts:office2telephonenumber | phoneNumber( Work )
+urn:schemas:contacts:secretaryphone | phoneNumber( Work )
+urn:schemas:contacts:organizationmainphone | phoneNumber( Work )
+urn:schemas:contacts:otherTelephone | phoneNumber( )
+urn:schemas:contacts:homePhone | phoneNumber( Home )
+urn:schemas:contacts:homephone2 | phoneNumber( Home )
+urn:schemas:contacts:mobile | phoneNumber( Cell | Pref )
+urn:schemas:contacts:othermobile | phoneNumber( Cell )
+urn:schemas:contacts:facsimiletelephonenumber| phoneNumber( Fax )
+urn:schemas:contacts:homefax | phoneNumber( Fax | Home )
+urn:schemas:contacts:otherfax | phoneNumber( Fax | Work)
+urn:schemas:contacts:pager | phoneNumber( Pager | Work )
+urn:schemas:contacts:otherpager | phoneNumber( Pager )
+urn:schemas:contacts:internationalisdnnumber |
+ (isdn number) | phoneNumber( Isdn )
+urn:schemas:contacts:callbackphone | phoneNumber( Msg )
+urn:schemas:contacts:telexnumber | phoneNumber( Bbs )
+urn:schemas:contacts:ttytddphone | phoneNumber( Pcs )
+ |
+ |
+// work address: |
+urn:schemas:contacts:workaddress | address(Work|Pref).
+urn:schemas:contacts:street | address(Work|Pref).street()
+urn:schemas:contacts:postofficebox | address(Work|Pref).postOfficeBox()
+urn:schemas:contacts:l (city) | address(Work|Pref).locality()
+urn:schemas:contacts:postalcode | address(Work|Pref).postalCode()
+urn:schemas:contacts:st (work state) | address(Work|Pref).region()
+urn:schemas:contacts:co (full ctry/region) | address(Work|Pref).country()
+urn:schemas:contacts:c (ctry/region abbrev.)| address(Work|Pref).countryCode()
+ |
+// home address: |
+urn:schemas:contacts:homepostaladdress | address(Home).
+urn:schemas:contacts:homeStreet | address(Home).street()
+urn:schemas:contacts:homepostofficebox | address(Home).postOfficeBox()
+urn:schemas:contacts:homeCity | address(Home).locality()
+urn:schemas:contacts:homePostalCode | address(Home).postalCode()
+urn:schemas:contacts:homeState | address(Home).region()
+urn:schemas:contacts:homeCountry | address(Home).country()
+urn:schemas:contacts:homeCountrycode | address(Home).countryCode()
+ |
+// mailing address: |
+urn:schemas:contacts:mailingpostaladdress | address(Postal).
+urn:schemas:contacts:mailingstreet | address(Postal).street()
+urn:schemas:contacts:mailingpostofficebox | address(Postal).postOfficeBox()
+urn:schemas:contacts:mailingcity | address(Postal).locality()
+urn:schemas:contacts:mailingpostalcode | address(Postal).postalCode()
+urn:schemas:contacts:mailingstate | address(Postal).region()
+urn:schemas:contacts:mailingcountry | address(Postal).country()
+urn:schemas:contacts:mailingcountrycode | address(Postal).countryCode()
+ |
+// other address: |
+urn:schemas:contacts:otherpostaladdress | address().
+urn:schemas:contacts:otherstreet | address().street()
+urn:schemas:contacts:otherpostofficebox | address().postOfficeBox()
+urn:schemas:contacts:othercity | address().locality()
+urn:schemas:contacts:otherpostalcode | address().postalCode()
+urn:schemas:contacts:otherstate | address().region()
+urn:schemas:contacts:othercountry | address().country()
+urn:schemas:contacts:othercountrycode | address().countryCode()
+ |
+ |
+urn:schemas:contacts:nickname | nickName()
+urn:schemas:contacts:spousecn | custom( "KADDRESSBOOK", "X-SpousesName" )
+ |
+urn:schemas:contacts:bday | birthday()
+urn:schemas:contacts:weddinganniversary | custom( "KADDRESSBOOK", "X-Anniversary" )
+ |
+? | timeZone()
+ |
+urn:schemas:calendar:geolatitude | geo()
+urn:schemas:calendar:geolongitude | geo()
+urn:schemas:contacts:mapurl | -
+urn:schemas:contacts:location | -
+ |
+urn:schemas:httpmail:textdescription | note()
+ |
+urn:schemas:contacts:usercertificate | keys()
+ |
+- | custom( app, name )
+ |
+// http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/0x00008025 | Journal
+// http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/0x00008056 | NetMeeting
+http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/0x00008062 | IM Address
+
+
+
+KABC::Addressee method not used:
+logo()
+photo()
+sound()
+agent()
+revision()
+productId()
+mailer()
+
+
+KABC::Address methods not used:
+id()
+type()
+extended ()
+
+
+ Not used:
+urn:schemas:contacts:computernetworkname
+urn:schemas:contacts:customerid
+urn:schemas:contacts:dn
+urn:schemas:contacts:employeenumber
+urn:schemas:contacts:fileasid
+urn:schemas:contacts:ftpsite
+urn:schemas:contacts:gender
+urn:schemas:contacts:governmentid
+urn:schemas:contacts:hobbies
+urn:schemas:contacts:homelatitude
+urn:schemas:contacts:homelongitude
+urn:schemas:contacts:hometimezone
+urn:schemas:contacts:language
+urn:schemas:contacts:mailingaddressid
+urn:schemas:contacts:othertimezone
+urn:schemas:contacts:proxyaddresses
+urn:schemas:contacts:referredby
+urn:schemas:contacts:secretaryurl
+urn:schemas:contacts:sourceurl
+urn:schemas:httpmail:hasattachment
+urn:schemas:httpmail:htmldescription
+urn:schemas:httpmail:outbox
+urn:schemas:httpmail:subject
+urn:schemas:mailheader:subject
+
diff --git a/kresources/newexchange/exchangeaddressbookadaptor.cpp b/kresources/newexchange/exchangeaddressbookadaptor.cpp
new file mode 100644
index 000000000..469d15c36
--- /dev/null
+++ b/kresources/newexchange/exchangeaddressbookadaptor.cpp
@@ -0,0 +1,95 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ 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.
+*/
+
+#include "exchangeaddressbookadaptor.h"
+#include "exchangeconvertercontact.h"
+#include <davgroupwareglobals.h>
+#include "exchangeglobals.h"
+#include <webdavhandler.h>
+#include <kdebug.h>
+#include <kio/davjob.h>
+
+using namespace KABC;
+
+ExchangeAddressBookUploadItem::ExchangeAddressBookUploadItem( AddressBookAdaptor *adaptor, KABC::Addressee addr, KPIM::GroupwareUploadItem::UploadType type )
+ : GroupwareUploadItem( type )
+{
+ if ( adaptor && !addr.isEmpty() ) {
+ mItemType = KPIM::FolderLister::Contact;
+
+ setUrl( addr.custom( adaptor->identifier(), "storagelocation" ) );
+ setUid( addr.uid() );
+
+ ExchangeConverterContact format;
+ mDavData = format.createWebDAV( addr );
+ }
+}
+
+KIO::TransferJob *ExchangeAddressBookUploadItem::createUploadJob( KPIM::GroupwareDataAdaptor *adaptor, const KURL &/*baseurl*/ )
+{
+kdDebug()<<"ExchangeAddressBookUploadItem::createUploadJob"<<endl;
+ Q_ASSERT( adaptor );
+ if ( !adaptor ) return 0;
+ KURL upUrl( url() );
+ adaptor->adaptUploadUrl( upUrl );
+ kdDebug() << "Uploading to: " << upUrl.prettyURL() << endl;
+ KIO::DavJob *job = KIO::davPropPatch( upUrl, mDavData, false );
+ return job;
+}
+
+KIO::TransferJob *ExchangeAddressBookUploadItem::createUploadNewJob( KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl )
+{
+kdDebug()<<"ExchangeAddressBookUploadItem::createUploadNewJob"<<endl;
+ KURL url( baseurl );
+ // TODO: Check that this URL doesn't exist yet
+ url.addPath( uid() + ".EML" );
+ setUrl( url );
+//url.addPath("newItem.EML");
+kdDebug()<<"Upload path: "<<url.url()<<endl;
+ return createUploadJob( adaptor, url );
+}
+
+ExchangeAddressBookAdaptor::ExchangeAddressBookAdaptor() : DavAddressBookAdaptor()
+{
+}
+
+void ExchangeAddressBookAdaptor::customAdaptDownloadUrl( KURL &url )
+{
+ url = WebdavHandler::toDAV( url );
+}
+
+void ExchangeAddressBookAdaptor::customAdaptUploadUrl( KURL &url )
+{
+ url = WebdavHandler::toDAV( url );
+// url.setPath( url.path() + "/NewItem.EML" );
+}
+
+QString ExchangeAddressBookAdaptor::defaultNewItemName( KPIM::GroupwareUploadItem *item ) {
+ if ( item ) return item->uid()+".EML";
+ else return QString::null;
+}
+
+
+KPIM::GroupwareUploadItem *ExchangeAddressBookAdaptor::newUploadItem( KABC::Addressee addr,
+ KPIM::GroupwareUploadItem::UploadType type )
+{
+ return new ExchangeAddressBookUploadItem( this, addr, type );
+}
diff --git a/kresources/newexchange/exchangeaddressbookadaptor.h b/kresources/newexchange/exchangeaddressbookadaptor.h
new file mode 100644
index 000000000..7d340bfb9
--- /dev/null
+++ b/kresources/newexchange/exchangeaddressbookadaptor.h
@@ -0,0 +1,102 @@
+ /*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+
+ 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.
+*/
+#ifndef KABC_EXCHANGEADDRESSBOOKADAPTOR_H
+#define KABC_EXCHANGEADDRESSBOOKADAPTOR_H
+
+#include "exchangeglobals.h"
+
+#include <groupwareresourcejob.h>
+#include <davaddressbookadaptor.h>
+
+#include <folderlister.h>
+
+#include <kabc/addressee.h>
+#include <kurl.h>
+#include <qdom.h>
+
+namespace KABC {
+
+class ExchangeAddressBookUploadItem : public KPIM::GroupwareUploadItem
+{
+ public:
+ ExchangeAddressBookUploadItem( AddressBookAdaptor *adaptor, KABC::Addressee addr, UploadType type );
+ virtual ~ExchangeAddressBookUploadItem() {}
+/**/ virtual KIO::TransferJob *createUploadJob(
+ KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl );
+/**/ virtual KIO::TransferJob *createUploadNewJob(
+ KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl );
+
+ protected:
+ ExchangeAddressBookUploadItem( UploadType type ) : KPIM::GroupwareUploadItem( type ) {}
+ QDomDocument mDavData;
+};
+
+class ExchangeAddressBookAdaptor : public DavAddressBookAdaptor
+{
+ public:
+ ExchangeAddressBookAdaptor();
+
+ void customAdaptDownloadUrl( KURL &url );
+ void customAdaptUploadUrl( KURL &url );
+ QString mimeType() const { return "message/rfc822"; }
+ QCString identifier() const { return "KABCResourceExchange"; }
+ QString defaultNewItemName( KPIM::GroupwareUploadItem *item );
+ long flags() const { return GWResBatchDelete; }
+
+
+
+ // Creating Jobs
+ KIO::Job *createListFoldersJob( const KURL &url )
+ { return ExchangeGlobals::createListFoldersJob( url ); }
+ KIO::TransferJob *createListItemsJob( const KURL &url )
+ { return ExchangeGlobals::createListItemsJob( url ); }
+ KIO::TransferJob *createDownloadJob( const KURL &url, KPIM::FolderLister::ContentType ctype )
+ { return ExchangeGlobals::createDownloadJob( this, url, ctype ); }
+ KIO::Job *createRemoveJob( const KURL &uploadurl, const KPIM::GroupwareUploadItem::List &deletedItems )
+ { return ExchangeGlobals::createRemoveJob( uploadurl, deletedItems ); }
+
+
+
+ // Interpreting Jobs
+ bool interpretListItemsJob( KIO::Job *job, const QString &jobData )
+ { return ExchangeGlobals::interpretListItemsJob( this, job, jobData ); }
+ bool interpretDownloadItemsJob( KIO::Job *job, const QString &jobData )
+ { return ExchangeGlobals::interpretAddressBookDownloadItemsJob( this, job, jobData ); }
+
+
+
+
+/**/ KPIM::GroupwareUploadItem *newUploadItem( KABC::Addressee addr,
+ KPIM::GroupwareUploadItem::UploadType type );
+
+
+
+
+ bool getFolderHasSubs( const QDomNode &folderNode )
+ { return ExchangeGlobals::getFolderHasSubs( folderNode ); }
+ KPIM::FolderLister::ContentType getContentType( const QDomNode &folderNode )
+ { return ExchangeGlobals::getContentType( folderNode ); }
+};
+
+}
+
+#endif
diff --git a/kresources/newexchange/exchangecalendaradaptor.cpp b/kresources/newexchange/exchangecalendaradaptor.cpp
new file mode 100644
index 000000000..254eb4da1
--- /dev/null
+++ b/kresources/newexchange/exchangecalendaradaptor.cpp
@@ -0,0 +1,183 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ 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.
+*/
+
+#include "exchangecalendaradaptor.h"
+#include "exchangeglobals.h"
+#include "exchangeconvertercalendar.h"
+#include <davgroupwareglobals.h>
+#include <webdavhandler.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kio/davjob.h>
+#include <libkcal/resourcecached.h>
+#include "davcalendaradaptor.h"
+
+using namespace KCal;
+
+ExchangeCalendarUploadItem::ExchangeCalendarUploadItem( CalendarAdaptor *adaptor, KCal::Incidence *incidence, KPIM::GroupwareUploadItem::UploadType type )
+ : GroupwareUploadItem( type )
+{
+ if ( incidence && adaptor ) {
+ if ( incidence->type() == "Event" ) mItemType = KPIM::FolderLister::Event;
+ else if ( incidence->type() == "Todo" ) mItemType = KPIM::FolderLister::Todo;
+ else if ( incidence->type() == "Journal" ) mItemType = KPIM::FolderLister::Journal;
+kdDebug()<<"mItemType=="<<mItemType<<endl;
+
+ setUrl( incidence->customProperty( adaptor->identifier(), "storagelocation" ) );
+ setUid( incidence->uid() );
+
+ ExchangeConverterCalendar format;
+ format.setTimeZone( adaptor->resource()->timeZoneId() );
+ mDavData = format.createWebDAV( incidence );
+ }
+}
+
+KIO::TransferJob *ExchangeCalendarUploadItem::createUploadJob( KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseUrl )
+{
+kdDebug()<<"ExchangeCalendarUploadItem::createUploadJob, adaptor="<<adaptor<<", URL="<<baseUrl.url()<<endl;
+ Q_ASSERT( adaptor );
+ if ( !adaptor ) return 0;
+ KURL upUrl( url() );
+ adaptor->adaptUploadUrl( upUrl );
+ kdDebug() << "Uploading to: " << upUrl.prettyURL() << endl;
+
+ KIO::DavJob *job = KIO::davPropPatch( upUrl, mDavData, false );
+ return job;
+}
+
+KIO::TransferJob *ExchangeCalendarUploadItem::createUploadNewJob( KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl )
+{
+kdDebug()<<"ExchangeCalendarUploadItem::createUploadNewJob"<<endl;
+ KURL url( baseurl );
+ // TODO: Check if this URL doesn't exist yet!
+ url.addPath( uid() + ".EML" );
+ setUrl( url );
+//url.addPath("newItem.EML");
+kdDebug()<<"Upload path: "<<url.url()<<endl;
+ return createUploadJob( adaptor, url );
+}
+
+
+
+ExchangeCalendarAdaptor::ExchangeCalendarAdaptor() : DavCalendarAdaptor()
+{
+ /* FIXME Set the progress item messages from the concrete job?*/
+ setDownloadProgressMessage( i18n( "Downloading items" ) );
+ setUploadProgressMessage( i18n( "Uploading items" ) );
+}
+
+void ExchangeCalendarAdaptor::customAdaptDownloadUrl( KURL &url )
+{
+ url = WebdavHandler::toDAV( url );
+}
+
+void ExchangeCalendarAdaptor::customAdaptUploadUrl( KURL &url )
+{
+ url = WebdavHandler::toDAV( url );
+// url.setPath( url.path() + "/NewItem.EML" );
+}
+
+
+/* Removing items: old version of the exchange resource: If the event is part
+ of a sequence of recurring event, we need to delete the master!
+void ExchangeDelete::findUidSingleMaster( QString const& uid )
+{
+ QString query =
+ "SELECT \"DAV:href\", \"urn:schemas:calendar:uid\"\r\n"
+ "FROM Scope('shallow traversal of \"\"')\r\n"
+ "WHERE \"urn:schemas:calendar:uid\" = '" + uid + "'\r\n"
+ " AND (\"urn:schemas:calendar:instancetype\" = 0\r\n"
+ " OR \"urn:schemas:calendar:instancetype\" = 1)\r\n";
+
+ KIO::DavJob* job = KIO::davSearch( mAccount->calendarURL(), "DAV:", "sql", query, false );
+ job->setWindow( mWindow );
+ connect(job, SIGNAL(result( KIO::Job * )), this, SLOT(slotFindUidResult(KIO::Job *)));
+}
+
+*/
+
+
+QString ExchangeCalendarAdaptor::defaultNewItemName( KPIM::GroupwareUploadItem *item ) {
+ if ( item ) return item->uid()+".EML";
+ else return QString::null;
+}
+
+KPIM::GroupwareUploadItem *ExchangeCalendarAdaptor::newUploadItem( KCal::Incidence*it,
+ KPIM::GroupwareUploadItem::UploadType type )
+{
+ return new ExchangeCalendarUploadItem( this, it, type );
+}
+
+bool ExchangeCalendarAdaptor::interpretUploadJob( KIO::Job *job, const QString &/*jobData*/ )
+{
+ kdDebug(7000) << "ExchangeCalendarAdaptor::interpretUploadJob " << endl;
+ KIO::DavJob *davjob = dynamic_cast<KIO::DavJob*>(job);
+ bool error = job->error();
+ const QString err = job->errorString();
+
+ if ( davjob ) {
+ if ( error ) {
+ emit itemUploadError( davjob->url(), err );
+ return false;
+ } else {
+ QDomDocument doc( davjob->response() );
+ // TODO: extract the href and the items that got a 404. If there's
+ // something important among them, issue the "usual" not-all-settings-uploaded
+ // warning to the user.
+
+ // We don't know the local id here (and we don't want to extract it from
+ // the idMapper, that's the task of the receiver
+ emit itemUploaded( uidFromJob( job ), davjob->url() );
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool ExchangeCalendarAdaptor::interpretUploadNewJob( KIO::Job *job, const QString &/*jobData*/ )
+{
+// TODO: How does the incidence mapper know the old/new ids???
+ kdDebug(7000) << "ExchangeCalendarAdaptor::interpretUploadNewJob " << endl;
+ KIO::DavJob *davjob = dynamic_cast<KIO::DavJob*>(job);
+ bool error = job->error();
+ const QString err = job->errorString();
+
+ if ( davjob ) {
+ if ( error ) {
+ emit itemUploadNewError( idMapper()->localId( davjob->url().path() ), err );
+ return false;
+ } else {
+ QDomDocument doc( davjob->response() );
+ // TODO: extract the href and the items that got a 404. If there's
+ // something important among them, issue the "usual" not-all-settings-uploaded
+ // warning to the user.
+
+ // We don't know the local id here (and we don't want to extract it from
+ // the idMapper, that's the task of the receiver
+ emit itemUploadedNew( uidFromJob( job ), davjob->url() );
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
diff --git a/kresources/newexchange/exchangecalendaradaptor.h b/kresources/newexchange/exchangecalendaradaptor.h
new file mode 100644
index 000000000..7e772302d
--- /dev/null
+++ b/kresources/newexchange/exchangecalendaradaptor.h
@@ -0,0 +1,99 @@
+ /*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+
+ 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.
+*/
+#ifndef KPIM_EXCHANGECALENDARADAPTOR_H
+#define KPIM_EXCHANGECALENDARADAPTOR_H
+
+#include "exchangeglobals.h"
+
+#include <groupwareresourcejob.h>
+#include <davcalendaradaptor.h>
+#include <kurl.h>
+#include <qdom.h>
+
+namespace KCal {
+
+class Incidence;
+
+class ExchangeCalendarUploadItem : public KPIM::GroupwareUploadItem
+{
+ public:
+ ExchangeCalendarUploadItem( CalendarAdaptor *adaptor, KCal::Incidence *incidence, UploadType type );
+ virtual ~ExchangeCalendarUploadItem() {}
+ virtual KIO::TransferJob *createUploadNewJob(
+ KPIM::GroupwareDataAdaptor *adaptor, const KURL &baseurl );
+ virtual KIO::TransferJob *createUploadJob(
+ KPIM::GroupwareDataAdaptor *adaptor, const KURL &url );
+
+ protected:
+ ExchangeCalendarUploadItem( UploadType type ) : KPIM::GroupwareUploadItem( type ) {}
+ QDomDocument mDavData;
+};
+
+class ExchangeCalendarAdaptor : public DavCalendarAdaptor
+{
+ public:
+ ExchangeCalendarAdaptor();
+
+ void customAdaptDownloadUrl( KURL &url );
+ void customAdaptUploadUrl( KURL &url );
+ QString mimeType() const { return "message/rfc822"; }
+ QCString identifier() const { return "KCalResourceExchange"; }
+ QString defaultNewItemName( KPIM::GroupwareUploadItem *item );
+ long flags() const { return GWResBatchDelete; }
+
+
+
+ // Creating Jobs
+ KIO::Job *createListFoldersJob( const KURL &url )
+ { return ExchangeGlobals::createListFoldersJob( url ); }
+ KIO::TransferJob *createListItemsJob( const KURL &url )
+ { return ExchangeGlobals::createListItemsJob( url ); }
+ KIO::TransferJob *createDownloadJob( const KURL &url, KPIM::FolderLister::ContentType ctype )
+ { return ExchangeGlobals::createDownloadJob( this, url, ctype ); }
+ KIO::Job *createRemoveJob( const KURL &uploadurl, const KPIM::GroupwareUploadItem::List &deletedItems )
+ { return ExchangeGlobals::createRemoveJob( uploadurl, deletedItems ); }
+
+
+ // Interpreting Jobs
+ bool interpretListItemsJob( KIO::Job *job, const QString &jobData )
+ { return ExchangeGlobals::interpretListItemsJob( this, job, jobData ); }
+ bool interpretDownloadItemsJob( KIO::Job *job, const QString &jobData )
+ { return ExchangeGlobals::interpretCalendarDownloadItemsJob( this, job, jobData ); }
+ bool interpretUploadJob( KIO::Job *job, const QString &/*jobData*/ );
+ bool interpretUploadNewJob( KIO::Job *job, const QString &/*jobData*/ );
+
+
+
+ KPIM::GroupwareUploadItem *newUploadItem( KCal::Incidence*it,
+ KPIM::GroupwareUploadItem::UploadType type );
+
+
+
+ bool getFolderHasSubs( const QDomNode &folderNode )
+ { return ExchangeGlobals::getFolderHasSubs( folderNode ); }
+ KPIM::FolderLister::ContentType getContentType( const QDomNode &folderNode )
+ { return ExchangeGlobals::getContentType( folderNode ); }
+};
+
+}
+
+#endif
diff --git a/kresources/newexchange/exchangeconvertercalendar.cpp b/kresources/newexchange/exchangeconvertercalendar.cpp
new file mode 100644
index 000000000..bc0481daf
--- /dev/null
+++ b/kresources/newexchange/exchangeconvertercalendar.cpp
@@ -0,0 +1,820 @@
+/*
+ This file is part of the exchange resource.
+ Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+ Parts are derived from the old libkpimexchange library:
+ Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
+
+ 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.
+*/
+
+#include "exchangeconvertercalendar.h"
+#include <webdavhandler.h>
+#include <libkcal/incidence.h>
+#include <libkcal/event.h>
+#include <libkcal/journal.h>
+#include <libkcal/todo.h>
+#include <libkcal/icalformat.h>
+#include <libemailfunctions/email.h>
+
+#include <kdebug.h>
+
+using namespace KCal;
+
+#define TaskNamespace1 "http://schemas.microsoft.com/mapi/id/{00062003-0000-0000-C000-000000000046}/"
+#define TaskProp_Status "0x00008101"
+#define TaskProp_PercentCompleted "0x00008102"
+#define TaskProp_DtStart "0x00008104"
+#define TaskProp_DtDue "0x00008105"
+#define TaskProp_Duration "0x00008106"
+#define TaskProp_CompletionDate "0x0000810f"
+#define TaskProp_IsCompleted "0x0000811C"
+#define TaskProp_Owner "0x0000811F"
+#define TaskProp_DoesRecur "0x00008126"
+
+#define TaskNamespace2 "http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/"
+#define TaskProp_ReminderTime "0x00008502"
+#define TaskProp_ReminderSet "0x00008503"
+#define TaskProp_ReminderPlaySound "0x0000851E"
+#define TaskProp_ReminderSoundFile "0x0000851F"
+#define TaskProp_ContactNames "0x0000853A"
+
+
+ExchangeConverterCalendar::ExchangeConverterCalendar()
+{
+}
+
+void ExchangeConverterCalendar::setTimeZone( const QString &id )
+{
+ // kdDebug() << "Setting timezone to: " << id << endl;
+ mFormat.setTimeZone( id, true );
+}
+
+#define propertyDAV( prop ) \
+ WebdavHandler::addElement( doc, root, "d:"prop )
+#define propertyNS( ns, prop ) \
+ WebdavHandler::addElementNS( doc, root, ns, prop )
+#define propertyCalendar( prop ) \
+ WebdavHandler::addElement( doc, root, "c:"prop )
+#define propertyHTTPMail( prop ) \
+ WebdavHandler::addElement( doc, root, "m:"prop )
+#define propertyMailHeader( prop ) \
+ WebdavHandler::addElement( doc, root, "h:"prop )
+#define property( prop ) \
+ WebdavHandler::addElement( doc, root, prop )
+
+void ExchangeConverterCalendar::createRequestIncidence( QDomDocument &doc, QDomElement &root )
+{
+ propertyDAV( "contentclass" );
+ propertyDAV( "getcontenttype" );
+ propertyNS( "http://schemas.microsoft.com/exchange/", "outlookmessageclass" );
+ propertyDAV( "getetag" );
+ propertyDAV( "href" );
+ propertyDAV( "isreadonly" );
+ propertyNS( "http://schemas.microsoft.com/repl/", "repl-uid" );
+ propertyHTTPMail( "subject" );
+ propertyHTTPMail( "textdescription" );
+ propertyHTTPMail( "date" );
+ propertyDAV( "comment" );
+ propertyNS( "urn:schemas-microsoft-com:office:office", "Keywords" );
+ propertyNS( "http://schemas.microsoft.com/exchange/", "sensitivity" );
+ propertyHTTPMail( "priority" );
+ propertyHTTPMail( "from" );
+ propertyHTTPMail( "to" );
+ propertyHTTPMail( "cc" );
+ propertyHTTPMail( "bcc" );
+ propertyHTTPMail( "hasattachment" );
+}
+
+void ExchangeConverterCalendar::createRequestAppointment( QDomDocument &doc, QDomElement &root )
+{
+ createRequestIncidence( doc, root );
+ QDomAttr att_c = doc.createAttribute( "xmlns:c" );
+ att_c.setValue( "urn:schemas:calendar:" );
+ doc.documentElement().setAttributeNode( att_c );
+ propertyCalendar( "uid" );
+ propertyCalendar( "created" );
+ propertyCalendar( "lastmodified" );
+ propertyCalendar( "dtstamp" );
+ propertyCalendar( "sequence" );
+ propertyCalendar( "location" );
+ propertyCalendar( "busystatus" );
+ propertyCalendar( "transparent" );
+ propertyCalendar( "timezone" );
+ propertyCalendar( "alldayevent" );
+ propertyCalendar( "dtstart" );
+ propertyCalendar( "dtend" );
+ propertyCalendar( "duration" );
+ propertyCalendar( "rrule" );
+ propertyCalendar( "rdate" );
+ propertyCalendar( "exrule" );
+ propertyCalendar( "exdate" );
+ propertyCalendar( "recurrenceid" );
+ propertyCalendar( "instancetype" );
+ propertyCalendar( "reminderoffset" );
+ propertyCalendar( "resources" );
+}
+
+#define propertyTask1( prop ) \
+ WebdavHandler::addElement( doc, props, "t1:"prop )
+#define propertyTask2( prop ) \
+ WebdavHandler::addElement( doc, props, "t2:"prop )
+
+void ExchangeConverterCalendar::createRequestTask( QDomDocument &doc, QDomElement &props )
+{
+ createRequestIncidence( doc, props );
+
+ QDomElement root = doc.documentElement();
+
+ QDomAttr att_t1 = doc.createAttribute( "xmlns:t1" );
+ att_t1.setValue( TaskNamespace1 );
+ root.setAttributeNode( att_t1 );
+
+ QDomAttr att_t2 = doc.createAttribute( "xmlns:t2" );
+ att_t2.setValue( TaskNamespace2 );
+ root.setAttributeNode( att_t2 );
+
+ // TODO: Insert the correct namespaces here:
+// propertyTask1( TaskProp_UID );
+ propertyDAV( "creationdate" );
+ propertyDAV( "getlastmodified" );
+ propertyTask1( TaskProp_Owner );
+ propertyTask2( TaskProp_ContactNames );
+ propertyTask1( TaskProp_DtStart );
+ propertyTask1( TaskProp_DtDue );
+ propertyTask1( TaskProp_Duration );
+ propertyTask1( TaskProp_IsCompleted );
+ propertyTask1( TaskProp_PercentCompleted );
+ propertyTask1( TaskProp_CompletionDate );
+ propertyTask1( TaskProp_DoesRecur );
+ // What to do about recurrence rules?
+ propertyTask2( TaskProp_ReminderSet );
+ propertyTask2( TaskProp_ReminderTime );
+ propertyTask2( TaskProp_ReminderPlaySound );
+ propertyTask2( TaskProp_ReminderSoundFile );
+ propertyTask1( TaskProp_Status );
+}
+#undef propertyTask1
+#undef propertyTask2
+
+void ExchangeConverterCalendar::createRequestJournal( QDomDocument &doc, QDomElement &root )
+{
+ createRequestIncidence( doc, root );
+ propertyDAV( "uid" );
+ propertyDAV( "creationdate" );
+ propertyDAV( "getlastmodified" );
+}
+#undef propertyDAV
+#undef propertyNS
+#undef propertyCalendar
+#undef propertyHTTPMail
+#undef propertyMailHeader
+#undef property
+
+bool ExchangeConverterCalendar::readTZ( const QDomElement &node, Incidence */*incidence*/ )
+{
+ QString timezoneid;
+ if ( WebdavHandler::extractString( node, "timezoneid", timezoneid ) ) {
+ // kdDebug() << "DEBUG: timezoneid = " << timezoneid << endl;
+ }
+
+ QString timezone;
+ if ( WebdavHandler::extractString( node, "timezone", timezone ) ) {
+ // kdDebug() << "DEBUG: timezone = " << timezone << endl;
+ }
+
+ // TODO:
+/* // mFormat is used for parsing recurrence rules.
+ QString localTimeZoneId;
+ if ( mCalendar ) {
+ mFormat.setTimeZone( mCalendar->timeZoneId(), !mCalendar->isLocalTime() );
+ localTimeZoneId = mCalendar->timeZoneId();
+ } else {
+ localTimeZoneId = "UTC";
+ // If no mCalendar, stay in UTC
+ }
+*/
+ return true;
+}
+
+bool ExchangeConverterCalendar::readIncidence( const QDomElement &node, Incidence *incidence )
+{
+kdDebug()<<"ExchangeConverterCalendar::readIncidencd"<<endl;
+ QDateTime tmpdt;
+ bool tmpbool;
+ QString tmpstr;
+ long tmplng;
+ QStringList tmplst;
+
+ readTZ( node, incidence );
+
+ if ( WebdavHandler::extractString( node, "getetag", tmpstr ) )
+ incidence->setCustomProperty( "KDEPIM-Exchange-Resource", "fingerprint", tmpstr );
+ if ( WebdavHandler::extractString( node, "href", tmpstr ) )
+ incidence->setCustomProperty( "KDEPIM-Exchange-Resource", "href", tmpstr );
+
+ // FIXME: use repl-uid as scheduling id?
+ if ( WebdavHandler::extractString( node, "textdescription", tmpstr ) )
+ incidence->setDescription( tmpstr );
+ if ( WebdavHandler::extractString( node, "subject", tmpstr ) )
+ incidence->setSummary( tmpstr );
+ if ( WebdavHandler::extractStringList( node, "Keywords", tmplst ) )
+ incidence->setCategories( tmplst );
+
+ // Use "created" or "creationdate"?
+ if ( WebdavHandler::extractBool( node, "isreadonly" , tmpbool ) )
+ incidence->setReadOnly( tmpbool );
+
+ // FIXME: Ignore the comment for now
+
+ // Exchange sentitivity values:
+ // 0 None, 1 Personal, 2 Private, 3 Company Confidential
+ if ( WebdavHandler::extractLong( node, "sensitivity", tmplng ) ) {
+ switch( tmplng ) {
+ case 0: incidence->setSecrecy( KCal::Incidence::SecrecyPublic ); break;
+ case 1:
+ case 2: incidence->setSecrecy( KCal::Incidence::SecrecyPrivate ); break;
+ case 3: incidence->setSecrecy( KCal::Incidence::SecrecyConfidential ); break;
+ default: kdWarning() << "Unknown sensitivity: " << tmplng << endl;
+ }
+ }
+
+ if ( WebdavHandler::extractBool( node, "hasattachment", tmpbool ) && tmpbool ) {
+ // FIXME: Extract attachments...
+ }
+
+ if ( WebdavHandler::extractLong( node, "priority", tmplng ) )
+ incidence->setPriority( tmplng );
+
+ // FIXME: Use the urn:schemes:httpmail:date property for what?
+
+ // Organizer, required and optional Attendees:
+ if ( WebdavHandler::extractString( node, "from", tmpstr ) )
+ incidence->setOrganizer( tmpstr );
+ if ( WebdavHandler::extractString( node, "to", tmpstr ) ) {
+ QStringList atts( KPIM::splitEmailAddrList( tmpstr ) );
+ for ( QStringList::Iterator it = atts.begin(); it != atts.end(); ++it ) {
+ QString name, email;
+ KPIM::getNameAndMail( *it, name, email );
+ Attendee *att = new Attendee( name, email );
+ att->setRole( KCal::Attendee::ReqParticipant );
+ // FIXME: Retrieve the other attendee properties somehow...
+ // urn:schemas:calendar:method
+ // urn:schemas:calendar:responserequested
+ // urn:schemas:calendar:meetingstatus
+ // urn:schemas:calendar:replytime
+ incidence->addAttendee( att );
+ }
+ }
+ if ( WebdavHandler::extractString( node, "cc", tmpstr ) ) {
+ QStringList atts( KPIM::splitEmailAddrList( tmpstr ) );
+ for ( QStringList::Iterator it = atts.begin(); it != atts.end(); ++it ) {
+ QString name, email;
+ KPIM::getNameAndMail( *it, name, email );
+ Attendee *att = new Attendee( name, email );
+ att->setRole( KCal::Attendee::OptParticipant );
+ // FIXME: Retrieve the other attendee properties somehow...
+ // urn:schemas:calendar:method
+ // urn:schemas:calendar:responserequested
+ // urn:schemas:calendar:meetingstatus
+ // urn:schemas:calendar:replytime
+ incidence->addAttendee( att );
+ }
+ }
+
+ return true;
+}
+
+/* FIXME: Handle recurrences
+void ExchangeDownload::handleRecurrence( QString uid )
+{
+ // kdDebug() << "Handling recurrence info for uid=" << uid << endl;
+ QString query =
+ "SELECT \"DAV:href\", \"urn:schemas:calendar:instancetype\"\r\n"
+ "FROM Scope('shallow traversal of \"\"')\r\n"
+ "WHERE \"urn:schemas:calendar:uid\" = '" + uid + "'\r\n"
+ " AND (\"urn:schemas:calendar:instancetype\" = 1)\r\n";
+// " OR \"urn:schemas:calendar:instancetype\" = 3)\r\n" // FIXME: exception are not handled
+
+ // kdDebug() << "Exchange master query: " << endl << query << endl;
+
+ KIO::DavJob* job = KIO::davSearch( mAccount->calendarURL(), "DAV:", "sql",
+ query, false );
+ KIO::Scheduler::scheduleJob( job );
+ job->setWindow( mWindow );
+ connect( job, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotMasterResult( KIO::Job * ) ) );
+}
+*/
+
+bool ExchangeConverterCalendar::readEvent( const QDomElement &node, Event *event )
+{
+ if ( !readIncidence( node, event ) ) return false;
+kdDebug()<<"ExchangeConverterCalendar::readEvent"<<endl;
+
+ QDateTime tmpdt;
+ QString tmpstr;
+ long tmplng;
+ bool tmpbool;
+
+ // The UID is absolutely required!
+ if ( WebdavHandler::extractString( node, "uid", tmpstr ) ) {
+ event->setUid( tmpstr );
+ } else {
+kdDebug()<<"ExchangeConverterCalendar::readIncidence: ERROR: No UID given"<<endl;
+ return false;
+ }
+ if ( WebdavHandler::extractDateTime( node, "created", tmpdt ) )
+ event->setCreated( WebdavHandler::utcAsZone( tmpdt, mFormat.timeZoneId() ) );
+ if ( WebdavHandler::extractDateTime( node, "lastmodified", tmpdt ) )
+ event->setLastModified( WebdavHandler::utcAsZone( tmpdt, mFormat.timeZoneId() ) );
+ // FIXME: Retrieve time zone: "timezone"
+ // FIXME: Use the "recurrenceid" prop for the recurrenceId of the event (which is protected!)
+
+ // FIXME: Retrieve MICROSOFT-CDO-* tags first
+
+ if ( WebdavHandler::extractLong( node, "sequence", tmplng ) )
+ event->setRevision( tmplng );
+
+ if ( WebdavHandler::extractString( node, "location", tmpstr ) )
+ event->setLocation( tmpstr );
+
+ // FIXME: Use "organizer" here instead of the From: person?
+/* if ( WebdavHandler::extractString( node, "organizer", tmpstr ) )
+ incidence->setOrganizer( tmpstr );*/
+
+ if ( WebdavHandler::extractDateTime( node, "dtstart", tmpdt ) ) {
+ event->setDtStart( WebdavHandler::utcAsZone( tmpdt, mFormat.timeZoneId() ) );
+ }
+
+ bool allDay = false;
+ if ( WebdavHandler::extractBool( node, "alldayevent", allDay ) )
+ event->setFloats( allDay );
+
+ if ( WebdavHandler::extractLong( node, "duration", tmplng ) ) {
+ if (allDay)
+ tmplng--; // Otherwise event extends into next day
+ event->setDuration( tmplng );
+ // kdDebug() << "DURATION " << tmplng << "\n";
+ } else if ( WebdavHandler::extractDateTime( node, "dtend", tmpdt ) ) {
+ event->setDtEnd( WebdavHandler::utcAsZone( tmpdt, mFormat.timeZoneId() ) );
+ }
+
+ // FIXME: Here we have two different props for the same thing?!?!?
+ if ( WebdavHandler::extractLong( node, "transparent", tmplng ) )
+ event->setTransparency( tmplng>0 ? Event::Transparent : Event::Opaque );
+ if ( WebdavHandler::extractString( node, "busystatus", tmpstr ) ) {
+ if ( tmpstr == "FREE" )
+ event->setTransparency( KCal::Event::Transparent );
+ if ( tmpstr == "BUSY" )
+ event->setTransparency( KCal::Event::Opaque );
+ }
+
+ if ( WebdavHandler::extractLong( node, "reminderoffset", tmplng ) ) {
+ // Duration before event in seconds
+ KCal::Duration offset( -tmplng );
+ KCal::Alarm *alarm = event->newAlarm();
+ alarm->setStartOffset( offset );
+ alarm->setEnabled( true );
+ alarm->setType( KCal::Alarm::Display);
+ // TODO: multiple alarms;
+ }
+
+
+ if ( WebdavHandler::extractString( node, "rrule", tmpstr ) && !tmpstr.isEmpty() ) {
+ kdDebug() << "Got rrule: " << tmpstr << endl;
+ // Timezone should be handled automatically
+ // because we used mFormat.setTimeZone() earlier
+ // FIXME: Implement this using the format!
+ RecurrenceRule *rrule = event->recurrence()->defaultRRule( true );
+ if ( ! mFormat.fromString( rrule, tmpstr ) ) {
+ kdError() << "ERROR parsing rrule " << tmpstr << endl;
+ event->recurrence()->addRRule( rrule );
+ }
+ }
+
+ QStringList tmplst;
+ if ( WebdavHandler::extractStringList( node, "exdate", tmplst ) ) {
+ QStringList::Iterator it = tmplst.begin();
+ KCal::DateList exdates;
+ for ( ; it != tmplst.end(); ++it ) {
+ exdates.append( /*utcAsZone(*/ QDateTime::fromString( *it, Qt::ISODate )/*,
+ localTimeZoneId )*/.date() );
+ }
+ event->recurrence()->setExDates( exdates );
+ }
+ // FIXME: use rdate and exrule!
+/* FIXME: Recurring events, they are split up
+ QDomElement instancetypeElement = prop.namedItem( "instancetype" ).toElement();
+ if ( instancetypeElement.isNull() ) {
+ kdError() << "Error: no instance type in Exchange server reply" << endl;
+ continue;
+ }
+ int instanceType = instancetypeElement.text().toInt();
+ //kdDebug() << "Instance type: " << instanceType << endl;
+
+ if ( recurrence && instanceType > 0 ) {
+ QDomElement uidElement = prop.namedItem( "uid" ).toElement();
+ if ( uidElement.isNull() ) {
+ kdError() << "Error: no uid in Exchange server reply" << endl;
+ continue;
+ }
+ QString uid = uidElement.text();
+ if ( ! m_uids.contains( uid ) ) {
+ m_uids[uid] = 1;
+ handleRecurrence(uid);
+ successCount++;
+ }
+ continue;
+ }
+*/
+
+
+ // FIXME: read the resources from the "resources" tag
+
+ // FIXME: Custom fields not yet implemented
+ return true;
+}
+
+bool ExchangeConverterCalendar::readTodo( const QDomElement &node, Todo *todo )
+{
+ if ( !readIncidence( node, todo ) ) return false;
+kdDebug()<<"ExchangeConverterCalendar::readTodo"<<endl;
+
+ // FIXME: Retrieve time zone: "timezone"
+ // FIXME: What to with TaskProp_Owner and TaskProp_ContactNames?
+
+ QDateTime tmpdt;
+ float tmpfloat;
+ long tmplong;
+ bool tmpbool;
+ QString tmpstr;
+
+ // The UID is absolutely required!
+ // FIXME: Which field shall be used as uid???
+/* if ( WebdavHandler::extractString( node, "uid", tmpstr ) ) {
+ todo->setUid( tmpstr );
+ } else {
+kdDebug()<<"ExchangeConverterCalendar::readIncidence: ERROR: No UID given"<<endl;
+ return false;
+ }*/
+// if ( WebdavHandler::extractDateTime( node, "created", tmpdt ) )
+/* FIXME: creation and last modification dates:
+ if ( WebdavHandler::extractDateTime( node, "creationdate", tmpdt ) )
+ incidence->setCreated( tmpdt );
+ if ( WebdavHandler::extractDateTime( node, "getlastmodified", tmpdt ) )
+ incidence->setLastModified( tmpdt );*/
+
+ if ( WebdavHandler::extractDateTime( node, TaskProp_DtStart, tmpdt ) )
+ todo->setDtStart( WebdavHandler::utcAsZone( tmpdt, mFormat.timeZoneId() ) );
+ if ( WebdavHandler::extractDateTime( node, TaskProp_DtDue, tmpdt ) )
+ todo->setDtDue( WebdavHandler::utcAsZone( tmpdt, mFormat.timeZoneId() ) );
+ if ( WebdavHandler::extractLong( node, TaskProp_Duration, tmplong ) )
+ todo->setDuration( tmplong );
+
+ if ( WebdavHandler::extractBool( node, TaskProp_IsCompleted, tmpbool ) && tmpbool ) {
+ todo->setCompleted( tmpbool );
+ if ( tmpbool && WebdavHandler::extractDateTime( node, TaskProp_CompletionDate, tmpdt ) ) {
+ todo->setCompleted( WebdavHandler::utcAsZone( tmpdt, mFormat.timeZoneId() ) );
+ }
+ }
+ if ( WebdavHandler::extractFloat( node, TaskProp_PercentCompleted, tmpfloat ) )
+ todo->setPercentComplete( (int)(tmpfloat*100) );
+
+ // FIXME: Recurrence, using TaskProp_DoesRecur
+ // What to do about recurrence rules?
+
+ // FIXME: Reminders, use TaskProp_ReminderSet, TaskProp_ReminderTime,
+ // TaskProp_ReminderPlaySound, TaskProp_ReminderSoundFile, TaskProp_Status
+ // But how do I get the offset?
+
+ return true;
+}
+
+bool ExchangeConverterCalendar::readJournal( const QDomElement &node, Journal *journal )
+{
+ if ( !readIncidence( node, journal ) ) return false;
+kdDebug()<<"ExchangeConverterCalendar::readJournal"<<endl;
+ QDateTime tmpdt;
+ QString tmpstr;
+ // The UID is absolutely required!
+ // FIXME: Which field shall be used as UID?
+ if ( WebdavHandler::extractString( node, "uid", tmpstr ) ) {
+ journal->setUid( tmpstr );
+ } else {
+kdDebug()<<"ExchangeConverterCalendar::readJournal: ERROR: No UID given"<<endl;
+ return false;
+ }
+/* FIXME: creation and last modification times:
+ if ( WebdavHandler::extractDateTime( node, "created", tmpdt ) )
+ incidence->setCreated( tmpdt );
+ if ( WebdavHandler::extractDateTime( node, "lastmodified", tmpdt ) )
+ incidence->setLastModified( tmpdt );*/
+
+ if ( WebdavHandler::extractDateTime( node, "date", tmpdt ) )
+ journal->setDtStart( tmpdt );
+ return true;
+}
+
+Incidence::List ExchangeConverterCalendar::parseWebDAV( const QDomDocument& davdata )
+{
+ QDomElement prop = davdata.documentElement().namedItem( "response" )
+ .namedItem( "propstat" ).namedItem( "prop" ).toElement();
+ if ( prop.isNull() ) return Incidence::List();
+
+ QString contentclass;
+ bool success = WebdavHandler::extractString( prop, "contentclass", contentclass );
+ if ( !success ) return Incidence::List();
+
+ Incidence *incidence = 0;
+ success = false;
+ if ( contentclass == "urn:content-classes:appointment" ) {
+ Event *event = new Event();
+ success = readEvent( prop, event );
+ incidence = event;
+ } else if ( contentclass == "urn:content-classes:task" ) {
+ Todo *todo = new Todo();
+ success = readTodo( prop, todo );
+ incidence = todo;
+ } else if ( contentclass == "urn:content-classes:journal" ||
+ contentclass == "urn:content-classes:message" ) {
+ Journal *journal = new Journal();
+ success = readJournal( prop, journal );
+ incidence = journal;
+ }
+
+ Incidence::List list;
+ if ( success ) {
+ list.append( incidence );
+ }
+ return list;
+}
+
+
+#define domDavProperty( name, value ) \
+ WebdavHandler::addElement( mDoc, mElement, "d:"name, value )
+#define domProperty( NS, name, value ) \
+ WebdavHandler::addElementNS( mDoc, mElement, NS, name, value )
+#define domCalendarProperty( name, value ) \
+ WebdavHandler::addElement( mDoc, mElement, "c:"name, value )
+#define domHTTPMailProperty( name, value ) \
+ WebdavHandler::addElement( mDoc, mElement, "m:"name, value )
+#define domMailHeaderProperty( name, value ) \
+ WebdavHandler::addElement( mDoc, mElement, "h:"name, value )
+
+
+
+
+class ExchangeConverterCalendar::createWebDAVVisitor : public IncidenceBase::Visitor
+{
+ public:
+ createWebDAVVisitor() : Visitor() {}
+ bool act( QDomDocument doc, QDomElement el, IncidenceBase *incidence, const QString &timeZoneId )
+ {
+ mDoc = doc;
+ mElement = el;
+ mTimeZoneId = timeZoneId;
+ return incidence->accept( *this );
+ }
+ protected:
+ void addBoolProp( QDomElement &el ) { el.setAttribute( "b:dt", "boolean" ); }
+ void addDateProp( QDomElement &el ) { el.setAttribute( "b:dt", "dateTime.tz" ); }
+ void addFloatProp( QDomElement &el ) { el.setAttribute( "b:dt", "float" ); }
+ void addIntProp( QDomElement &el ) { el.setAttribute( "b:dt", "int" ); }
+ QString timePropString( const QDateTime &dt ) { return dt.toString( Qt::ISODate )+"Z"; }
+
+ bool visitIncidence( Incidence *incidence )
+ {
+ QString tmpstr;
+ domDavProperty( "isreadonly", (incidence->isReadOnly())?"1":"0" );
+ // FIXME: scheduling ID
+// domProperty( "http://schemas.microsoft.com/repl/", "repl-uid", ??? );
+ domHTTPMailProperty( "subject", incidence->summary() );
+ domHTTPMailProperty( "textdescription", incidence->description() );
+ // FIXME: timestampt, comments and categories
+// domHTTPMailProperty( "date", ??? ); // timestamp not available in libkcal
+// domDavProperty( "comment", incidence->comments() ); // libkcal has a QStringlist, not one string
+// domProperty( "urn:schemas-microsoft-com:office:office", "Keywords", ??? ); // It's a <v>entyr1</v><v>entry2</v> String list!
+ tmpstr = QString::null;
+ switch ( incidence->secrecy() ) {
+ case KCal::Incidence::SecrecyPublic: tmpstr = "0"; break;
+ case KCal::Incidence::SecrecyPrivate: tmpstr = "2"; break;
+ case KCal::Incidence::SecrecyConfidential: tmpstr = "3"; break;
+ default: break;
+ }
+ if ( !tmpstr.isEmpty() )
+ domProperty( "http://schemas.microsoft.com/exchange/", "sensitivity", tmpstr );
+
+ domHTTPMailProperty( "priority", QString::number(incidence->priority()) );
+
+ domMailHeaderProperty( "from", incidence->organizer().fullName() );
+
+ // Attendees:
+ tmpstr = QString::null;
+ QStringList reqattnames;
+ QStringList optattnames;
+ Attendee::List atts = incidence->attendees();
+ for ( Attendee::List::Iterator it = atts.begin(); it != atts.end(); ++it ) {
+ switch ( (*it)->role() ) {
+ case KCal::Attendee::Chair:
+ case KCal::Attendee::ReqParticipant:
+ reqattnames << (*it)->fullName();
+ break;
+ case KCal::Attendee::OptParticipant:
+ case KCal::Attendee::NonParticipant:
+ optattnames << (*it)->fullName();
+ break;
+ default: break;
+ }
+ }
+
+ domMailHeaderProperty( "to", reqattnames.join(", ") );
+
+ domMailHeaderProperty( "cc", optattnames.join(", ") );
+
+ // FIXME: Attachments: propertyHTTPMail( "hasattachment" );
+
+ return true;
+ }
+ bool visit( Event *event )
+ {
+ if ( !visitIncidence(event) ) return false;
+
+ QDomAttr att_c = mDoc.createAttribute( "xmlns:c" );
+ att_c.setValue( "urn:schemas:calendar:" );
+ mDoc.documentElement().setAttributeNode( att_c );
+
+ domDavProperty( "contentclass", "urn:content-classes:appointment" );
+ domProperty( "http://schemas.microsoft.com/exchange/",
+ "outlookmessageclass", "IPM.Appointment" );
+ domCalendarProperty( "uid", event->uid() );
+ QDomElement el = domCalendarProperty( "created", timePropString( WebdavHandler::zoneAsUtc( event->created(), mTimeZoneId ) ) );
+ addDateProp( el );
+ el = domCalendarProperty( "lastmodified", timePropString( WebdavHandler::zoneAsUtc( event->lastModified(), mTimeZoneId ) ) );
+ addDateProp( el );
+ // FIXME: domCalendarProperty( "dtstamp", ??);
+// FIXME: domCalendarProperty( "sequence", event->sequence() );
+ domCalendarProperty( "location", event->location() );
+
+ QString tmpstr( QString::null );
+ switch ( event->transparency() ) {
+ case KCal::Event::Transparent: tmpstr = "FREE"; break;
+ case KCal::Event::Opaque: tmpstr = "BUSY"; break;
+ }
+ if ( !tmpstr.isEmpty() )
+ domCalendarProperty( "busystatus", tmpstr );
+// FIXME: What do do with the "transparent" property?
+// FIXME: Use the "timezone" property...
+ domCalendarProperty( "alldayevent", event->doesFloat()?"1":"0" );
+ el = domCalendarProperty( "dtstart", timePropString( WebdavHandler::zoneAsUtc( event->dtStart(), mTimeZoneId ) ) );
+ addDateProp( el );
+ if ( event->hasEndDate() ) {
+ el = domCalendarProperty( "dtend", timePropString( WebdavHandler::zoneAsUtc( event->dtEnd(), mTimeZoneId ) ) );
+ addDateProp( el );
+ } else {
+ domCalendarProperty( "duration", QString::number( event->duration() ) );
+ }
+ // FIXME: Convert the recurrence rule to a string:
+ if ( event->doesRecur() ) {
+// tmpstr = event->recurrence().....
+// domCalendarProperty( "rrule", tmpstr );
+ // FIXME: Use "rdate" and "exrule"
+ // FIXME: Use "exdate", what's the syntax?
+ // FIXME: use the "instancetype" property
+ }
+ // FIXME: RecurrenceID is protected!
+// domCalendarProperty( "recurrenceid", event->recurrenceId() );
+ // FIXME: "reminderoffset"
+ // FIXME: "resources" Alarm::List alarms = event->alarms();
+
+ Alarm::List::ConstIterator it;
+ Alarm::List alarms = event->alarms();
+ for( it = alarms.begin(); it != alarms.end(); ++it ) {
+ if ((*it)->hasStartOffset()) {
+ domCalendarProperty( "reminderoffset", QString::number( (*it)->startOffset().asSeconds() * -1 ) );
+ } else {
+ kdDebug() << "ExchangeConverterCalendar::createWebDAVVisitor: Alarm type not supported\n";
+ }
+ }
+
+ return true;
+ }
+ bool visit( Todo *todo )
+ {
+ if ( !visitIncidence(todo) ) return false;
+
+ QDomAttr att_t1 = mDoc.createAttribute( "xmlns:t1" );
+ att_t1.setValue( TaskNamespace1 );
+ mDoc.documentElement().setAttributeNode( att_t1 );
+
+ QDomAttr att_t2 = mDoc.createAttribute( "xmlns:t2" );
+ att_t2.setValue( TaskNamespace2 );
+ mDoc.documentElement().setAttributeNode( att_t2 );
+
+
+ domDavProperty( "contentclass", "urn:content-classes:task" );
+ domProperty( "http://schemas.microsoft.com/exchange/",
+ "outlookmessageclass", "IPM.Task" );
+
+/* FIXME:
+ domCalendarProperty( "uid", todo->uid() );
+ domCalendarProperty( "created", todo->created().toString( Qt::ISODate ) );
+ domCalendarProperty( "lastmodified", todo->lastModified().toString( Qt::ISODate ) );*/
+ // TODO
+/*propertyTask1( TaskProp_Owner );
+ propertyTask2( TaskProp_ContactNames );
+ propertyTask1( TaskProp_DtStart );
+ propertyTask1( TaskProp_DtDue );
+ propertyTask1( TaskProp_Duration );
+ propertyTask1( TaskProp_IsCompleted );
+ propertyTask1( TaskProp_PercentCompleted );
+ propertyTask1( TaskProp_CompetionDate );
+ propertyTask1( TaskProp_DoesRecur );
+ // What to do about recurrence rules?
+ propertyTask2( TaskProp_ReminderSet );
+ propertyTask2( TaskProp_ReminderTime );
+ propertyTask2( TaskProp_ReminderPlaySound );
+ propertyTask2( TaskProp_ReminderSoundFile );
+ propertyTask1( TaskProp_Status );*/
+ return true;
+ }
+ bool visit( Journal *journal )
+ {
+ if ( !visitIncidence(journal) ) return false;
+ domDavProperty( "contentclass", "urn:content-classes:journal" );
+ domProperty( "http://schemas.microsoft.com/exchange/",
+ "outlookmessageclass", "IPM.Journal" );
+/* FIXME:
+ domCalendarProperty( "uid", todo->uid() );
+ domCalendarProperty( "created", todo->created().toString( Qt::ISODate ) );
+ domCalendarProperty( "lastmodified", todo->lastModified().toString( Qt::ISODate ) );*/
+ // TODO
+ return true;
+ }
+
+ protected:
+ QDomDocument mDoc;
+ QDomElement mElement;
+ QString mTimeZoneId;
+};
+
+// Prefixes for the namespaces:
+// d... DAV:
+// b... urn:schemas-microsoft-com:datatypes
+// c... calendar
+// m... httpmail
+// h... httpheader
+// p... mapi
+// o... office
+//
+
+QDomDocument ExchangeConverterCalendar::createWebDAV( Incidence *incidence )
+{
+ // TODO
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "d:propertyupdate" );
+ QDomElement set = WebdavHandler::addElement( doc, root, "d:set" );
+ QDomElement prop = WebdavHandler::addElement( doc, set, "d:prop" );
+
+ QDomAttr att_b = doc.createAttribute( "xmlns:b" );
+ att_b.setValue( "urn:schemas-microsoft-com:datatypes" );
+ root.setAttributeNode( att_b );
+
+ QDomAttr att_h = doc.createAttribute( "xmlns:h" );
+ att_h.setValue( "urn:schemas:mailheader:" );
+ root.setAttributeNode( att_h );
+
+ QDomAttr att_m = doc.createAttribute( "xmlns:m" );
+ att_m.setValue( "urn:schemas:httpmail:" );
+ root.setAttributeNode( att_m );
+
+// QDomAttr att1 = doc.createAttributeNS( "do:whatever:you:like", "x:attname");
+// att1.setValue( "value" );
+// prop.setAttributeNodeNS( att1 );
+// root.setAttributeNodeNS( att1 );
+// set.setAttributeNode( att1 );
+// // prop.setAttributeNS ( "xmlns:b", "xmlns:b", "urn:schemas-microsoft-com:datatypes" );
+
+ ExchangeConverterCalendar::createWebDAVVisitor v;
+ v.act( doc, prop, incidence, mFormat.timeZoneId() );
+ kdDebug() << "ExchangeConverterCalendar::createWebDAVVisitor=" << doc.toString() << "\n";
+
+ return doc;
+}
+#undef domDavProperty
+#undef domProperty
+#undef domCalendarProperty
+#undef domHTTPMailProperty
+#undef domMailHeaderProperty
diff --git a/kresources/newexchange/exchangeconvertercalendar.h b/kresources/newexchange/exchangeconvertercalendar.h
new file mode 100644
index 000000000..346b2a954
--- /dev/null
+++ b/kresources/newexchange/exchangeconvertercalendar.h
@@ -0,0 +1,63 @@
+/*
+ This file is part of the exchange resource.
+ Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ 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.
+*/
+
+#ifndef KCal_EXCHANGECONVERTERCONTACT_H
+#define KCal_EXCHANGECONVERTERCONTACT_H
+
+#include <qstring.h>
+#include <qdom.h>
+
+#include <libkcal/incidence.h>
+#include <libkcal/icalformat.h>
+
+namespace KCal {
+class ICalFormat;
+
+class ExchangeConverterCalendar
+{
+ public:
+
+ ExchangeConverterCalendar();
+
+ void setTimeZone( const QString &id );
+
+ static void createRequestAppointment( QDomDocument &doc, QDomElement &root );
+ static void createRequestTask( QDomDocument &doc, QDomElement &root );
+ static void createRequestJournal( QDomDocument &doc, QDomElement &root );
+
+ QDomDocument createWebDAV( Incidence *incidence );
+
+ Incidence::List parseWebDAV( const QDomDocument& davdata );
+ bool readIncidence( const QDomElement &node, Incidence *incidence );
+
+ protected:
+ static void createRequestIncidence( QDomDocument &doc, QDomElement &root );
+ bool readEvent( const QDomElement &node, Event *event );
+ bool readTodo( const QDomElement &node, Todo *todo );
+ bool readJournal( const QDomElement &node, Journal *journal );
+ bool readTZ( const QDomElement &node, Incidence *incidence );
+
+ KCal::ICalFormat mFormat;
+ class createWebDAVVisitor;
+};
+
+}
+
+#endif
diff --git a/kresources/newexchange/exchangeconvertercontact.cpp b/kresources/newexchange/exchangeconvertercontact.cpp
new file mode 100644
index 000000000..1e756574f
--- /dev/null
+++ b/kresources/newexchange/exchangeconvertercontact.cpp
@@ -0,0 +1,615 @@
+/*
+ This file is part of the exchange resource.
+ Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ 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.
+*/
+
+#include "exchangeconvertercontact.h"
+#include <libkcal/freebusyurlstore.h>
+#include <webdavhandler.h>
+#include <kdebug.h>
+
+
+using namespace KABC;
+
+ExchangeConverterContact::ExchangeConverterContact()
+{
+}
+
+
+#define propertyDAV( prop ) \
+ WebdavHandler::addElement( doc, props, "d:" prop )
+#define propertyNS( ns, prop ) \
+ WebdavHandler::addElementNS( doc, props, ns, prop )
+#define propertyContact( prop ) \
+ WebdavHandler::addElement( doc, props, "c:" prop )
+#define propertyCalendar( prop ) \
+ WebdavHandler::addElement( doc, props, "cal:" prop )
+#define propertyHTTPMail( prop ) \
+ WebdavHandler::addElement( doc, props, "m:" prop )
+#define property( prop ) \
+ Webdavhandler::addElement( doc, props, prop )
+
+void ExchangeConverterContact::createRequest( QDomDocument &doc, QDomElement &props )
+{
+ QDomAttr att_c = doc.createAttribute( "xmlns:c" );
+ att_c.setValue( "urn:schemas:contacts:" );
+ doc.documentElement().setAttributeNode( att_c );
+ QDomAttr att_cal = doc.createAttribute( "xmlns:cal" );
+ att_cal.setValue( "urn:schemas:calendar:" );
+ doc.documentElement().setAttributeNode( att_cal );
+
+ propertyDAV( "contentclass" );
+ propertyDAV( "getcontenttype" );
+ propertyNS( "http://schemas.microsoft.com/exchange/", "outlookmessageclass" );
+ propertyDAV( "getetag" );
+ propertyDAV( "href" );
+ propertyDAV( "creationdate" );
+ propertyDAV( "getlastmodified" );
+ propertyDAV( "isreadonly" );
+ propertyContact( "cn" );
+// propertyContact( "uid" );
+ propertyDAV( "uid" );
+ propertyContact( "fileas" );
+ propertyContact( "cn" );
+ propertyContact( "givenName" );
+ propertyContact( "initials" );
+ propertyContact( "middlename" );
+ propertyContact( "namesuffix" );
+ propertyContact( "personaltitle" );
+ propertyContact( "sn" );
+ propertyContact( "title" );
+ propertyContact( "o" );
+ propertyContact( "department" );
+ propertyContact( "roomnumber" );
+ propertyContact( "profession" );
+ propertyContact( "manager" );
+ propertyContact( "secretarycn" );
+ propertyContact( "email1" );
+ propertyContact( "email2" );
+ propertyContact( "email3" );
+ propertyContact( "personalHomePage" );
+ propertyContact( "businesshomepage" );
+ propertyContact( "fburl" );
+ // TODO: Does this work?
+// propertyNS( "urn:schemas-microsoft-com:office:office", "Keywords" );
+ propertyDAV( "sensitivity" );
+ propertyContact( "telephoneNumber" );
+ propertyContact( "telephonenumber2" );
+ propertyContact( "officetelephonenumber" );
+ propertyContact( "office2telephonenumber" );
+ propertyContact( "secretaryphone" );
+ propertyContact( "organizationmainphone" );
+ propertyContact( "otherTelephone" );
+ propertyContact( "homePhone" );
+ propertyContact( "homephone2" );
+ propertyContact( "mobile" );
+ propertyContact( "othermobile" );
+ propertyContact( "facsimiletelephonenumber" );
+ propertyContact( "homefax" );
+ propertyContact( "otherfax" );
+ propertyContact( "pager" );
+ propertyContact( "otherpager" );
+ propertyContact( "internationalisdnnumber" );
+ propertyContact( "callbackphone" );
+ propertyContact( "telexnumber" );
+ propertyContact( "ttytddphone" );
+ propertyContact( "workaddress" );
+ propertyContact( "street" );
+ propertyContact( "postofficebox" );
+ propertyContact( "l" );
+ propertyContact( "postalcode" );
+ propertyContact( "st" );
+ propertyContact( "co" );
+ propertyContact( "c" );
+ propertyContact( "homepostaladdress" );
+ propertyContact( "homeStreet" );
+ propertyContact( "homepostofficebox" );
+ propertyContact( "homeCity" );
+ propertyContact( "homePostalCode" );
+ propertyContact( "homeState" );
+ propertyContact( "homeCountry" );
+ propertyContact( "homeCountrycode" );
+ propertyContact( "mailingpostaladdress" );
+ propertyContact( "mailingstreet" );
+ propertyContact( "mailingpostofficebox" );
+ propertyContact( "mailingcity" );
+ propertyContact( "mailingpostalcode" );
+ propertyContact( "mailingstate" );
+ propertyContact( "mailingcountry" );
+ propertyContact( "mailingcountrycode" );
+ propertyContact( "otherpostaladdress" );
+ propertyContact( "otherstreet" );
+ propertyContact( "otherpostofficebox" );
+ propertyContact( "othercity" );
+ propertyContact( "otherpostalcode" );
+ propertyContact( "otherstate" );
+ propertyContact( "othercountry" );
+ propertyContact( "othercountrycode" );
+ propertyContact( "nickname" );
+ propertyContact( "spousecn" );
+ propertyContact( "bday" );
+ propertyContact( "weddinganniversary" );
+ propertyCalendar( "geolatitude" );
+ propertyCalendar( "geolongitude" );
+ propertyContact( "mapurl" );
+ propertyContact( "location" );
+ propertyHTTPMail( "textdescription" );
+ propertyHTTPMail( "date" );
+ propertyContact( "usercertificate" );
+}
+#undef propertyDAV
+#undef propertyNS
+#undef propertyContact
+#undef propertyCalendar
+#undef propertyHTTPMail
+#undef property
+
+
+bool ExchangeConverterContact::extractAddress( const QDomElement &node,
+ Addressee &addressee, int type,
+ const QString &street, const QString &pobox, const QString &location,
+ const QString &postalcode, const QString &state, const QString &country,
+ const QString &/*countycode*/ )
+{
+ bool haveAddr = false;
+ Address addr( type );
+ QString tmpstr;
+
+ if ( WebdavHandler::extractString( node, street, tmpstr ) ) {
+ addr.setStreet( tmpstr );
+ haveAddr = true;
+ }
+ if ( WebdavHandler::extractString( node, pobox, tmpstr ) ) {
+ addr.setPostOfficeBox( tmpstr );
+ haveAddr = true;
+ }
+ if ( WebdavHandler::extractString( node, location, tmpstr ) ) {
+ addr.setLocality( tmpstr );
+ haveAddr = true;
+ }
+ if ( WebdavHandler::extractString( node, postalcode, tmpstr ) ) {
+ addr.setPostalCode( tmpstr );
+ haveAddr = true;
+ }
+ if ( WebdavHandler::extractString( node, state, tmpstr ) ) {
+ addr.setRegion( tmpstr );
+ haveAddr = true;
+ }
+ if ( WebdavHandler::extractString( node, country, tmpstr ) ) {
+ addr.setCountry( tmpstr );
+ haveAddr = true;
+ }
+// if ( WebdavHandler::extractString( node, countrycode, tmpstr ) ) {
+// addr.setCountryCode( tmpstr );
+// haveAddr = true;
+// }
+ if ( haveAddr ) {
+ addressee.insertAddress( addr );
+ }
+ return haveAddr;
+}
+
+
+/**
+For the complete list of Exchange <=> KABC field mappings see the file
+Person.mapping */
+bool ExchangeConverterContact::readAddressee( const QDomElement &node, Addressee &addressee )
+{
+ QString tmpstr;
+ long tmplng;
+
+ // The UID is absolutely required!
+ if ( WebdavHandler::extractString( node, "uid", tmpstr ) ) {
+ addressee.setUid( tmpstr );
+ } else {
+ kdDebug()<<"Addressee does not have a UID"<<endl;
+ return false;
+ }
+ if ( WebdavHandler::extractString( node, "getetag", tmpstr ) )
+ addressee.insertCustom( "KDEPIM-Exchange-Resource", "fingerprint", tmpstr );
+ if ( WebdavHandler::extractString( node, "href", tmpstr ) )
+ addressee.insertCustom( "KDEPIM-Exchange-Resource", "href", tmpstr );
+
+/* KDE4: addressee does not have any creation or modification date :-(( */
+/* KDE4: read-only not supported by libkabc */
+
+ // Name: first, family, pre/postfixes, common name
+ if ( WebdavHandler::extractString( node, "fileas", tmpstr ) ||
+ WebdavHandler::extractString( node, "cn", tmpstr ) )
+ addressee.setFormattedName( tmpstr );
+ if ( WebdavHandler::extractString( node, "givenName", tmpstr ) )
+ addressee.setGivenName( tmpstr );
+ if ( WebdavHandler::extractString( node, "middlename", tmpstr ) )
+ addressee.setAdditionalName( tmpstr );
+ if ( WebdavHandler::extractString( node, "sn", tmpstr ) )
+ addressee.setFamilyName( tmpstr );
+ //urn:schemas:contacts:initials not used -
+ if ( WebdavHandler::extractString( node, "namesuffix", tmpstr ) )
+ addressee.setSuffix( tmpstr );
+ if ( WebdavHandler::extractString( node, "personaltitle", tmpstr ) )
+ addressee.setPrefix( tmpstr );
+
+ // Role
+ if ( WebdavHandler::extractString( node, "title", tmpstr ) )
+ addressee.setRole( tmpstr );
+
+ // Company-Related settings
+ if ( WebdavHandler::extractString( node, "o", tmpstr ) )
+ addressee.setOrganization( tmpstr );
+ if ( WebdavHandler::extractString( node, "department", tmpstr ) )
+ addressee.insertCustom( "KADDRESSBOOK", "X-Department", tmpstr );
+ if ( WebdavHandler::extractString( node, "roomnumber", tmpstr ) )
+ addressee.insertCustom( "KADDRESSBOOK", "X-Office", tmpstr );
+ if ( WebdavHandler::extractString( node, "profession", tmpstr ) )
+ addressee.insertCustom( "KADDRESSBOOK", "X-Profession", tmpstr );
+ if ( WebdavHandler::extractString( node, "manager", tmpstr ) )
+ addressee.insertCustom( "KADDRESSBOOK", "X-ManagersName", tmpstr );
+
+ if ( WebdavHandler::extractString( node, "secretarycn", tmpstr ) )
+ addressee.insertCustom( "KADDRESSBOOK", "X-AssistantsName", tmpstr );
+
+
+ // Web-Related settings
+ if ( WebdavHandler::extractString( node, "email1", tmpstr ) )
+ addressee.insertEmail( tmpstr, true );
+ if ( WebdavHandler::extractString( node, "email2", tmpstr ) )
+ addressee.insertEmail( tmpstr );
+ if ( WebdavHandler::extractString( node, "email3", tmpstr ) )
+ addressee.insertEmail( tmpstr );
+
+ // No kabc field for personalHomePage
+ if ( WebdavHandler::extractString( node, "businesshomepage", tmpstr ) )
+ addressee.setUrl( tmpstr );
+
+ if ( WebdavHandler::extractString( node, "fburl", tmpstr ) ) {
+ KCal::FreeBusyUrlStore::self()->writeUrl( addressee.preferredEmail(), tmpstr );
+ KCal::FreeBusyUrlStore::self()->sync();
+ }
+
+
+ // General stuff:
+ QStringList tmplst;
+ if ( WebdavHandler::extractStringList( node, "Keywords", tmplst ) )
+ addressee.setCategories( tmplst );
+ // Exchange sentitivity values:
+ // 0 None, 1 Personal, 2 Private, 3 Company Confidential
+ if ( WebdavHandler::extractLong( node, "sensitivity", tmplng ) ) {
+ switch( tmplng ) {
+ case 0: addressee.setSecrecy( KABC::Secrecy::Public ); break;
+ case 1:
+ case 2: addressee.setSecrecy( KABC::Secrecy::Private ); break;
+ case 3: addressee.setSecrecy( KABC::Secrecy::Confidential ); break;
+ default: kdWarning() << "Unknown sensitivity: " << tmplng << endl;
+ }
+ }
+
+#define insertPhone( name, type ) \
+ if ( WebdavHandler::extractString( node, name, tmpstr ) ) \
+ addressee.insertPhoneNumber( KABC::PhoneNumber( tmpstr, type ) );
+ // Phone numbers
+ insertPhone( "telephoneNumber", PhoneNumber::Work );
+//insertPhone( "telephonenumber2", PhoneNumber::Work );
+ insertPhone( "officetelephonenumber", PhoneNumber::Work );
+//insertPhone( "office2telephonenumber", PhoneNumber::Work );
+//insertPhone( "secretaryphone", PhoneNumber::Work );
+//insertPhone( "organizationmainphone", PhoneNumber::Work );
+ insertPhone( "otherTelephone", 0 );
+ insertPhone( "homePhone", PhoneNumber::Home );
+//insertPhone( "homephone2", PhoneNumber::Home );
+ insertPhone( "mobile", PhoneNumber::Cell );
+//insertPhone( "othermobile", PhoneNumber::Cell );
+ insertPhone( "facsimiletelephonenumber",PhoneNumber::Fax );
+ insertPhone( "homefax", PhoneNumber::Fax | PhoneNumber::Home );
+ insertPhone( "otherfax", PhoneNumber::Fax | PhoneNumber::Work );
+ insertPhone( "pager", PhoneNumber::Pager | PhoneNumber::Work );
+ insertPhone( "otherpager", PhoneNumber::Pager );
+ insertPhone( "internationalisdnnumber", PhoneNumber::Isdn );
+ insertPhone( "callbackphone", PhoneNumber::Msg );
+ insertPhone( "telexnumber", PhoneNumber::Bbs );
+ insertPhone( "ttytddphone", PhoneNumber::Pcs );
+#undef insertPhone
+
+ // Addresses: Work, Home, Mailing and Other:
+ extractAddress( node, addressee, Address::Work | Address::Pref,
+ "street", "postofficebox", "l", "postalcode", "st", "co", "c" );
+ extractAddress( node, addressee, Address::Home,
+ "homeStreet", "homepostofficebox", "homeCity", "homePostalCode",
+ "homeState", "homeCountry", "homeCountrycode" );
+ // Exchange doesn't support writing/changing the mailing address fields,
+ // so don't download it. It's equal to either the home or work address anyway
+/* extractAddress( node, addressee, Address::Postal,
+ "mailingstreet", "mailingpostofficebox", "mailingcity", "mailingpostalcode",
+ "mailingstate", "mailingcountry", "mailingcountrycode" );*/
+ extractAddress( node, addressee, 0,
+ "otherstreet", "otherpostofficebox", "othercity", "otherpostalcode",
+ "otherstate", "othercountry", "othercountrycode" );
+
+
+ if ( WebdavHandler::extractString( node, "nickname", tmpstr ) )
+ addressee.setNickName( tmpstr );
+ if ( WebdavHandler::extractString( node, "spousecn", tmpstr ) )
+ addressee.insertCustom( "KADDRESSBOOK", "X-SpousesName", tmpstr );
+
+ QDateTime tmpdt;
+ if ( WebdavHandler::extractDateTime( node, "bday", tmpdt ) )
+ addressee.setBirthday( tmpdt.date() );
+ if ( WebdavHandler::extractString( node, "weddinganniversary", tmpstr ) )
+ addressee.insertCustom( "KADDRESSBOOK", "X-Anniversary", tmpstr );
+
+// TODO? timeZone()
+
+ float lt,lng;
+ if ( WebdavHandler::extractFloat( node, "geolatitude", lt ) &&
+ WebdavHandler::extractFloat( node, "geolongitude", lng ) )
+ addressee.setGeo( Geo( lt, lng ) );
+ // TODO: mapurl
+ // TODO: location
+
+ if ( WebdavHandler::extractString( node, "textdescription", tmpstr ) )
+ addressee.setNote( tmpstr );
+
+// if ( WebdavHandler::extractString( node, "usercertificate", tmpstr ) )
+// addressee.setKeys()
+
+ return true;
+}
+
+Addressee::List ExchangeConverterContact::parseWebDAV( const QDomDocument& davdata )
+{
+ // TODO: Handle multiple addressees per reply!
+ Addressee::List list;
+
+ QDomElement prop = davdata.documentElement().namedItem( "response" )
+ .namedItem( "propstat" ).namedItem( "prop" ).toElement();
+ if ( prop.isNull() ) {
+kdDebug()<<"ExchangeConverterContact::parseWebDAV, no response->propstat->prop element!"<<endl;
+ return list;
+ }
+
+ QString contentclass;
+ bool success = WebdavHandler::extractString( prop, "contentclass", contentclass );
+ if ( !success ) {
+kdDebug()<<"ExchangeConverterContact::parseWebDAV, No contentclass entry"<<endl;
+ return list;
+ }
+
+ success = false;
+ Addressee addressee;
+ if ( contentclass == "urn:content-classes:person" ) {
+ success = readAddressee( prop, addressee );
+ }
+
+ if ( success ) {
+ list.append( addressee );
+ } else {
+
+ }
+ return list;
+}
+
+#define domDavProperty( name, value ) \
+ WebdavHandler::addElement( doc, prop, "d:" name, value );
+#define domProperty( NS, name, value ) \
+ WebdavHandler::addElementNS( doc, prop, NS, name, value );
+#define domContactProperty( name, value ) \
+ WebdavHandler::addElement( doc, prop, "c:" name, value );
+#define domCalendarProperty( name, value ) \
+ WebdavHandler::addElement( doc, prop, "cal:" name, value );
+#define domPhoneProperty( name, type ) \
+ domContactProperty( name, addr.phoneNumber( type ).number() );
+
+
+QDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
+{
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "d:propertyupdate" );
+ QDomElement set = WebdavHandler::addElement( doc, root, "d:set" );
+ QDomElement prop = WebdavHandler::addElement( doc, set, "d:prop" );
+
+ QDomAttr att_c = doc.createAttribute( "xmlns:c" );
+ att_c.setValue( "urn:schemas:contacts:" );
+ doc.documentElement().setAttributeNode( att_c );
+
+ QDomAttr att_b = doc.createAttribute( "xmlns:b" );
+ att_b.setValue( "urn:schemas-microsoft-com:datatypes" );
+ root.setAttributeNode( att_b );
+
+ domDavProperty( "contentclass", "urn:content-classes:person" );
+ domProperty( "http://schemas.microsoft.com/exchange/",
+ "outlookmessageclass", "IPM.Contact" );
+// domContactProperty( "uid", addr.uid() );
+
+ domContactProperty( "fileas", addr.formattedName() );
+ domContactProperty( "givenName", addr.givenName() );
+ domContactProperty( "middlename", addr.additionalName() );
+ domContactProperty( "sn", addr.familyName() );
+ domContactProperty( "namesuffix", addr.suffix() );
+ domContactProperty( "personaltitle", addr.prefix() );
+
+ domContactProperty( "title", addr.role() );
+ domContactProperty( "o", addr.organization() );
+ domContactProperty( "department", addr.custom( "KADDRESSBOOK", "X-Department" ) );
+ domContactProperty( "roomnumber", addr.custom( "KADDRESSBOOK", "X-Office" ) );
+ domContactProperty( "profession", addr.custom( "KADDRESSBOOK", "X-Profession" ) );
+ domContactProperty( "manager", addr.custom( "KADDRESSBOOK", "X-ManagersName" ) );
+ domContactProperty( "secretarycn", addr.custom( "KADDRESSBOOK", "X-AssistantsName" ) );
+
+ QStringList emails = addr.emails();
+ QString prefemail = addr.preferredEmail();
+ if ( emails.contains( prefemail ) )
+ emails.remove( prefemail );
+ emails.prepend( prefemail );
+ if ( emails.count() > 0 ) {
+ domContactProperty( "email1", emails[0] );
+ }
+ if ( emails.count() > 1 ) {
+ domContactProperty( "email2", emails[1] );
+ }
+ if ( emails.count() > 2 ) {
+ domContactProperty( "email3", emails[2] );
+ }
+
+ // No value for "personalHomePage"
+ domContactProperty( "businesshomepage", addr.url().url() );
+
+ QString fburl = KCal::FreeBusyUrlStore::self()->readUrl( addr.preferredEmail() );
+ if ( !fburl.isEmpty() ) {
+ domContactProperty( "fburl", fburl );
+ }
+
+/* FIXME: This doesn't work!
+ QStringList cats = addr.categories();
+ if ( cats.isEmpty() ) {
+ QDomElement catsnode = WebdavHandler::addElementNS( doc, prop,
+ "urn:schemas-microsoft-com:office:office", "Keywords" );
+ for ( QStringList::Iterator it = cats.begin(); it != cats.end(); ++it ) {
+ WebdavHandler::addElementNS( doc, catsnode, "xml:", "v", *it );
+ }
+ } else {
+// QDomElement catsnode = addProperty( doc, prop,
+// "urn:schemas-microsoft-com:office:office", "Keywords", "" );
+ }*/
+
+ // Exchange sentitivity values:
+ // 0 None, 1 Personal, 2 Private, 3 Company Confidential
+ QString value;
+ switch ( addr.secrecy().type() ) {
+ case KABC::Secrecy::Private: value = "2"; break;
+ case KABC::Secrecy::Confidential: value = "3"; break;
+ default: value = "0";
+ }
+ domDavProperty( "sensitivity", value );
+
+ // Phone numbers
+ domPhoneProperty( "telephoneNumber", PhoneNumber::Work );
+// domPhoneProperty( "telephonenumber2", PhoneNumber::Work );
+ domPhoneProperty( "officetelephonenumber", PhoneNumber::Work );
+// domPhoneProperty( "office2telephonenumber", PhoneNumber::Work );
+// domPhoneProperty( "secretaryphone", PhoneNumber::Work );
+// domPhoneProperty( "organizationmainphone", PhoneNumber::Work );
+ domPhoneProperty( "otherTelephone", 0 );
+ domPhoneProperty( "homePhone", PhoneNumber::Home );
+// domPhoneProperty( "homephone2", PhoneNumber::Home );
+ domPhoneProperty( "mobile", PhoneNumber::Cell );
+ domPhoneProperty( "othermobile", PhoneNumber::Cell | PhoneNumber::Home );
+ domPhoneProperty( "facsimiletelephonenumber", PhoneNumber::Fax );
+ domPhoneProperty( "homefax", PhoneNumber::Fax | PhoneNumber::Home );
+ domPhoneProperty( "otherfax", PhoneNumber::Fax | PhoneNumber::Work );
+ domPhoneProperty( "pager", PhoneNumber::Pager | PhoneNumber::Work );
+ domPhoneProperty( "otherpager", PhoneNumber::Pager );
+ domPhoneProperty( "internationalisdnnumber", PhoneNumber::Isdn );
+ domPhoneProperty( "callbackphone", PhoneNumber::Msg );
+ domPhoneProperty( "telexnumber", PhoneNumber::Bbs );
+ domPhoneProperty( "ttytddphone", PhoneNumber::Pcs );
+
+
+// work address:
+ Address workaddr = addr.address( Address::Work | Address::Pref );
+ if ( !workaddr.isEmpty() ) {
+ domContactProperty( "street", workaddr.street() );
+ domContactProperty( "postofficebox", workaddr.postOfficeBox() );
+ domContactProperty( "l", workaddr.locality() );
+ domContactProperty( "postalcode", workaddr.postalCode() );
+ domContactProperty( "st", workaddr.region() );
+ domContactProperty( "co", workaddr.country() );
+ // domContactProperty( "c", workaddr.countryCode() );
+ }
+
+ // home address:
+ Address homeaddr = addr.address( Address::Home );
+ if ( !homeaddr.isEmpty() ) {
+ domContactProperty( "homeStreet", homeaddr.street() );
+ domContactProperty( "homepostofficebox", homeaddr.postOfficeBox() );
+ domContactProperty( "homeCity", homeaddr.locality() );
+ domContactProperty( "homePostalCode", homeaddr.postalCode() );
+ domContactProperty( "homeState", homeaddr.region() );
+ domContactProperty( "homeCountry", homeaddr.country() );
+ // domContactProperty( "homeCountrycode", homeaddr.countryCode() );
+ }
+
+ // mailing address:
+ // Exchange doesn't support writing/changing the mailing address fields
+/* Address mailingaddr = addr.address( Address::Postal );
+ if ( !mailingaddr.isEmpty() ) {
+ domContactProperty( "mailingstreet", mailingaddr.street() );
+ domContactProperty( "mailingpostofficebox", mailingaddr.postOfficeBox() );
+ domContactProperty( "mailingcity", mailingaddr.locality() );
+ domContactProperty( "mailingpostalcode", mailingaddr.postalCode() );
+ domContactProperty( "mailingstate", mailingaddr.region() );
+ domContactProperty( "mailingcountry", mailingaddr.country() );
+ // domContactProperty( "mailingcountrycode", mailingaddr.countryCode() );
+ }*/
+
+ // other address:
+ Address otheraddr = addr.address( 0 );
+ if ( !otheraddr.isEmpty() ) {
+ domContactProperty( "otherstreet", otheraddr.street() );
+ domContactProperty( "otherpostofficebox", otheraddr.postOfficeBox() );
+ domContactProperty( "othercity", otheraddr.locality() );
+ domContactProperty( "otherpostalcode", otheraddr.postalCode() );
+ domContactProperty( "otherstate", otheraddr.region() );
+ domContactProperty( "othercountry", otheraddr.country() );
+ // domContactProperty( "othercountrycode", otheraddr.countryCode() );
+ }
+
+
+ domContactProperty( "nickname", addr.nickName() );
+ domContactProperty( "spousecn", addr.custom( "KADDRESSBOOK", "X-SpousesName" ) );
+
+ // TODO: Birthday and Anniversary:
+ // FIXME: Exchange uses the date in the form 8/13, i.e. possibly without a
+ // year! How shall I deal with this?
+/* QDate dt = addr.birthday().date();
+ QString str = (dt.isValid())?(dt.toString( Qt::ISODate )):(QString::null);
+ if ( !str.isEmpty() ) {
+ QDomElement el = domContactProperty( "bday", str );
+ el.setAttribute( "b:dt", "date" );
+ }
+ dt = QDate::fromString( addr.custom( "KADDRESSBOOK", "X-Anniversary" ), Qt::ISODate );
+ str = (dt.isValid())?(dt.toString( Qt::ISODate )):(QString::null);
+ if ( !str.isEmpty() ) {
+ QDomElement el = domContactProperty( "weddinganniversary", str );
+ el.setAttribute( "b:dt", "date" );
+ }*/
+
+// ? TODO: timeZone()
+/*
+ KABC::Geo geo = addr.geo();
+ if ( geo.isValid() ) {
+ // TODO: Do we need to set any other attribute to make it a float?
+ QDomAttr att_cal = doc.createAttribute( "xmlns:cal" );
+ att_cal.setValue( "urn:schemas:calendar:" );
+ doc.documentElement().setAttributeNode( att_cal );
+ QDomElement el = domCalendarProperty( "geolatitude", QString::number( geo.latitude() ) );
+ el.setAttribute( "b:dt", "float" );
+ el = domCalendarProperty( "geolongitude", QString::number( geo.longitude() ) );
+ el.setAttribute( "b:dt", "float" );
+ }
+*/
+ domContactProperty( "textdescription", addr.note() );
+
+ // TODO:usercertificate
+ // TODO: custom fields
+kdDebug()<<"DOM document: "<<doc.toString() << endl;
+
+ return doc;
+}
+#undef domDavProperty
+#undef domProperty
+#undef domContactProperty
+#undef domPhoneProperty
diff --git a/kresources/newexchange/exchangeconvertercontact.h b/kresources/newexchange/exchangeconvertercontact.h
new file mode 100644
index 000000000..45ee7c7ca
--- /dev/null
+++ b/kresources/newexchange/exchangeconvertercontact.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of the exchange resource.
+ Copyright (c) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ 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.
+*/
+
+#ifndef KABC_EXCHANGECONVERTERCONTACT_H
+#define KABC_EXCHANGECONVERTERCONTACT_H
+
+#include <qstring.h>
+#include <qdom.h>
+
+#include <kabc/addressee.h>
+
+namespace KABC {
+
+class ExchangeConverterContact
+{
+ public:
+
+ ExchangeConverterContact();
+
+ static void createRequest( QDomDocument &doc, QDomElement &root );
+
+ QDomDocument createWebDAV( Addressee addr );
+
+ Addressee::List parseWebDAV( const QDomDocument& davdata );
+ bool readAddressee( const QDomElement &node, Addressee &addressee );
+
+ protected:
+ bool extractAddress( const QDomElement &node, Addressee &addressee, int type,
+ const QString &street, const QString &pobox, const QString &location,
+ const QString &postalcode, const QString &state, const QString &country,
+ const QString &countycode );
+};
+
+}
+
+#endif
diff --git a/kresources/newexchange/exchangeglobals.cpp b/kresources/newexchange/exchangeglobals.cpp
new file mode 100644
index 000000000..7cca837df
--- /dev/null
+++ b/kresources/newexchange/exchangeglobals.cpp
@@ -0,0 +1,286 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2005 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ 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.
+*/
+
+#include "exchangeglobals.h"
+#include <webdavhandler.h>
+#include <groupwaredataadaptor.h>
+#include "exchangeconvertercalendar.h"
+#include "exchangeconvertercontact.h"
+#include <calendaradaptor.h>
+#include <addressbookadaptor.h>
+
+#include <libkcal/resourcecached.h>
+#include <libemailfunctions/idmapper.h>
+#include <kio/job.h>
+#include <kio/davjob.h>
+#include <kdebug.h>
+
+KPIM::FolderLister::ContentType ExchangeGlobals::getContentType( const QDomElement &prop )
+{
+ const QString &contentclass = prop.namedItem("contentclass").toElement().text();
+kdDebug()<<"contentclass: "<<contentclass<<endl;
+ return getContentType( contentclass );
+}
+
+KPIM::FolderLister::ContentType ExchangeGlobals::getContentType( const QString &contentclass )
+{
+ if ( contentclass == "urn:content-classes:appointment" )
+ return KPIM::FolderLister::Event;
+ if ( contentclass == "urn:content-classes:task" )
+ return KPIM::FolderLister::Todo;
+ if ( contentclass == "urn:content-classes:message" )
+ return KPIM::FolderLister::Message;
+ if ( contentclass == "urn:content-classes:person" )
+ return KPIM::FolderLister::Contact;
+ return KPIM::FolderLister::Unknown;
+}
+
+
+KPIM::FolderLister::ContentType ExchangeGlobals::getContentType( const QDomNode &folderNode )
+{
+kdDebug()<<"ExchangeGlobals::getContentType(...)"<<endl;
+ QDomNode n4;
+ for( n4 = folderNode.firstChild(); !n4.isNull(); n4 = n4.nextSibling() ) {
+ QDomElement e = n4.toElement();
+
+ if ( e.tagName() == "contentclass" ) {
+ QString contentclass( e.text() );
+ if ( contentclass == "urn:content-classes:contactfolder" )
+ return KPIM::FolderLister::Contact;
+ if ( contentclass == "urn:content-classes:calendarfolder" )
+ return KPIM::FolderLister::Event;
+ if ( contentclass == "urn:content-classes:taskfolder" )
+ return KPIM::FolderLister::Todo;
+ if ( contentclass == "urn:content-classes:journalfolder" )
+ return KPIM::FolderLister::Journal;
+ if ( contentclass == "urn:content-classes:folder" )
+ return KPIM::FolderLister::Folder;
+ }
+ }
+ return KPIM::FolderLister::Unknown;
+}
+
+bool ExchangeGlobals::getFolderHasSubs( const QDomNode &folderNode )
+{
+ QString hassubs = folderNode.namedItem( "hassubs" ).toElement().text();
+ return hassubs == "1";
+}
+
+
+
+
+KIO::Job *ExchangeGlobals::createListFoldersJob( const KURL &url )
+{
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "d:propfind" );
+ QDomElement prop = WebdavHandler::addElement( doc, root, "d:prop" );
+ WebdavHandler::addElement( doc, prop, "d:displayname" );
+ WebdavHandler::addElement( doc, prop, "d:contentclass" );
+ WebdavHandler::addElement( doc, prop, "d:hassubs" );
+
+ kdDebug(7000) << "props: " << doc.toString() << endl;
+ return KIO::davPropFind( url, doc, "1", false );
+}
+
+
+KIO::TransferJob *ExchangeGlobals::createListItemsJob( const KURL &url )
+{
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "d:propfind" );
+ QDomElement prop = WebdavHandler::addElement( doc, root, "d:prop" );
+ WebdavHandler::addElement( doc, prop, "d:getetag" );
+ WebdavHandler::addElement( doc, prop, "d:contentclass" );
+ kdDebug(5800) << "props = "<< doc.toString() << endl;
+ return KIO::davPropFind( url, doc, "1", false );
+}
+
+
+KIO::TransferJob *ExchangeGlobals::createDownloadJob( KPIM::GroupwareDataAdaptor *adaptor,
+ const KURL &url, KPIM::FolderLister::ContentType ctype )
+{
+kdDebug() << "ExchangeGlobals::createDownloadJob()" << endl;
+kdDebug() << "ctype=" << ctype << endl;
+kdDebug() << "Person=" << KPIM::FolderLister::Contact << ", "
+ << "Appointment=" << KPIM::FolderLister::Event << ", "
+ << "Task=" << KPIM::FolderLister::Todo << ", "
+ << "Journal=" << KPIM::FolderLister::Journal << ", "
+ << "Message=" << KPIM::FolderLister::Message << endl;
+ // Don't use an <allprop/> request!
+
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "d:propfind" );
+ QDomElement prop = WebdavHandler::addElement( doc, root, "d:prop" );
+ QDomAttr att_h = doc.createAttribute( "xmlns:h" );
+ att_h.setValue( "urn:schemas:mailheader:" );
+ root.setAttributeNode( att_h );
+
+ QDomAttr att_m = doc.createAttribute( "xmlns:m" );
+ att_m.setValue( "urn:schemas:httpmail:" );
+ root.setAttributeNode( att_m );
+
+ switch ( ctype ) {
+ case KPIM::FolderLister::Event:
+ KCal::ExchangeConverterCalendar::createRequestAppointment( doc, prop );
+ break;
+ case KPIM::FolderLister::Todo:
+ KCal::ExchangeConverterCalendar::createRequestTask( doc, prop );
+ break;
+ case KPIM::FolderLister::Journal:
+ case KPIM::FolderLister::Message:
+ KCal::ExchangeConverterCalendar::createRequestJournal( doc, prop );
+ break;
+ case KPIM::FolderLister::Contact:
+ KABC::ExchangeConverterContact::createRequest( doc, prop );
+ break;
+ default:
+ break;
+ }
+
+ kdDebug(7000) << "doc: " << doc.toString() << endl;
+ KURL authURL = url;
+ KIO::DavJob *job = KIO::davPropFind( authURL, doc, "0", false );
+/* KURL httpurl( url );
+ QString proto("http");
+ httpurl.setProtocol( proto );
+ KIO::TransferJob *job = KIO::get(httpurl, false, false);
+ job->addMetaData("customHTTPHeader", "Translate: f");
+ job->addMetaData("cache", "reload");*/
+ return job;
+}
+
+
+KIO::Job *ExchangeGlobals::createRemoveJob( const KURL &uploadurl,
+ const KPIM::GroupwareUploadItem::List &deletedItems )
+{
+ QStringList urls;
+ KPIM::GroupwareUploadItem::List::const_iterator it;
+ kdDebug() << " ExchangeGlobals::createRemoveJob: , URL="<<uploadurl.url()<<endl;
+ for ( it = deletedItems.begin(); it != deletedItems.end(); ++it ) {
+ //kdDebug(7000) << "Delete: " << endl << format.toICalString(*it) << endl;
+ kdDebug() << "Delete: " << (*it)->url().url() << endl;
+ KURL url( uploadurl );
+ url.setPath( (*it)->url().path() );
+ if ( !url.isEmpty() )
+ urls << url.url();
+ kdDebug() << "Delete (Mod) : " << url.url() << endl;
+ }
+ return KIO::del( urls, false, false );
+}
+
+
+
+
+// FIXME: This is exactly the same code as in the OGo resource, except that
+// it calls getContentType of the ExchangeGlobals class, instead of the one
+// from OGoGlobals!!!!
+bool ExchangeGlobals::interpretListItemsJob( KPIM::GroupwareDataAdaptor *adaptor,
+ KIO::Job *job, const QString &/*jobData*/ )
+{
+kdDebug()<<"ExchangeGlobals::interpretListItemsJob"<<endl;
+ KIO::DavJob *davjob = dynamic_cast<KIO::DavJob *>(job);
+
+ if ( !davjob ) {
+ return false;
+ }
+ QDomDocument doc = davjob->response();
+
+ kdDebug(7000) << " Doc: " << doc.toString() << endl;
+ kdDebug(7000) << " IdMapper: " << adaptor->idMapper()->asString() << endl;
+
+ QDomElement docElem = doc.documentElement();
+ QDomNode n = docElem.firstChild();
+ while( !n.isNull() ) {
+ QDomElement e = n.toElement(); // try to convert the node to an element.
+ n = n.nextSibling();
+ if ( e.isNull() )
+ continue;
+
+ const KURL &entry( e.namedItem("href").toElement().text() );
+ QDomElement propstat = e.namedItem("propstat").toElement();
+ if ( propstat.isNull() )
+ continue;
+ QDomElement prop = propstat.namedItem( "prop" ).toElement();
+ if ( prop.isNull() )
+ continue;
+ QDomElement elem = prop.namedItem("getetag").toElement();
+ const QString &newFingerprint = elem.text();
+ if ( elem.isNull() || newFingerprint.isEmpty() )
+ continue;
+
+ KPIM::FolderLister::ContentType type = getContentType( prop );
+
+ if (type != KPIM::FolderLister::Unknown) { // Don't queue bad entries
+ adaptor->processDownloadListItem( entry, newFingerprint, type );
+ }
+ }
+
+ return true;
+}
+
+
+bool ExchangeGlobals::interpretCalendarDownloadItemsJob( KCal::CalendarAdaptor *adaptor,
+ KIO::Job *job, const QString &/*jobData*/ )
+{
+ KIO::DavJob *davjob = dynamic_cast<KIO::DavJob*>(job);
+ if ( !davjob || !adaptor ) return false;
+
+kdDebug() << "ExchangeGlobals::interpretCalendarDownloadItemsJob(): QDomDocument="
+ << endl << davjob->response().toString() << endl;
+ KCal::ExchangeConverterCalendar conv;
+ conv.setTimeZone( adaptor->resource()->timeZoneId() );
+ KCal::Incidence::List incidences = conv.parseWebDAV( davjob->response() );
+
+ bool res = false;
+ KCal::Incidence::List::Iterator it = incidences.begin();
+ for ( ; it != incidences.end(); ++it ) {
+ QString fpr = (*it)->customProperty( "KDEPIM-Exchange-Resource", "fingerprint" );
+ KURL href( (*it)->customProperty( "KDEPIM-Exchange-Resource", "href" ) );
+ adaptor->calendarItemDownloaded( (*it), (*it)->uid(), href, fpr, href.prettyURL() );
+ res = true;
+ }
+ return res;
+}
+
+
+bool ExchangeGlobals::interpretAddressBookDownloadItemsJob(
+ KABC::AddressBookAdaptor *adaptor, KIO::Job *job, const QString &/*jobData*/ )
+{
+ KIO::DavJob *davjob = dynamic_cast<KIO::DavJob*>(job);
+ if ( !davjob || !adaptor ) return false;
+
+kdDebug() << "ExchangeGlobals::interpretAddressBookDownloadItemsJob(): QDomDocument="
+ << endl << davjob->response().toString() << endl;
+ KABC::ExchangeConverterContact conv;
+ KABC::Addressee::List addressees = conv.parseWebDAV( davjob->response() );
+
+ bool res = false;
+ KABC::Addressee::List::Iterator it = addressees.begin();
+ for ( ; it != addressees.end(); ++it ) {
+ QString fpr = (*it).custom( "KDEPIM-Exchange-Resource", "fingerprint" );
+ KURL href( (*it).custom( "KDEPIM-Exchange-Resource", "href" ) );
+ adaptor->addressbookItemDownloaded( (*it), (*it).uid(), href, fpr, href.prettyURL() );
+ res = true;
+ }
+ return res;
+}
+
+
+
diff --git a/kresources/newexchange/exchangeglobals.h b/kresources/newexchange/exchangeglobals.h
new file mode 100644
index 000000000..ba56830d7
--- /dev/null
+++ b/kresources/newexchange/exchangeglobals.h
@@ -0,0 +1,70 @@
+ /*
+ This file is part of kdepim.
+
+ Copyright (c) 2005 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ 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.
+*/
+#ifndef EXCHANGEGLOBALS_H
+#define EXCHANGEGLOBALS_H
+
+#include <kurl.h>
+#include <groupwareuploadjob.h>
+#include <qdom.h>
+
+namespace KIO {
+class Job;
+class TransferJob;
+}
+
+namespace KPIM {
+class GroupwareDataAdaptor;
+class GroupwareUploadItem;
+}
+namespace KABC {
+class AddressBookAdaptor;
+}
+namespace KCal {
+class CalendarAdaptor;
+}
+
+class ExchangeGlobals
+{
+ public:
+ ExchangeGlobals() {}
+ static KPIM::FolderLister::ContentType getContentType( const QDomElement &prop );
+ static KPIM::FolderLister::ContentType getContentType( const QString &contentclass );
+ static KPIM::FolderLister::ContentType getContentType( const QDomNode &folderNode );
+ static bool getFolderHasSubs( const QDomNode &folderNode );
+
+
+ static KIO::Job *createListFoldersJob( const KURL &url );
+ static KIO::TransferJob *createListItemsJob( const KURL &url );
+ static KIO::TransferJob *createDownloadJob( KPIM::GroupwareDataAdaptor *adaptor,
+ const KURL &url, KPIM::FolderLister::ContentType ctype );
+ static KIO::Job *createRemoveJob( const KURL &uploadurl,
+ const KPIM::GroupwareUploadItem::List &deletedItems );
+
+
+ static bool interpretListItemsJob( KPIM::GroupwareDataAdaptor *adaptor,
+ KIO::Job *job, const QString &jobData );
+ static bool interpretCalendarDownloadItemsJob( KCal::CalendarAdaptor *adaptor,
+ KIO::Job *job, const QString &jobData );
+ static bool interpretAddressBookDownloadItemsJob( KABC::AddressBookAdaptor *adaptor,
+ KIO::Job *job, const QString &jobData );
+};
+
+#endif
diff --git a/kresources/newexchange/kabc_newexchange.desktop b/kresources/newexchange/kabc_newexchange.desktop
new file mode 100644
index 000000000..b829ace7d
--- /dev/null
+++ b/kresources/newexchange/kabc_newexchange.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=Addressbook on an Exchange Server (experimental)
+Name[af]=Adresboek op 'n Exchange bediener (eksperimenteel)
+Name[bg]=Адресник на сървър Exchange (експериментално)
+Name[ca]=Llibreta d'adreces a un servidor Exchange (experimental)
+Name[cs]=Kniha adres na serveru Exchange (experimentální)
+Name[da]=Adressebog på en Exchange-server (eksperimentel)
+Name[de]=Adressbuch auf einem Exchange-Server (experimentell)
+Name[el]=Βιβλίο διευθύνσεων σε εξυπηρετητή Exchange (πειραματικό)
+Name[es]=Libreta de direcciones en un servidor Exchange (experimental)
+Name[et]=Aadressiraamat Exchange-serveris (eksperimentaalne)
+Name[eu]=Helbide-liburua Exchange zerbitzari batean (esperimentala)
+Name[fa]=کتاب نشانی روی یک کارساز مبادله )تجربی(
+Name[fi]=Osoitekirja Exchange-palvelimella (kokeellinen)
+Name[fr]=Carnet d'adresse sur un serveur Exchange (expérimental)
+Name[fy]=Adresboek op in Exchange-tsjinner (eksperimenteel)
+Name[ga]=Leabhar Seoltaí ar Fhreastalaí Exchange (trialach)
+Name[gl]=Caderno de enderezos no Servidor Exchange2000 (experimental)
+Name[hu]=Exchange-kiszolgáló címjegyzéke (kísérleti)
+Name[is]=Vistfangaskrá Exchange þjóni (á tilraunarstigi)
+Name[it]=Rubrica indirizzi su un server Exchange (sperimentale)
+Name[ja]=Exchange サーバのアドレス帳 (実験版)
+Name[ka]=წიგნაკი Exchange სერვერზე(ექსპერიმენტული)
+Name[kk]=Exchange серверіндегі адрестік кітапша (сынақтағы)
+Name[km]=សៀវភៅ​អាសយដ្ឋាន​លើ​ម៉ាស៊ីន​បម្រើ Exchange (សម្រាប់​អ្នក​មាន​បទពិសោធន៍)
+Name[lt]=Adresų knygelė Exchange serveryje (eksperimentine tvarka)
+Name[mk]=Адресар на Exchange-сервер (експериментално)
+Name[ms]=Buku Alamat pada pelayan Exchange (ujikaji)
+Name[nb]=Adressebok på en Exchange-tjener (forsøksvis)
+Name[nds]=Adressbook op en Exchange-Server (warrt utprobeert)
+Name[ne]=एक्सचेन्ज सर्भरमा ठेगाना पुस्तिका (प्रयोगात्मक)
+Name[nl]=Adresboek op een Exchange-server (experimenteel)
+Name[nn]=Adressebok på ein Exchange-tenar (eksperimentelt)
+Name[pl]=Książka adresowa na serwerze Exchange (eksperymentalne)
+Name[pt]=Livro de endereços em servidor Exchange (experimental)
+Name[pt_BR]=Livro de Endereços em um Servidor Exchange (experimenal)
+Name[ru]=Адресная книга на сервере Exchange (экспериментально)
+Name[sk]=Adresár na Exchange serveri (experimentálne)
+Name[sl]=Adresar na strežniku Exchange (poskusno)
+Name[sr]=Адресар на Exchange серверу (експериментално)
+Name[sr@Latn]=Adresar na Exchange serveru (eksperimentalno)
+Name[sv]=Adressbok på en Exchange-server (experimentell)
+Name[ta]=IMAP சேவையக வழியாக கேஅஞ்சலில் நாள்காட்டி(சோதனைக்குரியது)
+Name[tr]=Bir Exchange Sunucusu üzerinde Adres Defteri (deneyimsel)
+Name[uk]=Адресна книга на сервері Exchange (експериментальне)
+Name[zh_CN]=Exchange 服务器上的地址簿(试验性)
+Name[zh_TW]=Exchanger 伺服器的通訊錄(實驗中)
+X-KDE-Library=kabc_newexchange
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=newexchange
diff --git a/kresources/newexchange/kabc_newexchange_final.desktop b/kresources/newexchange/kabc_newexchange_final.desktop
new file mode 100644
index 000000000..7069b14d8
--- /dev/null
+++ b/kresources/newexchange/kabc_newexchange_final.desktop
@@ -0,0 +1,49 @@
+[Desktop Entry]
+Name=Addressbook on an Exchange Server
+Name[af]=Adresboek op 'n Exchange bediener
+Name[bg]=Адресник на сървър Exchange
+Name[br]=Karned chomlec'hioù war ur servijer Exchange
+Name[ca]=Llibreta d'adreces a un servidor Exchange
+Name[cs]=Kniha adres na serveru Exchange
+Name[da]=Adressebog på en Exchange-server
+Name[de]=Adressbuch auf einem Exchange-Server
+Name[el]=Βιβλίο διευθύνσεων σε εξυπηρετητή Exchange
+Name[es]=Libreta de direcciones en un servidor Exchange
+Name[et]=Aadressiraamat Exchange-serveris
+Name[eu]=Helbide-liburua Exchange zerbitzari (esperimentala)
+Name[fa]=کتاب نشانی روی یک کارساز مبادله
+Name[fi]=Osoitekirja Exchange-palvelimella
+Name[fr]=Carnet d'adresse sur un serveur Exchange
+Name[fy]=Adresboek op in Exchange-tsjinner
+Name[ga]=Leabhar Seoltaí ar Fhreastalaí Exchange
+Name[gl]=Caderno de enderezos nun Servidor Exchange
+Name[he]=פנקס כתובות בשרת Exchange
+Name[hu]=Exchange-kiszolgáló címjegyzéke
+Name[is]=Vistfangaskrá á Exchange þjóni
+Name[it]=Rubrica indirizzi su un server Exchange
+Name[ja]=Exchange サーバのアドレス帳
+Name[ka]=წიგნაკი Exchange სერვერზე
+Name[kk]=Exchange серверіндегі адрестік кітапша
+Name[km]=សៀវភៅ​អាសយដ្ឋាន​លើ​ម៉ាស៊ីន​បម្រើ Exchange
+Name[lt]=Adresų knygelė Exchange serveryje
+Name[mk]=Адресар на Exchange-сервер
+Name[ms]=Buku alamat pada pelayan Exchange
+Name[nb]=Adressebok på en Exchange-tjener
+Name[nds]=Adressbook op en Exchange-Server
+Name[ne]=एक्सचेन्ज सर्भरमा ठेगाना पुस्तिका
+Name[nl]=Adresboek op een Exchange-server
+Name[nn]=Adressebok på ein Exchange-tenar
+Name[pl]=Książka adresowa na serwerze Exchange
+Name[pt]=Livro de endereços em servidor Exchange
+Name[pt_BR]=Livro de Endereços em um Servidor Exchange
+Name[ru]=Адресная книга на сервере Exchange
+Name[sk]=Adresár na Exchange serveri
+Name[sl]=Adresar na strežniko Exchange
+Name[sr]=Адресар на Exchange серверу
+Name[sr@Latn]=Adresar na Exchange serveru
+Name[sv]=Adressbok på en Exchange-server
+Name[ta]=ஒருமாற்று சேவகனில் முகவரிப்புத்தகம்
+Name[tr]=Bir Exchange Sunucusu üzerinde Adres Defteri
+Name[uk]=Адресна книга на сервері Exchange
+Name[zh_CN]=Exchange 服务器上的地址簿
+Name[zh_TW]=Exchanger 伺服器上的通訊錄
diff --git a/kresources/newexchange/kabc_resourceexchange.cpp b/kresources/newexchange/kabc_resourceexchange.cpp
new file mode 100644
index 000000000..8b32a4fac
--- /dev/null
+++ b/kresources/newexchange/kabc_resourceexchange.cpp
@@ -0,0 +1,48 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "exchangeaddressbookadaptor.h"
+
+#include "kabc_resourceexchange.h"
+#include "groupwaredownloadjob.h"
+#include "groupwareuploadjob.h"
+#include "kresources_groupwareprefs.h"
+
+using namespace KABC;
+
+ResourceExchange::ResourceExchange( const KConfig *config )
+ : ResourceGroupwareBase( config )
+{
+ init();
+ if ( config ) readConfig( config );
+}
+
+void ResourceExchange::init()
+{
+ setType( "ResourceExchange" );
+ setPrefs( createPrefs() );
+ setFolderLister( new KPIM::FolderLister( KPIM::FolderLister::AddressBook ) );
+ setAdaptor( new ExchangeAddressBookAdaptor() );
+
+ ResourceGroupwareBase::init();
+}
+
+#include "kabc_resourceexchange.moc"
diff --git a/kresources/newexchange/kabc_resourceexchange.h b/kresources/newexchange/kabc_resourceexchange.h
new file mode 100644
index 000000000..542b79955
--- /dev/null
+++ b/kresources/newexchange/kabc_resourceexchange.h
@@ -0,0 +1,42 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#ifndef KABC_RESOURCEEXCHANGE_H
+#define KABC_RESOURCEEXCHANGE_H
+
+#include <kabc_resourcegroupwarebase.h>
+
+namespace KABC {
+
+class KDE_EXPORT ResourceExchange : public ResourceGroupwareBase
+{
+ Q_OBJECT
+
+ public:
+ ResourceExchange( const KConfig * );
+/* ResourceExchange( const KURL &url,
+ const QString &user, const QString &password );*/
+ protected:
+ void init();
+};
+
+}
+
+#endif
diff --git a/kresources/newexchange/kabc_resourceexchange_plugin.cpp b/kresources/newexchange/kabc_resourceexchange_plugin.cpp
new file mode 100644
index 000000000..d324be10d
--- /dev/null
+++ b/kresources/newexchange/kabc_resourceexchange_plugin.cpp
@@ -0,0 +1,27 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "kabc_resourceexchange.h"
+#include "kabc_resourcegroupwarebaseconfig.h"
+
+using namespace KABC;
+
+typedef KRES::PluginFactory<ResourceExchange,ResourceGroupwareBaseConfig> ExchangeFactory;
+K_EXPORT_COMPONENT_FACTORY( kabc_newexchange, ExchangeFactory )
diff --git a/kresources/newexchange/kcal_newexchange.desktop b/kresources/newexchange/kcal_newexchange.desktop
new file mode 100644
index 000000000..b94e28ce9
--- /dev/null
+++ b/kresources/newexchange/kcal_newexchange.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=Calendar on an Exchange Server (experimental)
+Name[af]=Kalender op 'n Exchange bediener (eksperimenteel)
+Name[bg]=Календар на сървър Exchange (експериментално)
+Name[ca]=Calendari a un servidor Exchange (experimental)
+Name[cs]=Kalendář na serveru Exchange (experimentální)
+Name[da]=Kalender på en Exchange-server (eksperimentel)
+Name[de]=Kalender auf einem Exchange-Server (experimentell)
+Name[el]=Ημερολόγιο σε εξυπηρετητή Exchange (πειραματικό)
+Name[es]=Calendario en un servidor Exchange (experimental)
+Name[et]=Kalender Exchange-serveris (eksperimentaalne)
+Name[eu]=Egutegia Exchange zerbitzari batean (esperimentala)
+Name[fa]=تقویم روی یک کارساز مبادله )تجربی(
+Name[fi]=Kalenteri Exchange-palvelimella (kokeellinen)
+Name[fr]=Agenda sur un serveur Exchange (expérimental)
+Name[fy]=Aginda op in Exchange-tsjinner (eksperimenteel)
+Name[ga]=Féilire ar Fhreastalaí Exchange (trialach)
+Name[gl]=Calendario nun servidor Exchange (experimental)
+Name[hu]=Exchange 2000-kiszolgáló naptára (kísérleti)
+Name[is]=Dagatal á Exchange þjóni (á tilraunarstigi)
+Name[it]=Calendario su un server Exchange (sperimentale)
+Name[ja]=Exchange サーバのカレンダー (実験版)
+Name[ka]=კალენდარი Exchange სერვერზე (ექსპერიმენტული)
+Name[kk]=Exchange серверіндегі күнтізбе (сынақтағы)
+Name[km]=ប្រតិទិន​លើ​ម៉ាស៊ីន​បម្រើ Exchange (សម្រាប់​អ្នក​មាន​បទពិសោធន៍)
+Name[lt]=Kalendorius Exchange serveryje (eksperimentine tvarka)
+Name[mk]=Календар на Exchange-сервер (експериментално)
+Name[ms]=Kalendar pada pelayan Exchange (ujikaji)
+Name[nb]=Kalender på en Exchange-tjener (forsøksvis)
+Name[nds]=Kalenner op en Exchange-Server (warrt utprobeert)
+Name[ne]=एक्सचेन्ज सर्भरमा क्यालेन्डर (प्रयोगात्मक)
+Name[nl]=Agenda op een Exchange-server (experimenteel)
+Name[nn]=Kalender på ein Exchange-tenar (eksperimentelt)
+Name[pl]=Kalendarz na serwerze Exchange (eksperymentalne)
+Name[pt]=Calendário em servidor Exchange (experimental)
+Name[pt_BR]=Calendário em um Servidor Exchange (experimental)
+Name[ru]=Календарь на сервере Exchange (экспериментально)
+Name[sk]=Kalendár na Exchange serveri (experimentálne)
+Name[sl]=Koledar na strežniku Exchange (poskusno)
+Name[sr]=Календар на Exchange серверу (експериментално)
+Name[sr@Latn]=Kalendar na Exchange serveru (eksperimentalno)
+Name[sv]=Kalender på en Exchange-server (experimentell)
+Name[ta]=பரிமாற்ற சேவகனில் நாட்காட்டி (சோதனைக்குரியது)
+Name[tr]=Bir Exchange Sunucusu üzerinde Takvim (deneyimsel)
+Name[uk]=Календар на сервері Exchange (експериментальне)
+Name[zh_CN]=Exchange 服务器上的日历(试验性)
+Name[zh_TW]=Exchanger 伺服器上的行事曆(實驗中)
+X-KDE-Library=kcal_newexchange
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=calendar
+X-KDE-ResourceType=newexchange
diff --git a/kresources/newexchange/kcal_newexchange_final.desktop b/kresources/newexchange/kcal_newexchange_final.desktop
new file mode 100644
index 000000000..fd159051d
--- /dev/null
+++ b/kresources/newexchange/kcal_newexchange_final.desktop
@@ -0,0 +1,49 @@
+[Desktop Entry]
+Hidden=true
+Name=Calendar on an Exchange Server
+Name[af]=Kalender op 'n Exchange bediener
+Name[bg]=Календар на сървър Exchange
+Name[br]=Deiziadur en ur servijer Exchange
+Name[ca]=Calendari a un servidor Exchange
+Name[cs]=Kalendář na serveru Exchange
+Name[da]=Kalender på en Exchange-server
+Name[de]=Kalender auf einem Exchange-Server
+Name[el]=Ημερολόγιο σε εξυπηρετητή Exchange
+Name[es]=Calendario en un servidor Exchange
+Name[et]=Kalender Exchange-serveris
+Name[eu]=Egutegia Exchange zerbitzari batean
+Name[fa]=تقویم روی یک کارساز مبادله
+Name[fi]=Kalenteri Exchange-palvelimella
+Name[fr]=Agenda sur un serveur Exchange
+Name[fy]=Aginda op in Exchange-tsjinner
+Name[ga]=Féilire ar Fhreastalaí Exchange
+Name[gl]=Calendario nun servidor Exchange
+Name[hu]=Exchange 2000-kiszolgáló naptára
+Name[is]=Dagatal á Exchange þjóni
+Name[it]=Calendario su un server Exchange
+Name[ja]=Exchange サーバのカレンダー
+Name[ka]=კალენდარი Exchange სერვერზე
+Name[kk]=Exchange серверіндегі күнтізбе
+Name[km]=ប្រតិទិន​លើ​ម៉ាស៊ីន​បម្រើ Exchange
+Name[lt]=Kalendorius Exchange serveryje
+Name[mk]=Календар на Exchange-сервер
+Name[ms]=Kalendar pada pelayan Exchange
+Name[nb]=Kalender på en Exchange-tjener
+Name[nds]=Kalenner op en Exchange-Server
+Name[ne]=एक्सचेन्ज सर्भरमा क्यालेन्डर
+Name[nl]=Agenda op een Exchange-server
+Name[nn]=Kalender på ein Exchange-tenar
+Name[pl]=Kalendarz na serwerze Exchange
+Name[pt]=Calendário em servidor Exchange
+Name[pt_BR]=Calendário em um Servidor Exchange
+Name[ru]=Календарь на сервере Exchange
+Name[sk]=Kalendár na Exchange serveri
+Name[sl]=Koledar na strežniku Exchange
+Name[sr]=Календар на Exchange серверу
+Name[sr@Latn]=Kalendar na Exchange serveru
+Name[sv]=Kalender på en Exchange-server
+Name[ta]=ஒரு பரிமாற்ற சேவகனில் நாட்காட்சி
+Name[tr]=Bir Exchange Sunucusu üzerinde Takvim
+Name[uk]=Календар на сервері Exchange
+Name[zh_CN]=Exchange 服务器上的日历
+Name[zh_TW]=Exchanger 伺服器上的行事曆
diff --git a/kresources/newexchange/kcal_resourceexchange.cpp b/kresources/newexchange/kcal_resourceexchange.cpp
new file mode 100644
index 000000000..4c9f7726d
--- /dev/null
+++ b/kresources/newexchange/kcal_resourceexchange.cpp
@@ -0,0 +1,54 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+
+ 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 General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include "exchangecalendaradaptor.h"
+
+#include "kcal_resourceexchange.h"
+#include <groupwaredownloadjob.h>
+#include <groupwareuploadjob.h>
+#include <kresources_groupwareprefs.h>
+
+using namespace KCal;
+
+ResourceExchange::ResourceExchange()
+ : ResourceGroupwareBase()
+{
+ init();
+}
+
+ResourceExchange::ResourceExchange( const KConfig *config )
+ : ResourceGroupwareBase( config )
+{
+ init();
+ if ( config ) readConfig( config );
+}
+
+void ResourceExchange::init()
+{
+ setType( "ResourceExchange" );
+ setPrefs( createPrefs() );
+ setFolderLister( new KPIM::FolderLister( KPIM::FolderLister::Calendar ) );
+ setAdaptor( new ExchangeCalendarAdaptor() );
+
+ ResourceGroupwareBase::init();
+}
+
+#include "kcal_resourceexchange.moc"
diff --git a/kresources/newexchange/kcal_resourceexchange.h b/kresources/newexchange/kcal_resourceexchange.h
new file mode 100644
index 000000000..2a6d01675
--- /dev/null
+++ b/kresources/newexchange/kcal_resourceexchange.h
@@ -0,0 +1,45 @@
+ /*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+
+ 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.
+*/
+#ifndef KCAL_RESOURCEEXCHANGE_H
+#define KCAL_RESOURCEEXCHANGE_H
+
+#include <kcal_resourcegroupwarebase.h>
+
+namespace KCal {
+
+/**
+ This class provides a resource for accessing an Exchange server
+*/
+class KDE_EXPORT ResourceExchange : public ResourceGroupwareBase
+{
+ Q_OBJECT
+ public:
+ ResourceExchange();
+ ResourceExchange( const KConfig * );
+
+ protected:
+ void init();
+};
+
+}
+
+#endif
diff --git a/kresources/newexchange/kcal_resourceexchange_plugin.cpp b/kresources/newexchange/kcal_resourceexchange_plugin.cpp
new file mode 100644
index 000000000..e2b1d5396
--- /dev/null
+++ b/kresources/newexchange/kcal_resourceexchange_plugin.cpp
@@ -0,0 +1,28 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ 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.
+*/
+
+#include "kcal_resourceexchange.h"
+#include "kcal_resourcegroupwarebaseconfig.h"
+
+using namespace KCal;
+
+typedef KRES::PluginFactory< ResourceExchange, ResourceGroupwareBaseConfig > ExchangeFactory;
+K_EXPORT_COMPONENT_FACTORY( kcal_newexchange, ExchangeFactory )