summaryrefslogtreecommitdiffstats
path: root/kresources/slox
diff options
context:
space:
mode:
Diffstat (limited to 'kresources/slox')
-rw-r--r--kresources/slox/Makefile.am51
-rw-r--r--kresources/slox/kabc_ox.desktop47
-rw-r--r--kresources/slox/kabc_slox.desktop52
-rw-r--r--kresources/slox/kabcresourceslox.cpp673
-rw-r--r--kresources/slox/kabcresourceslox.h113
-rw-r--r--kresources/slox/kabcresourceslox_plugin.cpp39
-rw-r--r--kresources/slox/kabcresourcesloxconfig.cpp121
-rw-r--r--kresources/slox/kabcresourcesloxconfig.h61
-rw-r--r--kresources/slox/kabcsloxprefs.kcfgc11
-rw-r--r--kresources/slox/kcal_ox.desktop47
-rw-r--r--kresources/slox/kcal_slox.desktop52
-rw-r--r--kresources/slox/kcalresourceslox.cpp1326
-rw-r--r--kresources/slox/kcalresourceslox.h167
-rw-r--r--kresources/slox/kcalresourceslox_plugin.cpp40
-rw-r--r--kresources/slox/kcalresourcesloxconfig.cpp145
-rw-r--r--kresources/slox/kcalresourcesloxconfig.h75
-rw-r--r--kresources/slox/kcalsloxprefs.kcfgc11
-rw-r--r--kresources/slox/kresources_kabc_slox.kcfg31
-rw-r--r--kresources/slox/kresources_kcal_slox.kcfg38
-rw-r--r--kresources/slox/sloxaccounts.cpp222
-rw-r--r--kresources/slox/sloxaccounts.h66
-rw-r--r--kresources/slox/sloxbase.cpp139
-rw-r--r--kresources/slox/sloxbase.h115
-rw-r--r--kresources/slox/sloxfolder.cpp49
-rw-r--r--kresources/slox/sloxfolder.h55
-rw-r--r--kresources/slox/sloxfolderdialog.cpp125
-rw-r--r--kresources/slox/sloxfolderdialog.h55
-rw-r--r--kresources/slox/sloxfoldermanager.cpp172
-rw-r--r--kresources/slox/sloxfoldermanager.h66
-rw-r--r--kresources/slox/testsloxaccounts.cpp61
-rw-r--r--kresources/slox/webdavhandler.cpp295
-rw-r--r--kresources/slox/webdavhandler.h96
32 files changed, 4616 insertions, 0 deletions
diff --git a/kresources/slox/Makefile.am b/kresources/slox/Makefile.am
new file mode 100644
index 000000000..6cc95f1eb
--- /dev/null
+++ b/kresources/slox/Makefile.am
@@ -0,0 +1,51 @@
+INCLUDES = -I$(top_srcdir) $(all_includes)
+
+
+lib_LTLIBRARIES = libkslox.la libkabc_slox.la libkcal_slox.la
+
+libkslox_la_SOURCES = sloxaccounts.cpp webdavhandler.cpp \
+ sloxfolder.cpp sloxfoldermanager.cpp \
+ sloxfolderdialog.cpp sloxbase.cpp
+libkslox_la_LDFLAGS = $(all_libraries)
+libkslox_la_LIBADD = $(top_builddir)/libkcal/libkcal.la \
+ $(top_builddir)/libkdepim/libkdepim.la
+
+libkcal_slox_la_SOURCES = kcalresourceslox.cpp kcalresourcesloxconfig.cpp \
+ kcalsloxprefs.kcfgc
+libkcal_slox_la_LDFLAGS = $(all_libraries)
+libkcal_slox_la_LIBADD = libkslox.la $(top_builddir)/libkcal/libkcal.la
+
+libkabc_slox_la_SOURCES = kabcresourceslox.cpp kabcresourcesloxconfig.cpp \
+ kabcsloxprefs.kcfgc
+libkabc_slox_la_LDFLAGS = $(all_libraries)
+libkabc_slox_la_LIBADD = libkslox.la -lkabc
+
+
+kde_module_LTLIBRARIES = kcal_slox.la kabc_slox.la
+
+kcal_slox_la_SOURCES = kcalresourceslox_plugin.cpp
+kcal_slox_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kcal_slox_la_LIBADD = libkcal_slox.la
+
+kabc_slox_la_SOURCES = kabcresourceslox_plugin.cpp
+kabc_slox_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kabc_slox_la_LIBADD = libkabc_slox.la
+
+
+EXTRA_PROGRAMS = testsloxaccounts
+
+testsloxaccounts_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+testsloxaccounts_LDADD = libkslox.la
+testsloxaccounts_SOURCES = testsloxaccounts.cpp
+
+
+kcal_servicedir = $(kde_servicesdir)/kresources/kcal
+kcal_service_DATA = kcal_slox.desktop kcal_ox.desktop
+
+kabc_servicedir = $(kde_servicesdir)/kresources/kabc
+kabc_service_DATA = kabc_slox.desktop kabc_ox.desktop
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kabc_slox.pot
diff --git a/kresources/slox/kabc_ox.desktop b/kresources/slox/kabc_ox.desktop
new file mode 100644
index 000000000..4f4fb8c22
--- /dev/null
+++ b/kresources/slox/kabc_ox.desktop
@@ -0,0 +1,47 @@
+[Desktop Entry]
+Name=OpenXchange Server
+Name[af]=OpenXchange bediener
+Name[bg]=Сървър OpenXchange
+Name[br]=Servijer OpenXchange
+Name[ca]=Servidor OpenXchange
+Name[da]=Openxchange-server
+Name[el]=Εξυπηρετητής OpenXchange
+Name[es]=Servidor OpenXchange
+Name[et]=OpenXchange server
+Name[eu]=OpenXchange zerbitzaria
+Name[fa]=کارساز OpenXchange
+Name[fi]=OpenXchange-palvelin
+Name[fr]=Serveur OpenXchange
+Name[fy]=OpenXchange-tsjinner
+Name[ga]=Freastalaí Openexchange
+Name[gl]=Servidor OpenXchange
+Name[hu]=OpenXchange-kiszolgáló
+Name[is]=OpenXchange þjónn
+Name[ja]=OpenXchange サーバ
+Name[ka]=Openexchange სერვერი
+Name[kk]=OpenXchange сервері
+Name[km]=ម៉ាស៊ីន​បម្រើ OpenXchange
+Name[lt]=OpenXchange serveris
+Name[mk]=OpenXchange-сервер
+Name[nb]=OpenExchange-tjener
+Name[nds]=OpenXchange-Server
+Name[ne]=ओपन एक्सचेन्ज सर्भर
+Name[nl]=OpenXchange-server
+Name[nn]=OpenXchange-tenar
+Name[pl]=Server OpenXchange
+Name[pt]=Servidor OpenXchange
+Name[pt_BR]=Servidor OpenXchange
+Name[ru]=Сервер OpenXchange
+Name[sl]=Strežnik OpenXchange
+Name[sr]=Openexchange сервер
+Name[sr@Latn]=Openexchange server
+Name[sv]=Openxchange-server
+Name[tr]=OpenXchange Sunucusu
+Name[uk]=Сервер OpenXchange
+Name[zh_CN]=OpenXchange 服务器
+Name[zh_TW]=OpenXchange 伺服器
+X-KDE-Library=kabc_slox
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=ox
diff --git a/kresources/slox/kabc_slox.desktop b/kresources/slox/kabc_slox.desktop
new file mode 100644
index 000000000..bdfce204e
--- /dev/null
+++ b/kresources/slox/kabc_slox.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=SUSE LINUX Openexchange Server
+Name[af]=SuSE Linux OpenExchange bediener
+Name[bg]=Сървър SUSE LINUX Openexchange
+Name[br]=Servijer Openexchange SUSE LINUX
+Name[ca]=Servidor SUSE LINUX Openexchange
+Name[cs]=SUSE LINUX Openexchange server
+Name[da]=SUSE Linux Openexchange-server
+Name[de]=SUSE LINUX Openexchange-Server
+Name[el]=Εξυπηρετητή SUSE LINUX Openexchange
+Name[es]=Servidor Openexchange de SUSE LINUX
+Name[et]=SUSE LINUX Openexchange server
+Name[eu]=SUSE LINUX Openexchange zerbitzaria
+Name[fa]=کارساز SUSE LINUX Openexchange
+Name[fi]=Suse Linux Openexchange -palvelin
+Name[fr]=Serveur SUSE Linux Openexchange
+Name[fy]=SUSE LINUX Openexchange-tsjinner
+Name[ga]=Freastalaí Openexchange SUSE LINUX
+Name[gl]=Servidor SUSE LINUX Openexchange
+Name[hu]=SUSE LINUX Openexchange-kiszolgáló
+Name[is]=SUSE LINUX Openexchange þjónn
+Name[it]=Server SUSE LINUX Openexchange
+Name[ja]=SUSE LINUX Openexchange サーバ
+Name[ka]= SUSE LINUX Openexchange სერვერი
+Name[kk]=SUSE LINUX Openexchange сервері
+Name[km]=ម៉ាស៊ីន​បម្រើ Openexchange របស់​ស៊ូស៊ីលីនីក
+Name[lt]=SUSE LINUX Openexchange serveris
+Name[mk]=SUSE LINUX Openexchange-сервер
+Name[ms]=Pelayan SUSE LINUX Openexchange
+Name[nb]=SUSE LINUX Openexchange-tjener
+Name[nds]=SUSE-Openexchangeserver
+Name[ne]=SUSE LINUX ओपन एक्सचेन्ज सर्भर
+Name[nl]=SUSE LINUX Openexchange-server
+Name[nn]=SUSE LINUX Openexchange-tenar
+Name[pl]=Server SUSE LINUX Openexchange
+Name[pt]=Servidor SUSE LINUX Openexchange
+Name[pt_BR]=Servidor OpenExchange do SUSE Linux (SLOX)
+Name[ru]=Сервер SUSE LINUX Openexchange
+Name[sl]=Strežnik SUSE LINUX Openexchange
+Name[sr]=Openexchange сервер SUSE-овог Linux-а
+Name[sr@Latn]=Openexchange server SUSE-ovog Linux-a
+Name[sv]=SUSE Linux Openexchange-server
+Name[ta]=SUSE LINUX திறந்த பரிமாற்ற சேவகன்
+Name[tr]=SUSE LINUX Openexchange Sunucusu
+Name[uk]=Сервер SUSE LINUX Openexchange
+Name[zh_CN]=SUSE LINUX Openexchange 服务器
+Name[zh_TW]=SUSE LINUX Openexchange 伺服器
+X-KDE-Library=kabc_slox
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=slox
diff --git a/kresources/slox/kabcresourceslox.cpp b/kresources/slox/kabcresourceslox.cpp
new file mode 100644
index 000000000..e6bf326c3
--- /dev/null
+++ b/kresources/slox/kabcresourceslox.cpp
@@ -0,0 +1,673 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2005 Volker Krause <volker.krause@rwth-aachen.de>
+
+ 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 <qapplication.h>
+
+#include <kabc/picture.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmdcodec.h>
+#include <kstandarddirs.h>
+#include <kstringhandler.h>
+#include <libkdepim/kpimprefs.h>
+#include <libkdepim/progressmanager.h>
+#include <kio/davjob.h>
+
+#include "webdavhandler.h"
+#include "sloxaccounts.h"
+#include "kabcsloxprefs.h"
+
+#include "kabcresourceslox.h"
+
+using namespace KABC;
+
+ResourceSlox::ResourceSlox( const KConfig *config )
+ : ResourceCached( config ), SloxBase( this )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ if ( config ) {
+ readConfig( config );
+ }
+}
+
+ResourceSlox::ResourceSlox( const KURL &url,
+ const QString &user, const QString &password )
+ : ResourceCached( 0 ), SloxBase( this )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ mPrefs->setUrl( url.url() );
+ mPrefs->setUser( user );
+ mPrefs->setPassword( password );
+}
+
+void ResourceSlox::init()
+{
+ mPrefs = new SloxPrefs;
+ mWebdavHandler.setResource( this );
+
+ mDownloadJob = 0;
+ mUploadJob = 0;
+ mDownloadProgress = 0;
+ mUploadProgress = 0;
+
+ // phone number mapping for SLOX
+ mPhoneNumberSloxMap[PhoneNumber::Work] << "phone" << "phone2";
+ mPhoneNumberSloxMap[PhoneNumber::Home] << "privatephone" << "privatephone2";
+ mPhoneNumberSloxMap[PhoneNumber::Cell | PhoneNumber::Work] << "mobile" << "mobile2";
+ mPhoneNumberSloxMap[PhoneNumber::Cell | PhoneNumber::Home] << "privatemobile" << "privatemobile2";
+ mPhoneNumberSloxMap[PhoneNumber::Fax | PhoneNumber::Work] << "fax" << "fax2";
+ mPhoneNumberSloxMap[PhoneNumber::Fax | PhoneNumber::Home] << "privatefax" << "privatefax2";
+
+ // phone number mapping for OX (mapping partly taken from Kolab)
+ mPhoneNumberOxMap[PhoneNumber::Work] << "phone_business" << "phone_business2";
+ mPhoneNumberOxMap[PhoneNumber::Home] << "phone_home" << "phone_home2";
+ mPhoneNumberOxMap[PhoneNumber::Cell] << "mobile1"<< "mobile2";
+ mPhoneNumberOxMap[PhoneNumber::Fax | PhoneNumber::Work] << "fax_business";
+ mPhoneNumberOxMap[PhoneNumber::Fax | PhoneNumber::Home] << "fax_home";
+ mPhoneNumberOxMap[PhoneNumber::Fax] << "fax_other";
+ mPhoneNumberOxMap[PhoneNumber::Car] << "phone_car";
+ mPhoneNumberOxMap[PhoneNumber::Isdn] << "isdn";
+ mPhoneNumberOxMap[PhoneNumber::Pager] << "pager";
+ mPhoneNumberOxMap[PhoneNumber::Pref] << "primary";
+ mPhoneNumberOxMap[PhoneNumber::Voice] << "callback";
+ mPhoneNumberOxMap[PhoneNumber::Video] << "radio";
+ mPhoneNumberOxMap[PhoneNumber::Bbs] << "tty_tdd";
+ mPhoneNumberOxMap[PhoneNumber::Modem] << "telex";
+ mPhoneNumberOxMap[PhoneNumber::Pcs] << "phone_assistant";
+ mPhoneNumberOxMap[PhoneNumber::Msg] << "phone_company";
+}
+
+ResourceSlox::~ResourceSlox()
+{
+ kdDebug() << "KABC::~ResourceSlox()" << endl;
+
+ if ( mDownloadJob ) mDownloadJob->kill();
+
+ delete mPrefs;
+
+ kdDebug() << "KABC::~ResourceSlox() done" << endl;
+}
+
+void ResourceSlox::readConfig( const KConfig * )
+{
+ mPrefs->readConfig();
+}
+
+void ResourceSlox::writeConfig( KConfig *config )
+{
+ kdDebug() << "ResourceSlox::writeConfig() " << endl;
+ kdDebug() << mPrefs->url() << endl;
+
+ Resource::writeConfig( config );
+
+ mPrefs->writeConfig();
+}
+
+Ticket *ResourceSlox::requestSaveTicket()
+{
+ if ( !addressBook() ) {
+ kdDebug(5700) << "no addressbook" << endl;
+ return 0;
+ }
+
+ return createTicket( this );
+}
+
+void ResourceSlox::releaseSaveTicket( Ticket *ticket )
+{
+ delete ticket;
+}
+
+bool ResourceSlox::doOpen()
+{
+ return true;
+}
+
+void ResourceSlox::doClose()
+{
+ cancelDownload();
+ cancelUpload();
+}
+
+bool ResourceSlox::load()
+{
+ kdDebug() << "KABC::ResourceSlox::load()" << endl;
+
+#if 0
+ return asyncLoad();
+#else
+ kdDebug() << "KABC::ResourceSlox::load() is a nop." << endl;
+ return true;
+#endif
+}
+
+bool ResourceSlox::asyncLoad()
+{
+ kdDebug() << "KABC::ResourceSlox::asyncLoad()" << endl;
+
+ if ( mDownloadJob ) {
+ kdDebug() << "KABC::ResourceSlox::asyncLoad(): Loading still in progress."
+ << endl;
+ return true;
+ }
+
+ loadCache();
+ clearChanges();
+
+ KURL url = mPrefs->url();
+ url.setPath( "/servlet/webdav.contacts/" );
+ url.setUser( mPrefs->user() );
+ url.setPass( mPrefs->password() );
+
+ QString lastsync = "0";
+ if ( mPrefs->useLastSync() ) {
+ QDateTime dt = mPrefs->lastSync();
+ if ( dt.isValid() )
+ lastsync = WebdavHandler::qDateTimeToSlox( dt.addDays( -1 ) );
+ }
+
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ QDomElement prop = WebdavHandler::addDavElement( doc, root, "prop" );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( LastSync ), lastsync );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( FolderId ), mPrefs->folderId() );
+ if ( type() == "ox" ) {
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "NEW_AND_MODIFIED" );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "DELETED" );
+ } else
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "all" );
+
+ kdDebug() << "REQUEST CONTACTS: \n" << doc.toString( 2 ) << endl;
+
+ mDownloadJob = KIO::davPropFind( url, doc, "0", false );
+ connect( mDownloadJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotResult( KIO::Job * ) ) );
+ connect( mDownloadJob, SIGNAL( percent( KIO::Job *, unsigned long ) ),
+ SLOT( slotProgress( KIO::Job *, unsigned long ) ) );
+
+ mDownloadProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Downloading contacts") );
+ connect( mDownloadProgress,
+ SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ SLOT( cancelDownload() ) );
+
+ mPrefs->setLastSync( QDateTime::currentDateTime() );
+
+ return true;
+}
+
+void ResourceSlox::slotResult( KIO::Job *job )
+{
+ kdDebug() << "ResourceSlox::slotResult()" << endl;
+
+ if ( job->error() ) {
+ job->showErrorDialog( 0 );
+ } else {
+ kdDebug() << "ResourceSlox::slotResult() success" << endl;
+
+ QDomDocument doc = mDownloadJob->response();
+
+ mWebdavHandler.log( doc.toString( 2 ) );
+
+ QValueList<SloxItem> items = WebdavHandler::getSloxItems( this, doc );
+
+ bool changed = false;
+
+ QValueList<SloxItem>::ConstIterator it;
+ for( it = items.begin(); it != items.end(); ++it ) {
+ SloxItem item = *it;
+ QString uid = "kresources_slox_kabc_" + item.sloxId;
+ if ( item.status == SloxItem::Delete ) {
+ QMap<QString,Addressee>::Iterator it;
+ it = mAddrMap.find( uid );
+ if ( it != mAddrMap.end() ) {
+ mAddrMap.remove( it );
+ changed = true;
+ }
+ } else if ( item.status == SloxItem::Create ) {
+ Addressee a;
+ a.setUid( uid );
+
+ mWebdavHandler.clearSloxAttributeStatus();
+
+ QDomNode n;
+ for( n = item.domNode.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement e = n.toElement();
+ mWebdavHandler.parseSloxAttribute( e );
+ parseContactAttribute( e, a );
+ }
+
+ mWebdavHandler.setSloxAttributes( a );
+
+ a.setResource( this );
+ a.setChanged( false );
+
+ mAddrMap.replace( a.uid(), a );
+
+ // TODO: Do we need to try to associate addressees with slox accounts?
+
+ changed = true;
+ }
+ }
+
+ clearChanges();
+ saveCache();
+ }
+
+ mDownloadJob = 0;
+ mDownloadProgress->setComplete();
+ mDownloadProgress = 0;
+
+ emit loadingFinished( this );
+}
+
+void ResourceSlox::slotUploadResult( KIO::Job *job )
+{
+ kdDebug() << "ResourceSlox::slotUploadResult()" << endl;
+
+ if ( job->error() ) {
+ job->showErrorDialog( 0 );
+ } else {
+ kdDebug() << "ResourceSlox::slotUploadResult() success" << endl;
+
+ QDomDocument doc = mUploadJob->response();
+ kdDebug() << k_funcinfo << "Upload result: " << endl;
+ kdDebug() << doc.toString() << endl;
+
+ QValueList<SloxItem> items = WebdavHandler::getSloxItems( this, doc );
+
+ QValueList<SloxItem>::ConstIterator it;
+ for( it = items.begin(); it != items.end(); ++it ) {
+ SloxItem item = *it;
+ if ( !item.response.contains( "200" ) ) {
+ savingError( this, item.response + "\n" + item.responseDescription );
+ continue;
+ }
+ if ( item.status == SloxItem::New ) {
+ QMap<QString,Addressee>::Iterator search_res;
+ search_res = mAddrMap.find( item.clientId );
+ if ( search_res != mAddrMap.end() ) {
+ // use the id provided by the server
+ Addressee a = *search_res;
+ mAddrMap.remove( search_res );
+ a.setUid( "kresources_slox_kabc_" + item.sloxId );
+ a.setResource( this );
+ a.setChanged( false );
+ mAddrMap.replace( a.uid(), a );
+ saveCache();
+ }
+ }
+ }
+ }
+
+ clearChange( mUploadAddressee );
+
+ mUploadJob = 0;
+ mUploadProgress->setComplete();
+ mUploadProgress = 0;
+
+ uploadContacts();
+}
+
+void ResourceSlox::parseContactAttribute( const QDomElement &e, Addressee &a )
+{
+ QString text = decodeText( e.text() );
+ if ( text.isEmpty() ) return;
+ QString tag = e.tagName();
+ int pnType = 0;
+
+ if ( tag == fieldName( Birthday ) ) {
+ QDateTime dt = WebdavHandler::sloxToQDateTime( text );
+ a.setBirthday( dt.date() );
+ } else if ( tag == fieldName( Role ) ) {
+ a.setRole( text );
+ } else if ( tag == "salutation" ) { // what's this in OX?
+ a.setPrefix( text );
+ } else if ( tag == fieldName( Title ) ) {
+ a.setTitle( text );
+ } else if ( tag == fieldName( Organization ) ) {
+ a.setOrganization( text );
+ } else if ( tag == fieldName( Department ) ) {
+ a.insertCustom( "KADDRESSBOOK", "X-Department", text );
+ } else if ( tag == fieldName( FamilyName ) ) {
+ a.setFamilyName( text );
+ } else if ( tag == fieldName( GivenName) ) {
+ a.setGivenName( text );
+ } else if ( tag == fieldName( SecondName ) ) {
+ a.setAdditionalName( text );
+ } else if ( tag == fieldName( DisplayName ) ) {
+ a.setFormattedName( text );
+ } else if ( tag == fieldName( Suffix ) ) {
+ a.setSuffix( text );
+ } else if ( tag == fieldName( PrimaryEmail ) ) {
+ a.insertEmail( text, true );
+ } else if ( (pnType = phoneNumberType( tag )) ) {
+ a.insertPhoneNumber( PhoneNumber( text, pnType ) );
+ } else if ( tag == fieldName( Comment ) ) {
+ a.setNote( text );
+ } else if ( tag == fieldName( SecondaryEmail1 ) || tag == fieldName( SecondaryEmail2 ) ||
+ tag == fieldName( SecondaryEmail3 ) ) {
+ a.insertEmail( text );
+ } else if ( tag == fieldName( Url ) ) {
+ a.setUrl( text );
+ } else if ( tag == fieldName( Image ) ) {
+ QByteArray decodedPicture;
+ KCodecs::base64Decode( text.utf8(), decodedPicture );
+ a.setPhoto( Picture( QImage( decodedPicture ) ) );
+ } else if ( tag == fieldName( NickName ) ) {
+ a.setNickName( text );
+ } else if ( tag == fieldName( InstantMsg ) ) {
+ a.insertCustom( "KADDRESSBOOK", "X-IMAddress", text );
+ } else if ( tag == fieldName( Office ) ) {
+ a.insertCustom( "KADDRESSBOOK", "X-Office", text );
+ } else if ( tag == fieldName( Profession ) ) {
+ a.insertCustom( "KADDRESSBOOK", "X-Profession", text );
+ } else if ( tag == fieldName( ManagersName ) ) {
+ a.insertCustom( "KADDRESSBOOK", "X-ManagersName", text );
+ } else if ( tag == fieldName( AssistantsName ) ) {
+ a.insertCustom( "KADDRESSBOOK", "X-AssistantsName", text );
+ } else if ( tag == fieldName( SpousesName ) ) {
+ a.insertCustom( "KADDRESSBOOK", "X-SpousesName", text );
+ } else if ( tag == fieldName( Anniversary ) ) {
+ QDateTime dt = WebdavHandler::sloxToQDateTime( text );
+ a.insertCustom( "KADDRESSBOOK", "X-Anniversary", dt.toString( Qt::ISODate ) );
+ } else if ( tag == fieldName( Categories ) ) {
+ a.setCategories( QStringList::split( QRegExp(",\\s*"), text ) );
+ } else if ( type() == "ox" ) { // FIXME: Address reading is missing for SLOX
+ // read addresses
+ Address addr;
+ if ( tag.startsWith( fieldName( BusinessPrefix ) ) ) {
+ addr = a.address( KABC::Address::Work );
+ } else if ( tag.startsWith( fieldName( OtherPrefix ) ) ) {
+ addr = a.address( 0 );
+ } else {
+ addr = a.address( KABC::Address::Home );
+ }
+ if ( tag.endsWith( fieldName( Street ) ) ) {
+ addr.setStreet( text );
+ } else if ( tag.endsWith( fieldName( PostalCode ) ) ) {
+ addr.setPostalCode( text );
+ } else if ( tag.endsWith( fieldName( City ) ) ) {
+ addr.setLocality( text );
+ } else if ( tag.endsWith( fieldName( State ) ) ) {
+ addr.setRegion( text );
+ } else if ( tag.endsWith( fieldName( Country ) ) ) {
+ addr.setCountry( text );
+ }
+ a.insertAddress( addr );
+ }
+}
+
+int ResourceSlox::phoneNumberType( const QString &fieldName ) const
+{
+ QMap<int, QStringList> pnmap;
+ if ( type() == "ox" )
+ pnmap = mPhoneNumberOxMap;
+ else
+ pnmap = mPhoneNumberSloxMap;
+ QMap<int, QStringList>::ConstIterator it;
+ for ( it = pnmap.begin(); it != pnmap.end(); ++it ) {
+ QStringList l = it.data();
+ QStringList::ConstIterator it2;
+ for ( it2 = l.begin(); it2 != l.end(); ++it2 )
+ if ( (*it2) == fieldName )
+ return it.key();
+ }
+ return 0;
+}
+
+bool ResourceSlox::save( Ticket* )
+{
+ kdDebug() << k_funcinfo << endl;
+
+ if ( readOnly() || !hasChanges() || type() != "ox" ) {
+ emit savingFinished( this );
+ return true;
+ }
+
+ if ( mDownloadJob ) {
+ kdWarning() << k_funcinfo << "download still in progress" << endl;
+ return false;
+ }
+ if ( mUploadJob ) {
+ kdWarning() << k_funcinfo << "upload still in progress" << endl;
+ return false;
+ }
+
+ saveCache();
+ uploadContacts();
+ return true;
+}
+
+bool ResourceSlox::asyncSave( Ticket* )
+{
+ return false; // readonly
+}
+
+void ResourceSlox::uploadContacts()
+{
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "propertyupdate" );
+ QDomElement set = WebdavHandler::addDavElement( doc, root, "set" );
+ QDomElement prop = WebdavHandler::addDavElement( doc, set, "prop" );
+
+ bool isDelete = false;
+
+ KABC::Addressee::List addedAddr = addedAddressees();
+ KABC::Addressee::List changedAddr = changedAddressees();
+ KABC::Addressee::List deletedAddr = deletedAddressees();
+
+ if ( !addedAddr.isEmpty() ) {
+ mUploadAddressee = addedAddr.first();
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ClientId ), mUploadAddressee.uid() );
+ } else if ( !changedAddr.isEmpty() ) {
+ mUploadAddressee = changedAddr.first();
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectId ),
+ mUploadAddressee.uid().remove( 0, sizeof("kresources_slox_kabc_") - 1) );
+ } else if ( !deletedAddr.isEmpty() ) {
+ mUploadAddressee = deletedAddr.first();
+ isDelete = true;
+ } else {
+ kdDebug() << k_funcinfo << "Upload finished." << endl;
+ emit savingFinished( this );
+ return;
+ }
+
+ if ( !isDelete ) {
+ createAddresseeFields( doc, prop, mUploadAddressee );
+ } else {
+ QString tmp_uid = mUploadAddressee.uid().remove( 0, sizeof("kresources_slox_kabc_") - 1); // remove prefix from uid
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectId ), tmp_uid );
+ WebdavHandler::addSloxElement( this, doc, prop, "method", "DELETE" );
+ }
+
+ kdDebug() << k_funcinfo << doc.toString() << endl;
+
+ KURL url = mPrefs->url();
+ url.setPath( "/servlet/webdav.contacts/" );
+ url.setUser( mPrefs->user() );
+ url.setPass( mPrefs->password() );
+
+ mUploadJob = KIO::davPropPatch( url, doc, false );
+ connect( mUploadJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotUploadResult( KIO::Job * ) ) );
+ connect( mUploadJob, SIGNAL( percent( KIO::Job *, unsigned long ) ),
+ SLOT( slotProgress( KIO::Job *, unsigned long ) ) );
+
+ mUploadProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Uploading contacts") );
+ connect( mUploadProgress,
+ SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ SLOT( cancelUpload() ) );
+}
+
+void ResourceSlox::createAddresseeFields( QDomDocument &doc, QDomElement &prop,
+ const Addressee &a )
+{
+ // choose addressbook
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( FolderId ), mPrefs->folderId() );
+
+ // person
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( GivenName ), a.givenName() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( FamilyName ), a.familyName() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Title ), a.title() );
+ if ( !a.birthday().isNull() )
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Birthday ),
+ WebdavHandler::qDateTimeToSlox( a.birthday() ) );
+ else
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Birthday ) );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Role ), a.role() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Department ),
+ a.custom( "KADDRESSBOOK", "X-Department" ) );
+ if ( type() == "ox" ) { // OX only fields
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( DisplayName ), a.formattedName() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( SecondName ), a.additionalName() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Suffix ), a.suffix() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Organization ), a.organization() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( NickName ), a.nickName() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( InstantMsg ),
+ a.custom( "KADDRESSBOOK", "X-IMAddress" ) );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Office ),
+ a.custom( "KADDRESSBOOK", "X-Office" ) );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Profession ),
+ a.custom( "KADDRESSBOOK", "X-Profession" ) );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ManagersName ),
+ a.custom( "KADDRESSBOOK", "X-ManagersName" ) );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( AssistantsName ),
+ a.custom( "KADDRESSBOOK", "X-AssistantsName" ) );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( SpousesName ),
+ a.custom( "KADDRESSBOOK", "X-SpousesName" ) );
+ QString anniversary = a.custom( "KADDRESSBOOK", "X-Anniversary" );
+ if ( !anniversary.isEmpty() )
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Anniversary ),
+ WebdavHandler::qDateTimeToSlox( QDateTime::fromString( anniversary, Qt::ISODate ).date() ) );
+ else
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Anniversary ) );
+ }
+
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Url ), a.url().url() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Comment ), a.note() );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Categories ), a.categories().join( ", " ) );
+
+ // emails
+ QStringList email_list = a.emails();
+ QStringList::const_iterator emails_it = email_list.begin();
+ if ( emails_it != email_list.end() )
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( PrimaryEmail ), *(emails_it++) );
+ if ( emails_it != email_list.end() )
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( SecondaryEmail1 ), *(emails_it++) );
+ if ( emails_it != email_list.end() )
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( SecondaryEmail2 ), *(emails_it++) );
+
+ // phone numbers
+ PhoneNumber::List pnlist = a.phoneNumbers();
+ QMap<int, QStringList> pnSaveMap;
+ if ( type() == "ox" )
+ pnSaveMap = mPhoneNumberOxMap;
+ else
+ pnSaveMap = mPhoneNumberSloxMap;
+ for ( PhoneNumber::List::ConstIterator it = pnlist.begin() ; it != pnlist.end(); ++it ) {
+ if ( pnSaveMap.contains( (*it).type() ) ) {
+ QStringList l = pnSaveMap[(*it).type()];
+ QString fn = l.first();
+ l.remove( l.begin() );
+ if ( !l.isEmpty() )
+ pnSaveMap[(*it).type()] = l;
+ else
+ pnSaveMap.remove( (*it).type() );
+ WebdavHandler::addSloxElement( this, doc, prop, fn, (*it).number() );
+ } else
+ kdDebug() << k_funcinfo << "Can't save phone number " << (*it).number() << " of type " << (*it).type() << endl;
+ }
+ // send empty fields for the remaining ohone number fields
+ // it's not possible to delete phone numbers otherwise
+ for ( QMap<int, QStringList>::ConstIterator it = pnSaveMap.begin(); it != pnSaveMap.end(); ++it ) {
+ QStringList l = it.data();
+ for ( QStringList::ConstIterator it2 = l.begin(); it2 != l.end(); ++it2 )
+ WebdavHandler::addSloxElement( this, doc, prop, (*it2) );
+ }
+
+ // write addresses
+ createAddressFields( doc, prop, fieldName( HomePrefix ), a.address( KABC::Address::Home ) );
+ if ( type() == "ox" ) {
+ createAddressFields( doc, prop, fieldName( BusinessPrefix ), a.address( KABC::Address::Work ) );
+ createAddressFields( doc, prop, fieldName( OtherPrefix ), a.address( 0 ) );
+ }
+}
+
+void KABC::ResourceSlox::createAddressFields( QDomDocument &doc, QDomElement &parent,
+ const QString &prefix, const KABC::Address &addr )
+{
+ WebdavHandler::addSloxElement( this, doc, parent, prefix + fieldName( Street ), addr.street() );
+ WebdavHandler::addSloxElement( this, doc, parent, prefix + fieldName( PostalCode ), addr.postalCode() );
+ WebdavHandler::addSloxElement( this, doc, parent, prefix + fieldName( City ), addr.locality() );
+ WebdavHandler::addSloxElement( this, doc, parent, prefix + fieldName( State ), addr.region() );
+ WebdavHandler::addSloxElement( this, doc, parent, prefix + fieldName( Country ), addr.country() );
+}
+
+void ResourceSlox::slotProgress( KIO::Job *job, unsigned long percent )
+{
+ if ( mDownloadProgress && job == mDownloadJob )
+ mDownloadProgress->setProgress( percent );
+ else if ( mUploadProgress && job == mUploadJob )
+ mUploadProgress->setProgress( percent );
+}
+
+void ResourceSlox::cancelDownload()
+{
+ if ( mDownloadJob ) mDownloadJob->kill();
+ mDownloadJob = 0;
+ if ( mDownloadProgress ) mDownloadProgress->setComplete();
+ mDownloadProgress = 0;
+}
+
+void ResourceSlox::cancelUpload()
+{
+ if ( mUploadJob ) mUploadJob->kill();
+ mUploadJob = 0;
+ if ( mUploadProgress ) mUploadProgress->setComplete();
+ mUploadProgress = 0;
+}
+
+void ResourceSlox::setReadOnly( bool b )
+{
+ if ( type() == "ox" )
+ KABC::Resource::setReadOnly( b );
+ else
+ KABC::Resource::setReadOnly( true );
+}
+
+bool ResourceSlox::readOnly() const
+{
+ if ( type() == "ox" )
+ return KABC::Resource::readOnly();
+ else
+ return true;
+}
+
+#include "kabcresourceslox.moc"
diff --git a/kresources/slox/kabcresourceslox.h b/kresources/slox/kabcresourceslox.h
new file mode 100644
index 000000000..066fdeaa4
--- /dev/null
+++ b/kresources/slox/kabcresourceslox.h
@@ -0,0 +1,113 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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_RESOURCESLOX_H
+#define KABC_RESOURCESLOX_H
+
+#include "sloxbase.h"
+#include "webdavhandler.h"
+
+#include <libkdepim/kabcresourcecached.h>
+#include <kdepimmacros.h>
+#include <kabc/addressee.h>
+
+#include <qmap.h>
+#include <qdom.h>
+
+namespace KIO {
+class DavJob;
+class Job;
+}
+
+namespace KPIM {
+class ProgressItem;
+}
+
+class KConfig;
+
+namespace KABC {
+
+class SloxPrefs;
+
+class KDE_EXPORT ResourceSlox : public ResourceCached, public SloxBase
+{
+ Q_OBJECT
+ public:
+ ResourceSlox( const KConfig * );
+ ResourceSlox( const KURL &url,
+ const QString &user, const QString &password );
+ ~ResourceSlox();
+
+ void readConfig( const KConfig * );
+ void writeConfig( KConfig * );
+
+ SloxPrefs *prefs() const { return mPrefs; }
+
+ bool doOpen();
+ void doClose();
+
+ Ticket *requestSaveTicket();
+ void releaseSaveTicket( Ticket* );
+
+ bool load();
+ bool asyncLoad();
+ bool save( Ticket * );
+ bool asyncSave( Ticket * );
+
+ void setReadOnly( bool );
+ bool readOnly() const;
+
+ protected:
+ void init();
+
+ int phoneNumberType( const QString &fieldName ) const;
+ void parseContactAttribute( const QDomElement &e, Addressee &a );
+
+ void createAddresseeFields( QDomDocument &doc, QDomElement &prop, const Addressee &a );
+ void createAddressFields( QDomDocument &doc, QDomElement &parent,
+ const QString &prefix, const KABC::Address &addr );
+
+ void uploadContacts();
+
+ protected slots:
+ void slotResult( KIO::Job *job );
+ void slotUploadResult( KIO::Job *job );
+ void slotProgress( KIO::Job *job, unsigned long percent );
+
+ void cancelDownload();
+ void cancelUpload();
+
+ private:
+ SloxPrefs *mPrefs;
+
+ KIO::DavJob *mDownloadJob;
+ KIO::DavJob *mUploadJob;
+ KPIM::ProgressItem *mDownloadProgress;
+ KPIM::ProgressItem *mUploadProgress;
+
+ WebdavHandler mWebdavHandler;
+
+ KABC::Addressee mUploadAddressee;
+
+ QMap<int, QStringList> mPhoneNumberSloxMap, mPhoneNumberOxMap;
+};
+
+}
+
+#endif
diff --git a/kresources/slox/kabcresourceslox_plugin.cpp b/kresources/slox/kabcresourceslox_plugin.cpp
new file mode 100644
index 000000000..73152673a
--- /dev/null
+++ b/kresources/slox/kabcresourceslox_plugin.cpp
@@ -0,0 +1,39 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 "kabcresourceslox.h"
+#include "kabcresourcesloxconfig.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+
+using namespace KABC;
+
+typedef KRES::PluginFactory< ResourceSlox, ResourceSloxConfig > SloxFactory;
+
+extern "C"
+{
+ void *init_kabc_slox()
+ {
+ KGlobal::locale()->insertCatalogue( "libkcal" );
+ KGlobal::locale()->insertCatalogue( "kabc_slox" );
+ return new SloxFactory;
+ }
+}
diff --git a/kresources/slox/kabcresourcesloxconfig.cpp b/kresources/slox/kabcresourcesloxconfig.cpp
new file mode 100644
index 000000000..3df5636be
--- /dev/null
+++ b/kresources/slox/kabcresourcesloxconfig.cpp
@@ -0,0 +1,121 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 "kabcresourcesloxconfig.h"
+
+#include "kabcresourceslox.h"
+#include "kabcsloxprefs.h"
+#include "sloxbase.h"
+#include "sloxfolder.h"
+#include "sloxfolderdialog.h"
+#include "sloxfoldermanager.h"
+
+#include <kdebug.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <klineedit.h>
+#include <kurlrequester.h>
+
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+using namespace KABC;
+
+ResourceSloxConfig::ResourceSloxConfig( QWidget* parent, const char* name )
+ : KRES::ConfigWidget( parent, name ), mRes( 0 )
+{
+ QGridLayout *mainLayout = new QGridLayout( this, 5, 2, 0, KDialog::spacingHint() );
+
+ QLabel *label = new QLabel( i18n( "URL:" ), this );
+ mURL = new KURLRequester( this );
+
+ mainLayout->addWidget( label, 0, 0 );
+ mainLayout->addWidget( mURL, 0, 1 );
+
+ label = new QLabel( i18n( "User:" ), this );
+ mUser = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mUser, 1, 1 );
+
+ label = new QLabel( i18n( "Password:" ), this );
+ mPassword = new KLineEdit( this );
+ mPassword->setEchoMode( QLineEdit::Password );
+
+ mainLayout->addWidget( label, 2, 0 );
+ mainLayout->addWidget( mPassword, 2, 1 );
+
+ mLastSyncCheck = new QCheckBox( i18n("Only load data since last sync"),
+ this );
+ mainLayout->addMultiCellWidget( mLastSyncCheck, 3, 3, 0, 1 );
+
+ mFolderButton = new KPushButton( i18n("Select Folder..."), this );
+ mainLayout->addMultiCellWidget( mFolderButton, 4, 4, 0, 1 );
+ connect( mFolderButton, SIGNAL( clicked() ), SLOT( selectAddressFolder() ) );
+
+}
+
+void ResourceSloxConfig::loadSettings( KRES::Resource *res )
+{
+ ResourceSlox *resource = dynamic_cast<ResourceSlox*>( res );
+ mRes = resource;
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceSloxConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ if ( mRes->resType() == "slox" )
+ mFolderButton->setEnabled( false ); // TODO folder selection for SLOX
+
+ mURL->setURL( resource->prefs()->url() );
+ mUser->setText( resource->prefs()->user() );
+ mPassword->setText( resource->prefs()->password() );
+ mLastSyncCheck->setChecked( resource->prefs()->useLastSync() );
+ mFolderId = resource->prefs()->folderId();
+}
+
+void ResourceSloxConfig::saveSettings( KRES::Resource *res )
+{
+ ResourceSlox *resource = dynamic_cast<ResourceSlox*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceSloxConfig::saveSettings(): cast failed" << endl;
+ return;
+ }
+
+ resource->prefs()->setUrl( mURL->url() );
+ resource->prefs()->setUser( mUser->text() );
+ resource->prefs()->setPassword( mPassword->text() );
+ resource->prefs()->setUseLastSync( mLastSyncCheck->isChecked() );
+ resource->prefs()->setFolderId( mFolderId );
+}
+
+void KABC::ResourceSloxConfig::selectAddressFolder( )
+{
+ SloxFolderManager *manager = new SloxFolderManager( mRes, mURL->url() );
+ SloxFolderDialog *dialog = new SloxFolderDialog( manager, Contacts, this );
+ dialog->setSelectedFolder( mFolderId );
+ if ( dialog->exec() == QDialog::Accepted )
+ mFolderId = dialog->selectedFolder();
+}
+
+#include "kabcresourcesloxconfig.moc"
diff --git a/kresources/slox/kabcresourcesloxconfig.h b/kresources/slox/kabcresourcesloxconfig.h
new file mode 100644
index 000000000..b55282a85
--- /dev/null
+++ b/kresources/slox/kabcresourcesloxconfig.h
@@ -0,0 +1,61 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 RESOURCESLOXCONFIG_H
+#define RESOURCESLOXCONFIG_H
+
+#include <kresources/configwidget.h>
+#include <kdepimmacros.h>
+
+class QCheckBox;
+class KLineEdit;
+class KURLRequester;
+class KPushButton;
+
+class SloxBase;
+
+namespace KABC {
+
+class KDE_EXPORT ResourceSloxConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+ public:
+ ResourceSloxConfig( QWidget* parent = 0, const char* name = 0 );
+
+ public slots:
+ void loadSettings( KRES::Resource* );
+ void saveSettings( KRES::Resource* );
+
+ private slots:
+ void selectAddressFolder();
+
+ private:
+ KURLRequester *mURL;
+ KLineEdit *mUser;
+ KLineEdit *mPassword;
+ QCheckBox *mLastSyncCheck;
+ KPushButton *mFolderButton;
+ QString mFolderId;
+ SloxBase *mRes;
+};
+
+}
+
+#endif
diff --git a/kresources/slox/kabcsloxprefs.kcfgc b/kresources/slox/kabcsloxprefs.kcfgc
new file mode 100644
index 000000000..50c7cbbb8
--- /dev/null
+++ b/kresources/slox/kabcsloxprefs.kcfgc
@@ -0,0 +1,11 @@
+# Code generation options for kconfig_compiler
+File=kresources_kabc_slox.kcfg
+ClassName=SloxPrefs
+NameSpace=KABC
+Singleton=false
+Mutators=true
+Inherits=KResourcePrefs
+IncludeFiles=libkdepim/kresourceprefs.h
+GlobalEnums=true
+#ItemAccessors=true
+#SetUserTexts=true
diff --git a/kresources/slox/kcal_ox.desktop b/kresources/slox/kcal_ox.desktop
new file mode 100644
index 000000000..e0eaa9224
--- /dev/null
+++ b/kresources/slox/kcal_ox.desktop
@@ -0,0 +1,47 @@
+[Desktop Entry]
+Name=OpenXchange Server
+Name[af]=OpenXchange bediener
+Name[bg]=Сървър OpenXchange
+Name[br]=Servijer OpenXchange
+Name[ca]=Servidor OpenXchange
+Name[da]=Openxchange-server
+Name[el]=Εξυπηρετητής OpenXchange
+Name[es]=Servidor OpenXchange
+Name[et]=OpenXchange server
+Name[eu]=OpenXchange zerbitzaria
+Name[fa]=کارساز OpenXchange
+Name[fi]=OpenXchange-palvelin
+Name[fr]=Serveur OpenXchange
+Name[fy]=OpenXchange-tsjinner
+Name[ga]=Freastalaí Openexchange
+Name[gl]=Servidor OpenXchange
+Name[hu]=OpenXchange-kiszolgáló
+Name[is]=OpenXchange þjónn
+Name[ja]=OpenXchange サーバ
+Name[ka]=Openexchange სერვერი
+Name[kk]=OpenXchange сервері
+Name[km]=ម៉ាស៊ីន​បម្រើ OpenXchange
+Name[lt]=OpenXchange serveris
+Name[mk]=OpenXchange-сервер
+Name[nb]=OpenExchange-tjener
+Name[nds]=OpenXchange-Server
+Name[ne]=ओपन एक्सचेन्ज सर्भर
+Name[nl]=OpenXchange-server
+Name[nn]=OpenXchange-tenar
+Name[pl]=Server OpenXchange
+Name[pt]=Servidor OpenXchange
+Name[pt_BR]=Servidor OpenXchange
+Name[ru]=Сервер OpenXchange
+Name[sl]=Strežnik OpenXchange
+Name[sr]=Openexchange сервер
+Name[sr@Latn]=Openexchange server
+Name[sv]=Openxchange-server
+Name[tr]=OpenXchange Sunucusu
+Name[uk]=Сервер OpenXchange
+Name[zh_CN]=OpenXchange 服务器
+Name[zh_TW]=OpenXchange 伺服器
+X-KDE-Library=kcal_slox
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=calendar
+X-KDE-ResourceType=ox
diff --git a/kresources/slox/kcal_slox.desktop b/kresources/slox/kcal_slox.desktop
new file mode 100644
index 000000000..0daca0b2c
--- /dev/null
+++ b/kresources/slox/kcal_slox.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=SUSE LINUX Openexchange Server
+Name[af]=SuSE Linux OpenExchange bediener
+Name[bg]=Сървър SUSE LINUX Openexchange
+Name[br]=Servijer Openexchange SUSE LINUX
+Name[ca]=Servidor SUSE LINUX Openexchange
+Name[cs]=SUSE LINUX Openexchange server
+Name[da]=SUSE Linux Openexchange-server
+Name[de]=SUSE LINUX Openexchange-Server
+Name[el]=Εξυπηρετητή SUSE LINUX Openexchange
+Name[es]=Servidor Openexchange de SUSE LINUX
+Name[et]=SUSE LINUX Openexchange server
+Name[eu]=SUSE LINUX Openexchange zerbitzaria
+Name[fa]=کارساز SUSE LINUX Openexchange
+Name[fi]=Suse Linux Openexchange -palvelin
+Name[fr]=Serveur SUSE Linux Openexchange
+Name[fy]=SUSE LINUX Openexchange-tsjinner
+Name[ga]=Freastalaí Openexchange SUSE LINUX
+Name[gl]=Servidor SUSE LINUX Openexchange
+Name[hu]=SUSE LINUX Openexchange-kiszolgáló
+Name[is]=SUSE LINUX Openexchange þjónn
+Name[it]=Server SUSE LINUX Openexchange
+Name[ja]=SUSE LINUX Openexchange サーバ
+Name[ka]= SUSE LINUX Openexchange სერვერი
+Name[kk]=SUSE LINUX Openexchange сервері
+Name[km]=ម៉ាស៊ីន​បម្រើ Openexchange របស់​ស៊ូស៊ីលីនីក
+Name[lt]=SUSE LINUX Openexchange serveris
+Name[mk]=SUSE LINUX Openexchange-сервер
+Name[ms]=Pelayan SUSE LINUX Openexchange
+Name[nb]=SUSE LINUX Openexchange-tjener
+Name[nds]=SUSE-Openexchangeserver
+Name[ne]=SUSE LINUX ओपन एक्सचेन्ज सर्भर
+Name[nl]=SUSE LINUX Openexchange-server
+Name[nn]=SUSE LINUX Openexchange-tenar
+Name[pl]=Server SUSE LINUX Openexchange
+Name[pt]=Servidor SUSE LINUX Openexchange
+Name[pt_BR]=Servidor OpenExchange do SUSE Linux (SLOX)
+Name[ru]=Сервер SUSE LINUX Openexchange
+Name[sl]=Strežnik SUSE LINUX Openexchange
+Name[sr]=Openexchange сервер SUSE-овог Linux-а
+Name[sr@Latn]=Openexchange server SUSE-ovog Linux-a
+Name[sv]=SUSE Linux Openexchange-server
+Name[ta]=SUSE LINUX திறந்த பரிமாற்ற சேவகன்
+Name[tr]=SUSE LINUX Openexchange Sunucusu
+Name[uk]=Сервер SUSE LINUX Openexchange
+Name[zh_CN]=SUSE LINUX Openexchange 服务器
+Name[zh_TW]=SUSE LINUX Openexchange 伺服器
+X-KDE-Library=kcal_slox
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=calendar
+X-KDE-ResourceType=slox
diff --git a/kresources/slox/kcalresourceslox.cpp b/kresources/slox/kcalresourceslox.cpp
new file mode 100644
index 000000000..d446494f6
--- /dev/null
+++ b/kresources/slox/kcalresourceslox.cpp
@@ -0,0 +1,1326 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2005 Volker Krause <volker.krause@rwth-aachen.de>
+
+ 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 <typeinfo>
+#include <stdlib.h>
+
+#include <qdatetime.h>
+#include <qstring.h>
+#include <qptrlist.h>
+#include <qfile.h>
+#include <qregexp.h>
+
+#include <kdebug.h>
+#include <kurl.h>
+#include <kio/job.h>
+#include <kio/davjob.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include <libkdepim/progressmanager.h>
+
+#include <libkcal/vcaldrag.h>
+#include <libkcal/vcalformat.h>
+#include <libkcal/icalformat.h>
+#include <libkcal/exceptions.h>
+#include <libkcal/incidence.h>
+#include <libkcal/event.h>
+#include <libkcal/todo.h>
+#include <libkcal/journal.h>
+#include <libkcal/filestorage.h>
+#include <libkcal/confirmsavedialog.h>
+
+#include <kabc/locknull.h>
+#include <kabc/stdaddressbook.h>
+
+#include <kresources/configwidget.h>
+
+#include "webdavhandler.h"
+#include "kcalsloxprefs.h"
+#include "sloxaccounts.h"
+
+#include "kcalresourceslox.h"
+
+using namespace KCal;
+
+KCalResourceSlox::KCalResourceSlox( const KConfig *config )
+ : ResourceCached( config ), SloxBase( this )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ if ( config ) {
+ readConfig( config );
+ }
+}
+
+KCalResourceSlox::KCalResourceSlox( const KURL &url )
+ : ResourceCached( 0 ), SloxBase( this )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ mPrefs->setUrl( url.url() );
+}
+
+KCalResourceSlox::~KCalResourceSlox()
+{
+ kdDebug() << "~KCalResourceSlox()" << endl;
+
+ disableChangeNotification();
+
+ close();
+
+ if ( mLoadEventsJob ) mLoadEventsJob->kill();
+ if ( mLoadTodosJob ) mLoadTodosJob->kill();
+ if ( mUploadJob ) mUploadJob->kill();
+
+ delete mLock;
+
+ kdDebug() << "~KCalResourceSlox() done" << endl;
+}
+
+void KCalResourceSlox::init()
+{
+ mPrefs = new SloxPrefs;
+ mWebdavHandler.setResource( this );
+
+ mLoadEventsJob = 0;
+ mLoadTodosJob = 0;
+
+ mUploadJob = 0;
+
+ mLoadEventsProgress = 0;
+ mLoadTodosProgress = 0;
+
+ mAccounts = 0;
+
+ mLock = new KABC::LockNull( true );
+
+ enableChangeNotification();
+}
+
+void KCalResourceSlox::readConfig( const KConfig *config )
+{
+ mPrefs->readConfig();
+
+ mWebdavHandler.setUserId( mPrefs->user() );
+
+ ResourceCached::readConfig( config );
+
+ KURL url = mPrefs->url();
+ url.setUser( mPrefs->user() );
+ url.setPass( mPrefs->password() );
+
+ delete mAccounts;
+ mAccounts = new SloxAccounts( this, url );
+}
+
+void KCalResourceSlox::writeConfig( KConfig *config )
+{
+ kdDebug() << "KCalResourceSlox::writeConfig()" << endl;
+
+ ResourceCalendar::writeConfig( config );
+
+ mPrefs->writeConfig();
+
+ ResourceCached::writeConfig( config );
+}
+
+bool KCalResourceSlox::doLoad()
+{
+ kdDebug() << "KCalResourceSlox::load() " << long( this ) << endl;
+
+ if ( mLoadEventsJob || mLoadTodosJob ) {
+ kdDebug() << "KCalResourceSlox::load(): download still in progress."
+ << endl;
+ return true;
+ }
+ if ( mUploadJob ) {
+ kdWarning() << "KCalResourceSlox::load(): upload still in progress."
+ << endl;
+ loadError( "Upload still in progress." );
+ return false;
+ }
+
+ mCalendar.close();
+
+ disableChangeNotification();
+ loadCache();
+ enableChangeNotification();
+
+ emit resourceChanged( this );
+
+ clearChanges();
+
+ QString p = KURL( mPrefs->url() ).protocol();
+ if ( p != "http" && p != "https" && p != "webdav" && p != "webdavs" ) {
+ QString err = i18n("Non-http protocol: '%1'").arg( p );
+ kdDebug() << "KCalResourceSlox::load(): " << err << endl;
+ loadError( err );
+ return false;
+ }
+
+ // The SLOX contacts are loaded asynchronously, so make sure that they are
+ // actually loaded.
+ KABC::StdAddressBook::self( true )->asyncLoad();
+
+#if 1
+ requestEvents();
+#endif
+ requestTodos();
+
+ return true;
+}
+
+void KCalResourceSlox::requestEvents()
+{
+ KURL url = mPrefs->url();
+ url.setPath( "/servlet/webdav.calendar/" );
+ url.setUser( mPrefs->user() );
+ url.setPass( mPrefs->password() );
+
+ kdDebug() << "KCalResourceSlox::requestEvents(): " << url << endl;
+
+ QString lastsync = "0";
+ if ( mPrefs->useLastSync() ) {
+ QDateTime dt = mPrefs->lastEventSync();
+ if ( dt.isValid() ) {
+ lastsync = WebdavHandler::qDateTimeToSlox( dt.addDays( -1 ) );
+ }
+ }
+
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ QDomElement prop = WebdavHandler::addDavElement( doc, root, "prop" );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( LastSync ), lastsync );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( FolderId ), mPrefs->calendarFolderId() );
+ if ( type() == "ox" ) {
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "NEW_AND_MODIFIED" );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "DELETED" );
+ } else
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "all" );
+
+ kdDebug() << "REQUEST CALENDAR: \n" << doc.toString( 2 ) << endl;
+
+ mLoadEventsJob = KIO::davPropFind( url, doc, "0", false );
+ connect( mLoadEventsJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotLoadEventsResult( KIO::Job * ) ) );
+ connect( mLoadEventsJob, SIGNAL( percent( KIO::Job *, unsigned long ) ),
+ SLOT( slotEventsProgress( KIO::Job *, unsigned long ) ) );
+
+ mLoadEventsProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Downloading events") );
+ connect( mLoadEventsProgress,
+ SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ SLOT( cancelLoadEvents() ) );
+
+ mPrefs->setLastEventSync( QDateTime::currentDateTime() );
+}
+
+void KCalResourceSlox::requestTodos()
+{
+ KURL url = mPrefs->url();
+ url.setPath( "/servlet/webdav.tasks/" );
+ url.setUser( mPrefs->user() );
+ url.setPass( mPrefs->password() );
+
+ kdDebug() << "KCalResourceSlox::requestTodos(): " << url << endl;
+
+ QString lastsync = "0";
+ if ( mPrefs->useLastSync() ) {
+ QDateTime dt = mPrefs->lastTodoSync();
+ if ( dt.isValid() ) {
+ lastsync = WebdavHandler::qDateTimeToSlox( dt.addDays( -1 ) );
+ }
+ }
+
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ QDomElement prop = WebdavHandler::addDavElement( doc, root, "prop" );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( LastSync ), lastsync );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( FolderId ), mPrefs->taskFolderId() );
+ if ( type() == "ox" ) {
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "NEW_AND_MODIFIED" );
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "DELETED" );
+ } else
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectType ), "all" );
+
+ kdDebug() << "REQUEST TASKS: \n" << doc.toString( 2 ) << endl;
+
+ mLoadTodosJob = KIO::davPropFind( url, doc, "0", false );
+ connect( mLoadTodosJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotLoadTodosResult( KIO::Job * ) ) );
+ connect( mLoadTodosJob, SIGNAL( percent( KIO::Job *, unsigned long ) ),
+ SLOT( slotTodosProgress( KIO::Job *, unsigned long ) ) );
+
+ mLoadTodosProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Downloading to-dos") );
+ connect( mLoadTodosProgress,
+ SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ SLOT( cancelLoadTodos() ) );
+
+ mPrefs->setLastTodoSync( QDateTime::currentDateTime() );
+}
+
+void KCalResourceSlox::uploadIncidences()
+{
+ QDomDocument doc;
+ QDomElement ms = WebdavHandler::addDavElement( doc, doc, "multistatus" );
+ QDomElement pu = WebdavHandler::addDavElement( doc, ms, "propertyupdate" );
+ QDomElement set = WebdavHandler::addElement( doc, pu, "D:set" );
+ QDomElement prop = WebdavHandler::addElement( doc, set, "D:prop" );
+
+ mUploadIsDelete = false;
+ Incidence::List added = addedIncidences();
+ Incidence::List changed = changedIncidences();
+ Incidence::List deleted = deletedIncidences();
+ if ( !added.isEmpty() ) {
+ mUploadedIncidence = added.first();
+ } else if ( !changed.isEmpty() ) {
+ mUploadedIncidence = changed.first();
+ } else if ( !deleted.isEmpty() ) {
+ mUploadedIncidence = deleted.first();
+ mUploadIsDelete = true;
+ } else {
+ mUploadedIncidence = 0;
+ kdDebug() << "uploadIncidences(): FINISHED" << endl;
+ emit resourceSaved( this );
+ return;
+ }
+
+ // Don't try to upload recurring incidences as long as the resource doesn't
+ // correctly write them in order to avoid corrupting data on the server.
+ // FIXME: Remove when recurrences are correctly written.
+ if ( mUploadedIncidence->doesRecur() && type() == "slox" ) {
+ clearChange( mUploadedIncidence );
+ uploadIncidences();
+ return;
+ }
+
+ KURL url = mPrefs->url();
+
+ QString sloxId = mUploadedIncidence->customProperty( "SLOX", "ID" );
+ if ( !sloxId.isEmpty() ) {
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ObjectId ), sloxId );
+ } else {
+ if ( mUploadIsDelete ) {
+ kdError() << "Incidence to delete doesn't have a SLOX id" << endl;
+ clearChange( mUploadedIncidence );
+ uploadIncidences();
+ return;
+ }
+ }
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( ClientId ),
+ mUploadedIncidence->uid() );
+
+ if ( mUploadIsDelete ) {
+ if ( mUploadedIncidence->type() == "Event" ) {
+ url.setPath( "/servlet/webdav.calendar/" + sloxId );
+ } else if ( mUploadedIncidence->type() == "Todo" ) {
+ url.setPath( "/servlet/webdav.tasks/" + sloxId );
+ } else {
+ kdWarning() << "uploadIncidences(): Unsupported incidence type: "
+ << mUploadedIncidence->type() << endl;
+ return;
+ }
+
+ if ( type() == "ox" ) {
+ WebdavHandler::addSloxElement( this, doc, prop, "method", "DELETE" );
+ } else {
+ QDomElement remove = WebdavHandler::addElement( doc, pu, "D:remove" );
+ QDomElement prop = WebdavHandler::addElement( doc, remove, "D:prop" );
+ WebdavHandler::addSloxElement( this, doc, prop, "sloxid", sloxId );
+ }
+ } else {
+ createIncidenceAttributes( doc, prop, mUploadedIncidence );
+ // FIXME: Use a visitor
+ if ( mUploadedIncidence->type() == "Event" ) {
+ url.setPath( "/servlet/webdav.calendar/file.xml" );
+ createEventAttributes( doc, prop, static_cast<Event *>( mUploadedIncidence ) );
+ // TODO: OX supports recurrences also for tasks
+ createRecurrenceAttributes( doc, prop, mUploadedIncidence );
+ } else if ( mUploadedIncidence->type() == "Todo" ) {
+ url.setPath( "/servlet/webdav.tasks/file.xml" );
+ createTodoAttributes( doc, prop, static_cast<Todo *>( mUploadedIncidence ) );
+ } else {
+ kdWarning() << "uploadIncidences(): Unsupported incidence type: "
+ << mUploadedIncidence->type() << endl;
+ return;
+ }
+ }
+
+ url.setUser( mPrefs->user() );
+ url.setPass( mPrefs->password() );
+
+ kdDebug() << "KCalResourceSlox::uploadIncidences(): " << url << endl;
+
+ kdDebug() << "UPLOAD: \n" << doc.toString( 2 ) << endl;
+
+ mUploadJob = KIO::davPropPatch( url, doc, false );
+ connect( mUploadJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotUploadResult( KIO::Job * ) ) );
+ connect( mUploadJob, SIGNAL( percent( KIO::Job *, unsigned long ) ),
+ SLOT( slotUploadProgress( KIO::Job *, unsigned long ) ) );
+
+ mUploadProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Uploading incidence") );
+ connect( mUploadProgress,
+ SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ SLOT( cancelUpload() ) );
+}
+
+void KCalResourceSlox::createIncidenceAttributes( QDomDocument &doc,
+ QDomElement &parent,
+ Incidence *incidence )
+{
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( IncidenceTitle ),
+ incidence->summary() );
+
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( Description ),
+ incidence->description() );
+
+ if ( incidence->attendeeCount() > 0 ) {
+ QDomElement members = WebdavHandler::addSloxElement( this, doc, parent,
+ fieldName( Participants ) );
+ Attendee::List attendees = incidence->attendees();
+ Attendee::List::ConstIterator it;
+ for( it = attendees.begin(); it != attendees.end(); ++it ) {
+ if ( mAccounts ) {
+ QString userId = mAccounts->lookupId( (*it)->email() );
+ QString status;
+ switch ( (*it)->status() ) {
+ case Attendee::Accepted: status = "accept"; break;
+ case Attendee::Declined: status = "decline"; break;
+ default: status = "none"; break;
+ }
+ QDomElement el = WebdavHandler::addSloxElement( this, doc, members, fieldName( Participant ), userId );
+ el.setAttribute( "confirm", status );
+ } else {
+ kdError() << "KCalResourceSlox: No accounts set." << endl;
+ }
+ }
+ }
+
+ // set read attributes - if SecrecyPublic, set it to users
+ // TODO OX support
+ if ( incidence->secrecy() == Incidence::SecrecyPublic && type() != "ox" )
+ {
+ QDomElement rights = WebdavHandler::addSloxElement( this, doc, parent, "readrights" );
+ WebdavHandler::addSloxElement( this, doc, rights, "group", "users" );
+ }
+
+ // set reminder as the number of minutes to the start of the event
+ KCal::Alarm::List alarms = incidence->alarms();
+ if ( !alarms.isEmpty() && alarms.first()->hasStartOffset() && alarms.first()->enabled() )
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( Reminder ),
+ QString::number( (-1) * alarms.first()->startOffset().asSeconds() / 60 ) );
+ else
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( Reminder ), "0" );
+
+ // categories
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( Categories ), incidence->categories().join( ", " ) );
+}
+
+void KCalResourceSlox::createEventAttributes( QDomDocument &doc,
+ QDomElement &parent,
+ Event *event )
+{
+ QString folderId = mPrefs->calendarFolderId();
+ if ( folderId.isEmpty() && type() == "ox" ) // SLOX and OX use diffrent default folders
+ folderId = "-1";
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( FolderId ), folderId );
+
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( EventBegin ),
+ WebdavHandler::qDateTimeToSlox( event->dtStart(), timeZoneId() ) );
+
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( EventEnd ),
+ WebdavHandler::qDateTimeToSlox( event->dtEnd(), timeZoneId() ) );
+
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( Location ), event->location() );
+
+ if ( event->doesFloat() ) {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( FullTime ), boolToStr( true ) );
+ } else {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( FullTime ), boolToStr( false ) );
+ }
+}
+
+void KCalResourceSlox::createTodoAttributes( QDomDocument &doc,
+ QDomElement &parent,
+ Todo *todo )
+{
+ QString folderId = mPrefs->taskFolderId();
+ if ( folderId.isEmpty() && type() == "ox" ) // SLOX and OX use diffrent default folders
+ folderId = "-1";
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( FolderId ), folderId );
+
+ if ( todo->hasStartDate() ) {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( TaskBegin ),
+ WebdavHandler::qDateTimeToSlox( todo->dtStart(), timeZoneId() ) );
+ }
+
+ if ( todo->hasDueDate() ) {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( TaskEnd ),
+ WebdavHandler::qDateTimeToSlox( todo->dtDue(), timeZoneId() ) );
+ }
+
+ int priority = todo->priority();
+ QString txt;
+ switch ( priority ) {
+ case 9:
+ case 8:
+ txt = "1";
+ break;
+ case 2:
+ case 1:
+ txt = "3";
+ break;
+ default:
+ txt = "2";
+ break;
+ }
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( Priority ), txt );
+
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( PercentComplete ),
+ QString::number( todo->percentComplete() ) );
+}
+
+void KCalResourceSlox::createRecurrenceAttributes( QDomDocument &doc,
+ QDomElement &parent,
+ KCal::Incidence *incidence )
+{
+ if ( !incidence->doesRecur() ) {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ),
+ type() == "ox" ? "none" : "no" );
+ return;
+ }
+ Recurrence *r = incidence->recurrence();
+ int monthOffset = ( type() == "ox" ? -1 : 0 );
+ switch ( r->recurrenceType() ) {
+ case Recurrence::rDaily:
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "daily" );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceDailyFreq ),
+ QString::number( r->frequency() ) );
+ break;
+ case Recurrence::rWeekly: {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "weekly" );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceWeeklyFreq ),
+ QString::number( r->frequency() ) );
+ // TODO: SLOX support
+ int oxDays = 0;
+ for ( int i = 0; i < 7; ++i ) {
+ if ( r->days()[i] )
+ oxDays += 1 << ( ( i + 1 ) % 7 );
+ }
+ if ( type() == "ox" )
+ WebdavHandler::addSloxElement( this, doc, parent, "days", QString::number( oxDays ) );
+ break; }
+ case Recurrence::rMonthlyDay:
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "monthly" );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthlyFreq ),
+ QString::number( r->frequency() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthlyDay ),
+ QString::number( r->monthDays().first() ) );
+ break;
+ case Recurrence::rMonthlyPos: {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ),
+ type() == "ox" ? "monthly" : "monthly2" );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthly2Freq ),
+ QString::number( r->frequency() ) );
+ RecurrenceRule::WDayPos wdp = r->monthPositions().first();
+ // TODO: SLOX support
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthly2Day ),
+ QString::number( 1 << wdp.day() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthly2Pos ),
+ QString::number( wdp.pos() ) );
+ break; }
+ case Recurrence::rYearlyMonth:
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "yearly" );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearlyDay ),
+ QString::number( r->yearDates().first() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearlyMonth ),
+ QString::number( r->yearMonths().first() + monthOffset ) );
+ if ( type() == "ox" )
+ WebdavHandler::addSloxElement( this, doc, parent, "interval", "1" );
+ break;
+ case Recurrence::rYearlyPos: {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ),
+ type() == "ox" ? "yearly" : "yearly2" );
+ RecurrenceRule::WDayPos wdp = r->monthPositions().first();
+ // TODO: SLOX support
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearly2Day ),
+ QString::number( 1 << wdp.day() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearly2Pos ),
+ QString::number( wdp.pos() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearly2Month ),
+ QString::number( r->yearMonths().first() + monthOffset ) );
+ if ( type() == "ox" )
+ WebdavHandler::addSloxElement( this, doc, parent, "interval", "1" );
+ break; }
+ default:
+ kdDebug() << k_funcinfo << "unsupported recurrence type: " << r->recurrenceType() << endl;
+ }
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceEnd ),
+ WebdavHandler::qDateTimeToSlox( r->endDateTime() ) );
+ // delete exceptions
+ DateList exlist = r->exDates();
+ QStringList res;
+ for ( DateList::Iterator it = exlist.begin(); it != exlist.end(); ++it )
+ res.append( WebdavHandler::qDateTimeToSlox( *it ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceDelEx ), res.join( "," ) );
+}
+
+void KCalResourceSlox::parseMembersAttribute( const QDomElement &e,
+ Incidence *incidence )
+{
+ incidence->clearAttendees();
+
+ QDomNode n;
+ for( n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement memberElement = n.toElement();
+ if ( memberElement.tagName() == fieldName( Participant ) ) {
+ QString member = memberElement.text();
+ KABC::Addressee account;
+ if ( mAccounts ) account = mAccounts->lookupUser( member );
+ else kdError() << "KCalResourceSlox: no accounts set" << endl;
+ QString name;
+ QString email;
+ Attendee *a = incidence->attendeeByUid( member );
+ if ( account.isEmpty() ) {
+ if ( a ) continue;
+
+ name = member;
+ email = member + "@" + KURL( mPrefs->url() ).host();
+ } else {
+ name = account.realName();
+ email = account.preferredEmail();
+ }
+ if ( a ) {
+ a->setName( name );
+ a->setEmail( email );
+ } else {
+ a = new Attendee( name, email );
+ a->setUid( member );
+ incidence->addAttendee( a );
+ }
+ QString status = memberElement.attribute( "confirm" );
+ if ( !status.isEmpty() ) {
+ if ( status == "accept" ) {
+ a->setStatus( Attendee::Accepted );
+ } else if ( status == "decline" ) {
+ a->setStatus( Attendee::Declined );
+ } else {
+ a->setStatus( Attendee::NeedsAction );
+ }
+ }
+ } else {
+ kdDebug() << "Unknown tag in members attribute: "
+ << memberElement.tagName() << endl;
+ }
+ }
+}
+
+void KCalResourceSlox::parseReadRightsAttribute( const QDomElement &e,
+ Incidence *incidence )
+{
+ QDomNode n;
+ for( n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement rightElement = n.toElement();
+ if ( rightElement.tagName() == "group" ) {
+ QString groupName = rightElement.text();
+ if ( groupName == "users" )
+ incidence->setSecrecy( Incidence::SecrecyPublic );
+ }
+ }
+}
+
+void KCalResourceSlox::parseIncidenceAttribute( const QDomElement &e,
+ Incidence *incidence )
+{
+ QString tag = e.tagName();
+ QString text = decodeText( e.text() );
+ if ( text.isEmpty() ) return;
+
+ if ( tag == fieldName( IncidenceTitle ) ) {
+ incidence->setSummary( text );
+ } else if ( e.tagName() == fieldName( Description ) ) {
+ incidence->setDescription( text );
+ } else if ( tag == fieldName( Reminder ) ) {
+ int minutes = text.toInt();
+ if ( minutes != 0 ) {
+ Alarm::List alarms = incidence->alarms();
+ Alarm *alarm;
+ if ( alarms.isEmpty() ) alarm = incidence->newAlarm();
+ else alarm = alarms.first();
+ if ( alarm->type() == Alarm::Invalid ) {
+ alarm->setType( Alarm::Display );
+ }
+ Duration d( minutes * -60 );
+ alarm->setStartOffset( d );
+ alarm->setEnabled( true );
+ } else {
+ // 0 reminder -> disable alarm
+ incidence->clearAlarms();
+ }
+ } else if ( tag == fieldName( CreatedBy ) ) {
+ KABC::Addressee a;
+ if ( mAccounts ) a = mAccounts->lookupUser( text );
+ else kdDebug() << "KCalResourceSlox: no accounts set" << endl;
+ incidence->setOrganizer( Person( a.formattedName(), a.preferredEmail() ) );
+ } else if ( tag == fieldName( Participants ) ) {
+ parseMembersAttribute( e, incidence );
+ } else if ( tag == "readrights" ) {
+ parseReadRightsAttribute( e, incidence );
+ } else if ( tag == fieldName( Categories ) ) {
+ incidence->setCategories( QStringList::split( QRegExp(",\\s*"), text ) );
+ }
+}
+
+void KCalResourceSlox::parseEventAttribute( const QDomElement &e,
+ Event *event )
+{
+ QString tag = e.tagName();
+ QString text = decodeText( e.text() );
+ if ( text.isEmpty() ) return;
+
+ if ( tag == fieldName( EventBegin ) ) {
+ QDateTime dt;
+ if ( event->doesFloat() ) {
+ if ( type() == "ox" )
+ dt = WebdavHandler::sloxToQDateTime( text, timeZoneId() );
+ else
+ dt = WebdavHandler::sloxToQDateTime( text ); // ### is this really correct for SLOX?
+ } else
+ dt = WebdavHandler::sloxToQDateTime( text, timeZoneId() );
+ event->setDtStart( dt );
+ } else if ( tag == fieldName( EventEnd ) ) {
+ QDateTime dt;
+ if ( event->doesFloat() ) {
+ dt = WebdavHandler::sloxToQDateTime( text );
+ dt = dt.addSecs( -1 );
+ }
+ else dt = WebdavHandler::sloxToQDateTime( text, timeZoneId() );
+ event->setDtEnd( dt );
+ } else if ( tag == fieldName( Location ) ) {
+ event->setLocation( text );
+ }
+}
+
+void KCalResourceSlox::parseRecurrence( const QDomNode &node, Event *event )
+{
+ QString type;
+
+ int dailyValue = -1;
+ QDateTime end;
+
+ int weeklyValue = -1;
+ QBitArray days( 7 ); // days, starting with monday
+ bool daysSet = false;
+
+ int monthlyValueDay = -1;
+ int monthlyValueMonth = -1;
+
+ int yearlyValueDay = -1;
+ int yearlyMonth = -1;
+
+ int monthly2Recurrency = 0;
+ int monthly2Day = 0;
+ int monthly2ValueMonth = -1;
+
+ int yearly2Recurrency = 0;
+ int yearly2Day = 0;
+ int yearly2Month = -1;
+
+ DateList deleteExceptions;
+
+ QDomNode n;
+
+ for( n = node.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement e = n.toElement();
+ QString tag = e.tagName();
+ QString text = decodeText( e.text() );
+ kdDebug() << k_funcinfo << tag << ": " << text << endl;
+
+ if ( tag == fieldName( RecurrenceType ) ) {
+ type = text;
+ } else if ( tag == "daily_value" ) {
+ dailyValue = text.toInt();
+ } else if ( tag == fieldName( RecurrenceEnd ) ) {
+ end = WebdavHandler::sloxToQDateTime( text );
+ } else if ( tag == "weekly_value" ) {
+ weeklyValue = text.toInt();
+ } else if ( tag.left( 11 ) == "weekly_day_" ) {
+ int day = tag.mid( 11, 1 ).toInt();
+ int index;
+ if ( day == 1 ) index = 0;
+ else index = day - 2;
+ days.setBit( index );
+ } else if ( tag == "monthly_value_day" ) {
+ monthlyValueDay = text.toInt();
+ } else if ( tag == "monthly_value_month" ) {
+ monthlyValueMonth = text.toInt();
+ } else if ( tag == "yearly_value_day" ) {
+ yearlyValueDay = text.toInt();
+ } else if ( tag == "yearly_month" ) {
+ yearlyMonth = text.toInt();
+ } else if ( tag == "monthly2_recurrency" ) {
+ monthly2Recurrency = text.toInt();
+ } else if ( tag == "monthly2_day" ) {
+ monthly2Day = text.toInt();
+ } else if ( tag == "monthly2_value_month" ) {
+ monthly2ValueMonth = text.toInt();
+ } else if ( tag == "yearly2_reccurency" ) { // this is not a typo, this is what SLOX really sends!
+ yearly2Recurrency = text.toInt();
+ } else if ( tag == "yearly2_day" ) {
+ yearly2Day = text.toInt();
+ } else if ( tag == "yearly2_month" ) {
+ yearly2Month = text.toInt() + 1;
+ // OX recurrence fields
+ } else if ( tag == "interval" ) {
+ dailyValue = text.toInt();
+ weeklyValue = text.toInt();
+ monthlyValueMonth = text.toInt();
+ monthly2ValueMonth = text.toInt();
+ } else if ( tag == "days" ) {
+ int tmp = text.toInt(); // OX encodes days binary: 1=Su, 2=Mo, 4=Tu, ...
+ for ( int i = 0; i < 7; ++i ) {
+ if ( tmp & (1 << i) )
+ days.setBit( (i + 6) % 7 );
+ }
+ daysSet = true;
+ } else if ( tag == "day_in_month" ) {
+ monthlyValueDay = text.toInt();
+ monthly2Recurrency = text.toInt();
+ yearlyValueDay = text.toInt();
+ yearly2Recurrency = text.toInt();
+ } else if ( tag == "month" ) {
+ yearlyMonth = text.toInt() + 1; // starts at 0
+ yearly2Month = text.toInt() + 1;
+ } else if ( tag == fieldName( RecurrenceDelEx ) ) {
+ QStringList exdates = QStringList::split( ",", text );
+ QStringList::Iterator it;
+ for ( it = exdates.begin(); it != exdates.end(); ++it )
+ deleteExceptions.append( WebdavHandler::sloxToQDateTime( *it ).date() );
+ }
+ }
+
+ if ( daysSet && type == "monthly" )
+ type = "monthly2"; // HACK: OX doesn't cleanly distinguish between monthly and monthly2
+ if ( daysSet && type == "yearly" )
+ type = "yearly2";
+
+ Recurrence *r = event->recurrence();
+
+ if ( type == "daily" ) {
+ r->setDaily( dailyValue );
+ } else if ( type == "weekly" ) {
+ r->setWeekly( weeklyValue, days );
+ } else if ( type == "monthly" ) {
+ r->setMonthly( monthlyValueMonth );
+ r->addMonthlyDate( monthlyValueDay );
+ } else if ( type == "yearly" ) {
+ r->setYearly( 1 );
+ r->addYearlyDate( yearlyValueDay );
+ r->addYearlyMonth( yearlyMonth );
+ } else if ( type == "monthly2" ) {
+ r->setMonthly( monthly2ValueMonth );
+ QBitArray _days( 7 );
+ if ( daysSet )
+ _days = days;
+ else
+ _days.setBit( event->dtStart().date().dayOfWeek() );
+ r->addMonthlyPos( monthly2Recurrency, _days );
+ } else if ( type == "yearly2" ) {
+ r->setYearly( 1 );
+ r->addYearlyMonth( yearly2Month );
+ QBitArray _days( 7 );
+ if ( daysSet )
+ _days = days;
+ else
+ _days.setBit( ( yearly2Day + 5 ) % 7 );
+ r->addYearlyPos( yearly2Recurrency, _days );
+ }
+ r->setEndDate( end.date() );
+ r->setExDates( deleteExceptions );
+}
+
+void KCalResourceSlox::parseTodoAttribute( const QDomElement &e,
+ Todo *todo )
+{
+ QString tag = e.tagName();
+ QString text = decodeText( e.text() );
+ if ( text.isEmpty() ) return;
+
+ if ( tag == fieldName( TaskBegin ) ) {
+ QDateTime dt = WebdavHandler::sloxToQDateTime( text );
+ if ( dt.isValid() ) {
+ todo->setDtStart( dt );
+ todo->setHasStartDate( true );
+ }
+ } else if ( tag == fieldName( TaskEnd ) ) {
+ QDateTime dt = WebdavHandler::sloxToQDateTime( text );
+ if ( dt.isValid() ) {
+ todo->setDtDue( dt );
+ todo->setHasDueDate( true );
+ }
+ } else if ( tag == fieldName( Priority ) ) {
+ int p = text.toInt();
+ if ( p < 1 || p > 3 ) {
+ kdError() << "Unknown priority: " << text << endl;
+ } else {
+ int priority;
+ switch ( p ) {
+ case 1:
+ priority = 9;
+ break;
+ default:
+ case 2:
+ priority = 5;
+ break;
+ case 3:
+ priority = 1;
+ break;
+ }
+ todo->setPriority( priority );
+ }
+ } else if ( tag == fieldName( PercentComplete ) ) {
+ int completed = text.toInt();
+ todo->setPercentComplete( completed );
+ }
+}
+
+void KCalResourceSlox::slotLoadTodosResult( KIO::Job *job )
+{
+ kdDebug() << "KCalResourceSlox::slotLoadTodosJobResult()" << endl;
+
+ if ( job->error() ) {
+ loadError( job->errorString() );
+ } else {
+ kdDebug() << "KCalResourceSlox::slotLoadTodosJobResult() success" << endl;
+
+ QDomDocument doc = mLoadTodosJob->response();
+
+ mWebdavHandler.log( doc.toString( 2 ) );
+
+ QValueList<SloxItem> items = WebdavHandler::getSloxItems( this, doc );
+
+ bool changed = false;
+
+ disableChangeNotification();
+
+ QValueList<SloxItem>::ConstIterator it;
+ for( it = items.begin(); it != items.end(); ++it ) {
+ SloxItem item = *it;
+ QString uid = sloxIdToTodoUid( item.sloxId );
+ if ( item.status == SloxItem::Delete ) {
+ Todo *todo = mCalendar.todo( uid );
+ if ( todo ) {
+ mCalendar.deleteTodo( todo );
+ changed = true;
+ }
+ } else if ( item.status == SloxItem::Create ) {
+ Todo *newTodo = 0;
+ Todo *todo = mCalendar.todo( uid );
+ if ( !todo ) {
+ newTodo = new Todo;
+ todo = newTodo;
+ todo->setUid( uid );
+ todo->setSecrecy( Incidence::SecrecyPrivate );
+ }
+
+ todo->setCustomProperty( "SLOX", "ID", item.sloxId );
+
+ mWebdavHandler.clearSloxAttributeStatus();
+
+ QDomNode n;
+ for( n = item.domNode.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement e = n.toElement();
+ mWebdavHandler.parseSloxAttribute( e );
+ parseIncidenceAttribute( e, todo );
+ parseTodoAttribute( e, todo );
+ }
+
+ mWebdavHandler.setSloxAttributes( todo );
+
+ if ( newTodo ) mCalendar.addTodo( todo );
+
+ changed = true;
+ }
+ }
+
+ enableChangeNotification();
+
+ clearChanges();
+
+ if ( changed ) emit resourceChanged( this );
+
+ emit resourceLoaded( this );
+ }
+
+ mLoadTodosJob = 0;
+
+ if ( mLoadTodosProgress ) mLoadTodosProgress->setComplete();
+ mLoadTodosProgress = 0;
+}
+
+void KCalResourceSlox::slotLoadEventsResult( KIO::Job *job )
+{
+ kdDebug() << "KCalResourceSlox::slotLoadEventsResult() " << long( this ) << endl;
+
+ if ( job->error() ) {
+ loadError( job->errorString() );
+ } else {
+ kdDebug() << "KCalResourceSlox::slotLoadEventsResult() success" << endl;
+
+ QDomDocument doc = mLoadEventsJob->response();
+
+ mWebdavHandler.log( doc.toString( 2 ) );
+
+ QValueList<SloxItem> items = WebdavHandler::getSloxItems( this, doc );
+
+ bool changed = false;
+
+ disableChangeNotification();
+
+ QValueList<SloxItem>::ConstIterator it;
+ for( it = items.begin(); it != items.end(); ++it ) {
+ SloxItem item = *it;
+ QString uid = sloxIdToEventUid( item.sloxId );
+ if ( item.status == SloxItem::Delete ) {
+ Event *event = mCalendar.event( uid );
+ if ( event ) {
+ mCalendar.deleteEvent( event );
+ changed = true;
+ }
+ } else if ( item.status == SloxItem::Create ) {
+ Event *newEvent = 0;
+ Event *event = mCalendar.event( uid );
+ if ( !event ) {
+ newEvent = new Event;
+ event = newEvent;
+ event->setUid( uid );
+ event->setSecrecy( Incidence::SecrecyPrivate );
+ }
+
+ event->setCustomProperty( "SLOX", "ID", item.sloxId );
+
+ QDomNode n = item.domNode.namedItem( fieldName( FullTime ) );
+ event->setFloats( n.toElement().text() == boolToStr( true ) );
+
+ bool doesRecur = false;
+
+ mWebdavHandler.clearSloxAttributeStatus();
+
+ for( n = item.domNode.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement e = n.toElement();
+ mWebdavHandler.parseSloxAttribute( e );
+ parseIncidenceAttribute( e, event );
+ parseEventAttribute( e, event );
+ if ( e.tagName() == fieldName( RecurrenceType ) && e.text() != "no" ) {
+ doesRecur = true;
+ }
+ }
+
+ if ( doesRecur )
+ parseRecurrence( item.domNode, event );
+ else
+ event->recurrence()->unsetRecurs();
+
+ mWebdavHandler.setSloxAttributes( event );
+
+// kdDebug() << "EVENT " << item.uid << " " << event->summary() << endl;
+
+ if ( newEvent ) mCalendar.addEvent( event );
+
+ changed = true;
+ }
+ }
+
+ enableChangeNotification();
+
+ saveCache();
+
+ clearChanges();
+
+ if ( changed ) emit resourceChanged( this );
+
+ emit resourceLoaded( this );
+ }
+
+ mLoadEventsJob = 0;
+
+ if ( mLoadEventsProgress ) mLoadEventsProgress->setComplete();
+ mLoadEventsProgress = 0;
+}
+
+void KCalResourceSlox::slotUploadResult( KIO::Job *job )
+{
+ kdDebug() << "KCalResourceSlox::slotUploadResult()" << endl;
+
+ if ( job->error() ) {
+ saveError( job->errorString() );
+ } else {
+ kdDebug() << "KCalResourceSlox::slotUploadResult() success" << endl;
+
+ if ( !mUploadJob )
+ {
+ kdDebug() << "KCalResourceSlox::slotUploadResult() - mUploadJob was 0" << endl;
+ return;
+ }
+
+ QDomDocument doc = mUploadJob->response();
+
+ kdDebug() << "UPLOAD RESULT:" << endl;
+ kdDebug() << doc.toString( 2 ) << endl;
+
+ QDomElement docElement = doc.documentElement();
+
+ QDomNode responseNode;
+ for( responseNode = docElement.firstChild(); !responseNode.isNull();
+ responseNode = responseNode.nextSibling() ) {
+ QDomElement responseElement = responseNode.toElement();
+ if ( responseElement.tagName() == "response" ) {
+ QDomNode propstat = responseElement.namedItem( "propstat" );
+ if ( propstat.isNull() ) {
+ kdError() << "Unable to find propstat tag." << endl;
+ continue;
+ }
+
+ QDomNode status = propstat.namedItem( "status" );
+ if ( !status.isNull() ) {
+ QDomElement statusElement = status.toElement();
+ QString response = statusElement.text();
+ if ( !response.contains( "200" ) ) {
+ QString error = "'" + mUploadedIncidence->summary() + "'\n";
+ error += response;
+ QDomNode dn = propstat.namedItem( "responsedescription" );
+ QString d = dn.toElement().text();
+ if ( !d.isEmpty() ) error += "\n" + d;
+ saveError( error );
+ continue;
+ }
+ }
+
+ QDomNode prop = propstat.namedItem( "prop" );
+ if ( prop.isNull() ) {
+ kdError() << "Unable to find WebDAV property" << endl;
+ continue;
+ }
+
+ QDomNode sloxIdNode = prop.namedItem( fieldName( ObjectId ) );
+ if ( sloxIdNode.isNull() ) {
+ kdError() << "Unable to find SLOX id." << endl;
+ continue;
+ }
+ QDomElement sloxIdElement = sloxIdNode.toElement();
+ QString sloxId = sloxIdElement.text();
+ kdDebug() << "SLOXID: " << sloxId << endl;
+
+ if ( mUploadIsDelete ) {
+ kdDebug() << "Incidence deleted" << endl;
+ } else {
+ QDomNode clientIdNode = prop.namedItem( fieldName( ClientId ) );
+ if ( clientIdNode.isNull() ) {
+ kdError() << "Unable to find client id." << endl;
+ continue;
+ }
+ QDomElement clientidElement = clientIdNode.toElement();
+ QString clientId = clientidElement.text();
+
+ kdDebug() << "CLIENTID: " << clientId << endl;
+
+ Incidence *i = mUploadedIncidence->clone();
+ QString uid;
+ if ( i->type() == "Event" ) uid = sloxIdToEventUid( sloxId );
+ else if ( i->type() == "Todo" ) uid = sloxIdToTodoUid( sloxId );
+ else {
+ kdError() << "KCalResourceSlox::slotUploadResult(): Unknown type: "
+ << i->type() << endl;
+ }
+ i->setUid( uid );
+ i->setCustomProperty( "SLOX", "ID", sloxId );
+
+ disableChangeNotification();
+ mCalendar.deleteIncidence( mUploadedIncidence );
+ mCalendar.addIncidence( i );
+ saveCache();
+ enableChangeNotification();
+
+ emit resourceChanged( this );
+ }
+ }
+ }
+ }
+
+ mUploadJob = 0;
+
+ mUploadProgress->setComplete();
+ mUploadProgress = 0;
+
+ clearChange( mUploadedIncidence );
+
+ uploadIncidences();
+}
+
+void KCalResourceSlox::slotEventsProgress( KIO::Job *job,
+ unsigned long percent )
+{
+#if 0
+ kdDebug() << "PROGRESS: events " << int( job ) << ": " << percent << endl;
+#else
+ Q_UNUSED( job );
+ Q_UNUSED( percent );
+#endif
+ if ( mLoadEventsProgress ) mLoadEventsProgress->setProgress( percent );
+}
+
+void KCalResourceSlox::slotTodosProgress( KIO::Job *job, unsigned long percent )
+{
+#if 0
+ kdDebug() << "PROGRESS: todos " << int( job ) << ": " << percent << endl;
+#else
+ Q_UNUSED( job );
+ Q_UNUSED( percent );
+#endif
+ if ( mLoadTodosProgress ) mLoadTodosProgress->setProgress( percent );
+}
+
+void KCalResourceSlox::slotUploadProgress( KIO::Job *job, unsigned long percent )
+{
+#if 0
+ kdDebug() << "PROGRESS: upload " << int( job ) << ": " << percent << endl;
+#else
+ Q_UNUSED( job );
+ Q_UNUSED( percent );
+#endif
+ if ( mUploadProgress ) mUploadProgress->setProgress( percent );
+}
+
+bool KCalResourceSlox::confirmSave()
+{
+ if ( !hasChanges() ) return true;
+
+ ConfirmSaveDialog dlg( resourceName(), 0 );
+
+ dlg.addIncidences( addedIncidences(), i18n("Added") );
+ dlg.addIncidences( changedIncidences(), i18n("Changed") );
+ dlg.addIncidences( deletedIncidences(), i18n("Deleted") );
+
+ int result = dlg.exec();
+ return result == QDialog::Accepted;
+}
+
+bool KCalResourceSlox::doSave()
+{
+ kdDebug() << "KCalResourceSlox::save()" << endl;
+
+ if ( readOnly() || !hasChanges() ) {
+ emit resourceSaved( this );
+ return true;
+ }
+
+ if ( mLoadEventsJob || mLoadTodosJob ) {
+ kdWarning() << "KCalResourceSlox::save(): download still in progress."
+ << endl;
+ return false;
+ }
+ if ( mUploadJob ) {
+ kdWarning() << "KCalResourceSlox::save(): upload still in progress."
+ << endl;
+ return false;
+ }
+
+ if ( !confirmSave() ) return false;
+
+ saveCache();
+
+ uploadIncidences();
+
+ return true;
+}
+
+bool KCalResourceSlox::isSaving()
+{
+ return mUploadJob;
+}
+
+void KCalResourceSlox::doClose()
+{
+ kdDebug() << "KCalResourceSlox::doClose()" << endl;
+
+ cancelLoadEvents();
+ cancelLoadTodos();
+
+ if ( mUploadJob ) {
+ kdError() << "KCalResourceSlox::doClose() Still saving" << endl;
+ } else {
+ mCalendar.close();
+ }
+}
+
+KABC::Lock *KCalResourceSlox::lock()
+{
+ return mLock;
+}
+
+void KCalResourceSlox::dump() const
+{
+ ResourceCalendar::dump();
+ kdDebug(5800) << " Url: " << mPrefs->url() << endl;
+}
+
+void KCalResourceSlox::cancelLoadEvents()
+{
+ if ( mLoadEventsJob ) mLoadEventsJob->kill();
+ mLoadEventsJob = 0;
+ if ( mLoadEventsProgress ) mLoadEventsProgress->setComplete();
+ mLoadEventsProgress = 0;
+}
+
+void KCalResourceSlox::cancelLoadTodos()
+{
+ if ( mLoadTodosJob ) mLoadTodosJob->kill();
+ mLoadTodosJob = 0;
+ if ( mLoadTodosProgress ) mLoadTodosProgress->setComplete();
+ mLoadTodosProgress = 0;
+}
+
+void KCalResourceSlox::cancelUpload()
+{
+ if ( mUploadJob ) mUploadJob->kill();
+ mUploadJob = 0;
+ if ( mUploadProgress ) mUploadProgress->setComplete();
+}
+
+QString KCalResourceSlox::sloxIdToEventUid( const QString &sloxId )
+{
+ return "KResources_SLOX_Event_" + sloxId;
+}
+
+QString KCalResourceSlox::sloxIdToTodoUid( const QString &sloxId )
+{
+ return "KResources_SLOX_Todo_" + sloxId;
+}
+
+#include "kcalresourceslox.moc"
diff --git a/kresources/slox/kcalresourceslox.h b/kresources/slox/kcalresourceslox.h
new file mode 100644
index 000000000..2d0022cc7
--- /dev/null
+++ b/kresources/slox/kcalresourceslox.h
@@ -0,0 +1,167 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 KCALRESOURCESLOX_H
+#define KCALRESOURCESLOX_H
+
+#include "sloxbase.h"
+#include "webdavhandler.h"
+
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qdatetime.h>
+#include <qdom.h>
+
+#include <kurl.h>
+#include <kconfig.h>
+#include <kdirwatch.h>
+#include <kdepimmacros.h>
+
+#include <libkcal/incidence.h>
+#include <libkcal/todo.h>
+#include <libkcal/calendarlocal.h>
+#include <libkcal/icalformat.h>
+#include <libkcal/resourcecached.h>
+
+namespace KIO {
+class FileCopyJob;
+class Job;
+class DavJob;
+}
+
+namespace KCal {
+class SloxPrefs;
+}
+
+namespace KPIM {
+class ProgressItem;
+}
+
+class SloxAccounts;
+
+/**
+ This class provides a calendar stored as a remote file.
+*/
+class KDE_EXPORT KCalResourceSlox : public KCal::ResourceCached, public SloxBase
+{
+ Q_OBJECT
+
+ friend class KCalResourceSloxConfig;
+
+ public:
+ /**
+ Reload policy.
+
+ @see setReloadPolicy(), reloadPolicy()
+ */
+ enum { ReloadNever, ReloadOnStartup, ReloadOnceADay, ReloadAlways };
+
+ /**
+ Create resource from configuration information stored in KConfig object.
+ */
+ KCalResourceSlox( const KConfig * );
+ KCalResourceSlox( const KURL &url );
+ ~KCalResourceSlox();
+
+ void readConfig( const KConfig *config );
+ void writeConfig( KConfig *config );
+
+ KCal::SloxPrefs *prefs() const { return mPrefs; }
+
+ KABC::Lock *lock();
+
+ bool isSaving();
+
+ void dump() const;
+
+ protected slots:
+ void slotLoadEventsResult( KIO::Job * );
+ void slotLoadTodosResult( KIO::Job * );
+ void slotUploadResult( KIO::Job * );
+
+ void slotEventsProgress( KIO::Job *job, unsigned long percent );
+ void slotTodosProgress( KIO::Job *job, unsigned long percent );
+ void slotUploadProgress( KIO::Job *job, unsigned long percent );
+
+ void cancelLoadEvents();
+ void cancelLoadTodos();
+ void cancelUpload();
+
+ protected:
+ void doClose();
+ bool doLoad();
+ bool doSave();
+
+ void requestEvents();
+ void requestTodos();
+
+ void uploadIncidences();
+
+ void parseMembersAttribute( const QDomElement &e,
+ KCal::Incidence *incidence );
+ void parseReadRightsAttribute( const QDomElement &e,
+ KCal::Incidence *incidence );
+ void parseIncidenceAttribute( const QDomElement &e,
+ KCal::Incidence *incidence );
+ void parseTodoAttribute( const QDomElement &e, KCal::Todo *todo );
+ void parseEventAttribute( const QDomElement &e, KCal::Event *event );
+ void parseRecurrence( const QDomNode &n, KCal::Event *event );
+
+ void createIncidenceAttributes( QDomDocument &doc,
+ QDomElement &parent,
+ KCal::Incidence *incidence );
+ void createEventAttributes( QDomDocument &doc,
+ QDomElement &parent,
+ KCal::Event *event );
+ void createTodoAttributes( QDomDocument &doc,
+ QDomElement &parent,
+ KCal::Todo *todo );
+ void createRecurrenceAttributes( QDomDocument &doc,
+ QDomElement &parent,
+ KCal::Incidence *incidence );
+
+ bool confirmSave();
+
+ QString sloxIdToEventUid( const QString &sloxId );
+ QString sloxIdToTodoUid( const QString &sloxId );
+
+ private:
+ void init();
+
+ KCal::SloxPrefs *mPrefs;
+
+ KIO::DavJob *mLoadEventsJob;
+ KIO::DavJob *mLoadTodosJob;
+ KIO::DavJob *mUploadJob;
+
+ KPIM::ProgressItem *mLoadEventsProgress;
+ KPIM::ProgressItem *mLoadTodosProgress;
+ KPIM::ProgressItem *mUploadProgress;
+
+ KCal::Incidence *mUploadedIncidence;
+ bool mUploadIsDelete;
+
+ KABC::Lock *mLock;
+
+ WebdavHandler mWebdavHandler;
+
+ SloxAccounts *mAccounts;
+};
+
+#endif
diff --git a/kresources/slox/kcalresourceslox_plugin.cpp b/kresources/slox/kcalresourceslox_plugin.cpp
new file mode 100644
index 000000000..57aa9dc58
--- /dev/null
+++ b/kresources/slox/kcalresourceslox_plugin.cpp
@@ -0,0 +1,40 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 "kcalresourcesloxconfig.h"
+#include "kcalresourceslox.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+
+using namespace KCal;
+
+typedef KRES::PluginFactory<KCalResourceSlox,KCalResourceSloxConfig> SLOXFactory;
+// FIXME: Use K_EXPORT_COMPONENT_FACTORY( kcal_slox, SLOXFactory ); here
+// Problem: How do I insert the catalogue???
+extern "C"
+{
+ void *init_kcal_slox()
+ {
+ KGlobal::locale()->insertCatalogue( "libkcal" );
+ KGlobal::locale()->insertCatalogue( "kabc_slox" );
+ return new SLOXFactory;
+ }
+}
diff --git a/kresources/slox/kcalresourcesloxconfig.cpp b/kresources/slox/kcalresourcesloxconfig.cpp
new file mode 100644
index 000000000..403a5e518
--- /dev/null
+++ b/kresources/slox/kcalresourcesloxconfig.cpp
@@ -0,0 +1,145 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 <typeinfo>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qcheckbox.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <klineedit.h>
+#include <kpushbutton.h>
+
+#include <libkcal/resourcecachedconfig.h>
+
+#include "kcalresourceslox.h"
+#include "kcalsloxprefs.h"
+#include "sloxfolder.h"
+#include "sloxfolderdialog.h"
+#include "sloxfoldermanager.h"
+
+#include "kcalresourcesloxconfig.h"
+
+KCalResourceSloxConfig::KCalResourceSloxConfig( QWidget* parent, const char* name ) :
+ KRES::ConfigWidget( parent, name ), mRes( 0 )
+{
+ resize( 245, 115 );
+ QGridLayout *mainLayout = new QGridLayout( this, 6, 2, KDialog::spacingHint(), KDialog::spacingHint() );
+
+ QLabel *label = new QLabel( i18n( "Download from:" ), this );
+
+ mDownloadUrl = new KURLRequester( this );
+ mDownloadUrl->setMode( KFile::File );
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mDownloadUrl, 1, 1 );
+
+ label = new QLabel( i18n("User:"), this );
+ mainLayout->addWidget( label, 2, 0 );
+
+ mUserEdit = new KLineEdit( this );
+ mainLayout->addWidget( mUserEdit, 2, 1 );
+
+ label = new QLabel( i18n("Password:"), this );
+ mainLayout->addWidget( label, 3, 0 );
+
+ mPasswordEdit = new KLineEdit( this );
+ mainLayout->addWidget( mPasswordEdit, 3, 1 );
+ mPasswordEdit->setEchoMode( KLineEdit::Password );
+
+ mLastSyncCheck = new QCheckBox( i18n("Only load data since last sync"),
+ this );
+ mainLayout->addMultiCellWidget( mLastSyncCheck, 4, 4, 0, 1 );
+
+ mCalButton = new KPushButton( i18n("Calendar Folder..."), this );
+ mainLayout->addWidget( mCalButton, 5, 0 );
+ connect( mCalButton, SIGNAL( clicked() ), SLOT( selectCalendarFolder() ) );
+
+ mTaskButton = new KPushButton( i18n("Task Folder..."), this );
+ mainLayout->addWidget( mTaskButton, 5, 1 );
+ connect( mTaskButton, SIGNAL( clicked() ), SLOT( selectTaskFolder() ) );
+
+ mReloadConfig = new KCal::ResourceCachedReloadConfig( this );
+ mainLayout->addMultiCellWidget( mReloadConfig, 6, 6, 0, 1 );
+
+ mSaveConfig = new KCal::ResourceCachedSaveConfig( this );
+ mainLayout->addMultiCellWidget( mSaveConfig, 7, 7, 0, 1 );
+}
+
+void KCalResourceSloxConfig::loadSettings( KRES::Resource *resource )
+{
+ KCalResourceSlox *res = static_cast<KCalResourceSlox *>( resource );
+ mRes = res;
+ if ( mRes->resType() == "slox" ) { // we don't have folder selection for SLOX
+ mCalButton->setEnabled( false );
+ mTaskButton->setEnabled( false );
+ }
+ if ( res ) {
+ mDownloadUrl->setURL( res->prefs()->url() );
+ mLastSyncCheck->setChecked( res->prefs()->useLastSync() );
+ mUserEdit->setText( res->prefs()->user() );
+ mPasswordEdit->setText( res->prefs()->password() );
+ mCalendarFolderId = res->prefs()->calendarFolderId();
+ mTaskFolderId = res->prefs()->taskFolderId();
+ mReloadConfig->loadSettings( res );
+ mSaveConfig->loadSettings( res );
+ } else {
+ kdError(5700) << "KCalResourceSloxConfig::loadSettings(): no KCalResourceSlox, cast failed" << endl;
+ }
+}
+
+void KCalResourceSloxConfig::saveSettings( KRES::Resource *resource )
+{
+ KCalResourceSlox *res = static_cast<KCalResourceSlox*>( resource );
+ if ( res ) {
+ res->prefs()->setUrl( mDownloadUrl->url() );
+ res->prefs()->setUseLastSync( mLastSyncCheck->isChecked() );
+ res->prefs()->setUser( mUserEdit->text() );
+ res->prefs()->setPassword( mPasswordEdit->text() );
+ res->prefs()->setCalendarFolderId( mCalendarFolderId );
+ res->prefs()->setTaskFolderId( mTaskFolderId );
+ mReloadConfig->saveSettings( res );
+ mSaveConfig->saveSettings( res );
+ } else {
+ kdError(5700) << "KCalResourceSloxConfig::saveSettings(): no KCalResourceSlox, cast failed" << endl;
+ }
+}
+
+void KCalResourceSloxConfig::selectCalendarFolder()
+{
+ SloxFolderManager *manager = new SloxFolderManager( mRes, mDownloadUrl->url() );
+ SloxFolderDialog *dialog = new SloxFolderDialog( manager, ::Calendar, this );
+ dialog->setSelectedFolder( mCalendarFolderId );
+ if ( dialog->exec() == QDialog::Accepted )
+ mCalendarFolderId = dialog->selectedFolder();
+}
+
+void KCalResourceSloxConfig::selectTaskFolder( )
+{
+ SloxFolderManager *manager = new SloxFolderManager( mRes, mDownloadUrl->url() );
+ SloxFolderDialog *dialog = new SloxFolderDialog( manager, Tasks, this );
+ dialog->setSelectedFolder( mTaskFolderId );
+ if ( dialog->exec() == QDialog::Accepted )
+ mTaskFolderId = dialog->selectedFolder();
+}
+
+#include "kcalresourcesloxconfig.moc"
diff --git a/kresources/slox/kcalresourcesloxconfig.h b/kresources/slox/kcalresourcesloxconfig.h
new file mode 100644
index 000000000..a656478d2
--- /dev/null
+++ b/kresources/slox/kcalresourcesloxconfig.h
@@ -0,0 +1,75 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 KCALRESOURCESLOXCONFIG_H
+#define KCALRESOURCESLOXCONFIG_H
+
+#include <kurlrequester.h>
+#include <kdepimmacros.h>
+
+#include <kresources/resource.h>
+#include <kresources/configwidget.h>
+
+class QCheckBox;
+class KLineEdit;
+class KPushButton;
+
+namespace KCal {
+class ResourceCachedReloadConfig;
+class ResourceCachedSaveConfig;
+}
+
+class SloxBase;
+
+/**
+ Configuration widget for SLOX resource.
+
+ @see KCalResourceSlox
+*/
+class KDE_EXPORT KCalResourceSloxConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+ public:
+ KCalResourceSloxConfig( QWidget *parent = 0, const char *name = 0 );
+
+ public slots:
+ virtual void loadSettings( KRES::Resource *resource );
+ virtual void saveSettings( KRES::Resource *resource );
+
+ private slots:
+ void selectCalendarFolder();
+ void selectTaskFolder();
+
+ private:
+ KURLRequester *mDownloadUrl;
+ KLineEdit *mUserEdit;
+ KLineEdit *mPasswordEdit;
+ QCheckBox *mLastSyncCheck;
+ KPushButton *mCalButton;
+ KPushButton *mTaskButton;
+ QString mCalendarFolderId;
+ QString mTaskFolderId;
+
+ KCal::ResourceCachedReloadConfig *mReloadConfig;
+ KCal::ResourceCachedSaveConfig *mSaveConfig;
+
+ SloxBase *mRes;
+};
+
+#endif
diff --git a/kresources/slox/kcalsloxprefs.kcfgc b/kresources/slox/kcalsloxprefs.kcfgc
new file mode 100644
index 000000000..0c1bff263
--- /dev/null
+++ b/kresources/slox/kcalsloxprefs.kcfgc
@@ -0,0 +1,11 @@
+# Code generation options for kconfig_compiler
+File=kresources_kcal_slox.kcfg
+ClassName=SloxPrefs
+NameSpace=KCal
+Singleton=false
+Mutators=true
+Inherits=KResourcePrefs
+IncludeFiles=libkdepim/kresourceprefs.h
+GlobalEnums=true
+#ItemAccessors=true
+#SetUserTexts=true
diff --git a/kresources/slox/kresources_kabc_slox.kcfg b/kresources/slox/kresources_kabc_slox.kcfg
new file mode 100644
index 000000000..159605ba3
--- /dev/null
+++ b/kresources/slox/kresources_kabc_slox.kcfg
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="kresources_kabc_sloxrc"/>
+
+ <group name="General">
+ <entry type="String" name="Url">
+ <label>Base Url</label>
+ </entry>
+ <entry type="String" name="User">
+ <label>User Name</label>
+ </entry>
+ <entry type="Password" name="Password">
+ <label>Password</label>
+ </entry>
+ <entry type="Bool" name="UseLastSync">
+ <label>Only load data since last sync</label>
+ <default>true</default>
+ </entry>
+ <entry type="String" name="FolderId">
+ <label>Folder ID</label>
+ <default></default>
+ </entry>
+ <entry type="DateTime" name="LastSync">
+ <label>Last Sync</label>
+ </entry>
+ </group>
+
+</kcfg>
diff --git a/kresources/slox/kresources_kcal_slox.kcfg b/kresources/slox/kresources_kcal_slox.kcfg
new file mode 100644
index 000000000..9e4e6f4eb
--- /dev/null
+++ b/kresources/slox/kresources_kcal_slox.kcfg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="kresources_kcal_sloxrc"/>
+
+ <group name="General">
+ <entry type="String" name="Url">
+ <label>Base Url</label>
+ </entry>
+ <entry type="String" name="User">
+ <label>User Name</label>
+ </entry>
+ <entry type="Password" name="Password">
+ <label>Password</label>
+ </entry>
+ <entry type="DateTime" name="LastEventSync">
+ <label>Last Event Sync</label>
+ </entry>
+ <entry type="DateTime" name="LastTodoSync">
+ <label>Last To-do Sync</label>
+ </entry>
+ <entry type="Bool" name="UseLastSync">
+ <label>Only load data since last sync</label>
+ <default>true</default>
+ </entry>
+ <entry type="String" name="CalendarFolderId">
+ <label>Calendar Folder</label>
+ <default></default>
+ </entry>
+ <entry type="String" name="TaskFolderId">
+ <label>Task Folder</label>
+ <default></default>
+ </entry>
+ </group>
+
+</kcfg>
diff --git a/kresources/slox/sloxaccounts.cpp b/kresources/slox/sloxaccounts.cpp
new file mode 100644
index 000000000..35203b06f
--- /dev/null
+++ b/kresources/slox/sloxaccounts.cpp
@@ -0,0 +1,222 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2005 Volker Krause <volker.krause@rwth-aachen.de>
+
+ 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 "sloxaccounts.h"
+#include "sloxbase.h"
+#include "webdavhandler.h"
+
+#include <libkcal/freebusyurlstore.h>
+
+#include <kstaticdeleter.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <kio/job.h>
+#include <kio/davjob.h>
+#include <kstringhandler.h>
+#include <kconfig.h>
+
+#include <qfile.h>
+#include <qdom.h>
+#include <qstring.h>
+
+SloxAccounts::SloxAccounts( SloxBase *res, const KURL &baseUrl )
+ : mBaseUrl( baseUrl ), mRes( res )
+{
+ kdDebug() << "SloxAccounts(): " << baseUrl << endl;
+
+ mDownloadJob = 0;
+
+ QString server = mBaseUrl.host();
+
+ QStringList l = QStringList::split( '.', server );
+
+ if ( l.count() < 2 ) mDomain = server;
+ else mDomain = l[ l.count() - 2 ] + "." + l[ l.count() - 1 ];
+
+ readAccounts();
+}
+
+SloxAccounts::~SloxAccounts()
+{
+ kdDebug() << "~SloxAccounts()" << endl;
+
+ if ( mDownloadJob ) mDownloadJob->kill();
+}
+
+void SloxAccounts::insertUser( const QString &id, const KABC::Addressee &a )
+{
+ kdDebug() << "SloxAccount::insertUser() " << id << endl;
+
+ mUsers.replace( id, a );
+
+ QString email = a.preferredEmail();
+
+ QString url = "http://" + mBaseUrl.host() + "/servlet/webdav.freebusy?username=";
+ url += id + "&server=" + mDomain;
+
+ KCal::FreeBusyUrlStore::self()->writeUrl( email, url );
+}
+
+KABC::Addressee SloxAccounts::lookupUser( const QString &id )
+{
+ QMap<QString, KABC::Addressee>::ConstIterator it;
+ it = mUsers.find( id );
+ if ( it == mUsers.end() ) {
+ requestAccounts();
+ return KABC::Addressee();
+ } else {
+ return *it;
+ }
+}
+
+QString SloxAccounts::lookupId( const QString &email )
+{
+ kdDebug() << "SloxAccounts::lookupId() " << email << endl;
+
+ QMap<QString, KABC::Addressee>::ConstIterator it;
+ for( it = mUsers.begin(); it != mUsers.end(); ++it ) {
+ kdDebug() << "PREF: " << (*it).preferredEmail() << endl;
+ kdDebug() << "KEY: " << it.key() << endl;
+ if ( (*it).preferredEmail() == email ) return it.key();
+ }
+ requestAccounts();
+
+ int pos = email.find( '@' );
+ if ( pos < 0 ) return email;
+ else return email.left( pos );
+}
+
+void SloxAccounts::requestAccounts()
+{
+ kdDebug() << "SloxAccounts::requestAccounts()" << endl;
+
+ if ( mDownloadJob ) {
+ kdDebug() << "SloxAccount::requestAccounts(): Download still in progress"
+ << endl;
+ return;
+ }
+
+ if ( mRes->resType() == "slox" ) {
+ KURL url = mBaseUrl;
+ url.addPath( "/servlet/webdav.groupuser" );
+ url.setQuery( "?user=*&group=*&groupres=*&res=*&details=t" );
+
+ kdDebug() << "SloxAccounts::requestAccounts() URL: " << url << endl;
+
+ mDownloadJob = KIO::file_copy( url, cacheFile(), -1, true, false, false );
+ } else if ( mRes->resType() == "ox" ) {
+ KURL url = mBaseUrl;
+ url.setPath( "/servlet/webdav.groupuser/" );
+
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ QDomElement prop = WebdavHandler::addDavElement( doc, root, "prop" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "user", "*" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "group", "*" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "resource", "*" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "resourcegroup", "*" );
+
+ kdDebug() << k_funcinfo << doc.toString( 2 ) << endl;
+
+ mDownloadJob = KIO::davPropFind( url, doc, "0", false );
+ }
+
+ connect( mDownloadJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotResult( KIO::Job * ) ) );
+}
+
+void SloxAccounts::slotResult( KIO::Job *job )
+{
+ kdDebug() << "SloxAccounts::slotResult()" << endl;
+
+ if ( job->error() ) {
+ job->showErrorDialog( 0 );
+ } else {
+ if ( mRes->resType() == "ox" ) {
+ QFile f( cacheFile() );
+ if ( !f.open( IO_WriteOnly ) ) {
+ kdWarning() << "Unable to open '" << cacheFile() << "'" << endl;
+ return;
+ }
+ QTextStream stream ( &f );
+ stream << static_cast<KIO::DavJob*>( mDownloadJob )->response();
+ f.close();
+ }
+ readAccounts();
+ }
+
+ mDownloadJob = 0;
+}
+
+QString SloxAccounts::cacheFile() const
+{
+ QString host = mBaseUrl.host();
+
+ QString file = locateLocal( "cache", "slox/accounts_" + host );
+
+ kdDebug() << "SloxAccounts::cacheFile(): " << file << endl;
+
+ return file;
+}
+
+void SloxAccounts::readAccounts()
+{
+ kdDebug() << "SloxAccounts::readAccounts()" << endl;
+
+ QFile f( cacheFile() );
+ if ( !f.open( IO_ReadOnly ) ) {
+ kdDebug() << "Unable to open '" << cacheFile() << "'" << endl;
+ requestAccounts();
+ return;
+ }
+
+ QDomDocument doc;
+ doc.setContent( &f );
+
+// kdDebug() << "SLOX ACCOUNTS: " << doc.toString( 2 ) << endl;
+
+ QDomElement docElement = doc.documentElement();
+
+ mUsers.clear();
+
+ QDomNodeList nodes = doc.elementsByTagName( mRes->resType() == "ox" ? "ox:user" : "user" );
+ for( uint i = 0; i < nodes.count(); ++i ) {
+ QDomElement element = nodes.item(i).toElement();
+ QString id;
+ KABC::Addressee a;
+ QDomNode n;
+ for( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement e = n.toElement();
+ QString tag = e.tagName();
+ // remove XML namespace
+ tag = tag.right( tag.length() - ( tag.find( ':' ) + 1 ) );
+ QString value = e.text();
+ if ( tag == "uid" ) id = value;
+ else if ( tag == "mail" ) a.insertEmail( value, true );
+ else if ( tag == "forename" ) a.setGivenName( value );
+ else if ( tag == "surename" ) a.setFamilyName( value );
+ }
+// kdDebug() << "MAIL: " << a.preferredEmail() << endl;
+ insertUser( id, a );
+ }
+}
+
+#include "sloxaccounts.moc"
diff --git a/kresources/slox/sloxaccounts.h b/kresources/slox/sloxaccounts.h
new file mode 100644
index 000000000..ea3e664e2
--- /dev/null
+++ b/kresources/slox/sloxaccounts.h
@@ -0,0 +1,66 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 SLOXACCOUNTS_H
+#define SLOXACCOUNTS_H
+
+#include <kabc/addressee.h>
+#include <kdepimmacros.h>
+#include <qobject.h>
+
+namespace KIO {
+class Job;
+}
+
+class SloxBase;
+
+class KDE_EXPORT SloxAccounts : public QObject
+{
+ Q_OBJECT
+ public:
+ SloxAccounts( SloxBase *res, const KURL &baseUrl );
+ ~SloxAccounts();
+
+ void insertUser( const QString &id, const KABC::Addressee &a );
+
+ KABC::Addressee lookupUser( const QString &id );
+
+ QString lookupId( const QString &email );
+
+ protected:
+ void requestAccounts();
+ void readAccounts();
+
+ QString cacheFile() const;
+
+ protected slots:
+ void slotResult( KIO::Job * );
+
+ private:
+ QString mDomain;
+
+ KIO::Job *mDownloadJob;
+
+ QMap<QString, KABC::Addressee> mUsers; // map users ids to addressees.
+
+ KURL mBaseUrl;
+ SloxBase *mRes;
+};
+
+#endif
diff --git a/kresources/slox/sloxbase.cpp b/kresources/slox/sloxbase.cpp
new file mode 100644
index 000000000..c58990593
--- /dev/null
+++ b/kresources/slox/sloxbase.cpp
@@ -0,0 +1,139 @@
+/*
+ Copyright (c) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
+ Copyright (c) 2005 by Florian Schröder <florian@deltatauchi.de>
+
+ 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 "sloxbase.h"
+
+#include <kdebug.h>
+#include <kresources/resource.h>
+
+static QString mFieldNameMap[][2] =
+{
+ // SLOX, OX
+ {"sloxid", "object_id"}, // system fields
+ {"clientid", "client_id"},
+ {"folderid", "folder_id"},
+ {"lastsync", "lastsync"},
+ {"objecttype", "objectmode"},
+ {"sloxstatus", "object_status"},
+ {"createfrom", "created_by"},
+ {"categories", "categories"},
+ // incidence fields
+ {"title", "title"},
+ {"description", "note"},
+ {"members", "participants"},
+ {"member", "user"},
+ {"reminder", "alarm"},
+ // recurrence fields
+ {"date_sequence", "recurrence_type"},
+ {"ds_ends", "until"},
+ {"daily_value", "interval"},
+ {"weekly_value", "interval"},
+ {"monthly_value_month", "interval"},
+ {"monthly_value_day", "day_in_month"},
+ {"yearly_value_day", "day_in_month"},
+ {"yearly_month", "month"},
+ {"monthly2_value_month", "interval"},
+ {"monthly2_day", "days"},
+ {"monthly2_recurrency", "day_in_month"},
+ {"yearly2_day", "days"},
+ {"yearly2_reccurency", "day_in_month"}, // this is not a typo, this is what SLOX erally sends!
+ {"yearly2_month", "month"},
+ {"deleteexceptions", "deleteexceptions"},
+ // event fields
+ {"begins", "start_date"},
+ {"ends", "end_date"},
+ {"location", "location"},
+ {"full_time", "full_time"},
+ // task fields
+ {"startdate", "start_date"},
+ {"deadline", "end_date"},
+ {"priority", "priority"},
+ {"status", "percent_complete"},
+ // contact fields
+ {"lastname", "last_name"},
+ {"firstname", "first_name"},
+ {"n/a", "second_name"},
+ {"displayname", "displayname"}, // FIXME: what's this in SLOX?
+ {"title", "title"},
+ {"n/a", "suffix"},
+ {"position", "position"},
+ {"n/a", "company"}, // SLOX handles company separately
+ {"department", "department"},
+ {"email", "email1"},
+ {"email2", "email2"},
+ {"privateemail", "email3"},
+ {"privateemail2", "email3"}, // OX has only three email fields
+ {"birthday", "birthday"},
+ {"privateurl", "url"},
+ {"comment", "note"},
+ {"n/a", "image1"}, // not supported by SLOX
+ {"n/a", "instant_messenger"},
+ {"n/a", "room_number"},
+ {"n/a", "profession"},
+ {"n/a", "managers_name"},
+ {"n/a", "assistants_name"},
+ {"n/a", "spouse_name"},
+ {"n/a", "anniversary"},
+ {"n/a", "nickname"},
+ {"street", "street"}, // address fields
+ {"zipcode", "postal_code"},
+ {"city", "city"},
+ {"state", "state"},
+ {"country", "country"},
+ {"private", ""}, // address type prefix
+ {"business_", "business_"}, // doesn't work with SLOX
+ {"second_", "second_"},
+};
+
+SloxBase::SloxBase( KRES::Resource * res ) :
+ mRes( res )
+{
+}
+
+QString SloxBase::decodeText( const QString & text )
+{
+ if ( mRes->type() == "ox" )
+ return text;
+ return QString::fromUtf8( text.latin1() );
+}
+
+QString SloxBase::fieldName( Field f )
+{
+ int t = 0;
+ if ( mRes->type() == "ox" )
+ t = 1;
+ return mFieldNameMap[f][t];
+}
+
+QString SloxBase::resType( ) const
+{
+ return mRes->type();
+}
+
+QString SloxBase::boolToStr( bool b )
+{
+ if ( mRes->type() == "ox" ) {
+ if ( b )
+ return "true";
+ return "false";
+ }
+ if ( b )
+ return "yes";
+ return "no";
+}
diff --git a/kresources/slox/sloxbase.h b/kresources/slox/sloxbase.h
new file mode 100644
index 000000000..90afb16fa
--- /dev/null
+++ b/kresources/slox/sloxbase.h
@@ -0,0 +1,115 @@
+/*
+ Copyright (c) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
+ Copyright (c) 2005 by Florian Schröder <florian@deltatauchi.de>
+
+ 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 SLOXUTILS_H
+#define SLOXUTILS_H
+
+#include <qstring.h>
+#include <kdepimmacros.h>
+
+namespace KRES {
+class Resource;
+}
+
+class KDE_EXPORT SloxBase {
+ public:
+ enum Field {
+ ObjectId = 0, // system fields
+ ClientId,
+ FolderId,
+ LastSync,
+ ObjectType,
+ ObjectStatus,
+ CreatedBy,
+ Categories,
+ IncidenceTitle, // incidence fields
+ Description,
+ Participants,
+ Participant,
+ Reminder,
+ RecurrenceType, // recurrence fields
+ RecurrenceEnd,
+ RecurrenceDailyFreq,
+ RecurrenceWeeklyFreq,
+ RecurrenceMonthlyFreq,
+ RecurrenceMonthlyDay,
+ RecurrenceYearlyDay,
+ RecurrenceYearlyMonth,
+ RecurrenceMonthly2Freq,
+ RecurrenceMonthly2Day,
+ RecurrenceMonthly2Pos,
+ RecurrenceYearly2Day,
+ RecurrenceYearly2Pos,
+ RecurrenceYearly2Month,
+ RecurrenceDelEx,
+ EventBegin, // event fields
+ EventEnd,
+ Location,
+ FullTime,
+ TaskBegin, // task fields
+ TaskEnd,
+ Priority,
+ PercentComplete,
+ FamilyName, // contact fields
+ GivenName,
+ SecondName,
+ DisplayName,
+ Title,
+ Suffix,
+ Role,
+ Organization,
+ Department,
+ PrimaryEmail,
+ SecondaryEmail1,
+ SecondaryEmail2,
+ SecondaryEmail3,
+ Birthday,
+ Url,
+ Comment,
+ Image,
+ InstantMsg,
+ Office,
+ Profession,
+ ManagersName,
+ AssistantsName,
+ SpousesName,
+ Anniversary,
+ NickName,
+ Street, // address fields
+ PostalCode,
+ City,
+ State,
+ Country,
+ HomePrefix, // address type prefixes
+ BusinessPrefix,
+ OtherPrefix
+ };
+
+ SloxBase( KRES::Resource *res );
+
+ QString decodeText( const QString &text );
+ QString fieldName( Field f );
+ QString resType() const;
+ QString boolToStr( bool b );
+
+ private:
+ KRES::Resource *mRes;
+};
+
+#endif
diff --git a/kresources/slox/sloxfolder.cpp b/kresources/slox/sloxfolder.cpp
new file mode 100644
index 000000000..157463149
--- /dev/null
+++ b/kresources/slox/sloxfolder.cpp
@@ -0,0 +1,49 @@
+/*
+ Copyright (c) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
+ Copyright (c) 2005 by Florian Schröder <florian@deltatauchi.de>
+
+ 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 <klocale.h>
+
+#include "sloxfolder.h"
+
+SloxFolder::SloxFolder( const QString &id, const QString &parentId, const QString &type, const QString &name, bool def ) :
+ item( 0 ),
+ mId( id ),
+ mParentId( parentId ),
+ mName( name ),
+ mDefault( def )
+{
+ if ( type == "calendar" )
+ mType = Calendar;
+ else if ( type == "task" )
+ mType = Tasks;
+ else if ( type == "contact" )
+ mType = Contacts;
+ else
+ mType = Unbound;
+}
+
+QString SloxFolder::name( ) const
+{
+ // special cases for system folders
+ if ( mName == "system_global" )
+ return i18n( "Global Addressbook" );
+ if ( mName == "system_ldap" )
+ return i18n( "Internal Addressbook" );
+ return mName;
+}
diff --git a/kresources/slox/sloxfolder.h b/kresources/slox/sloxfolder.h
new file mode 100644
index 000000000..bda529ba4
--- /dev/null
+++ b/kresources/slox/sloxfolder.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (c) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
+ Copyright (c) 2005 by Florian Schröder <florian@deltatauchi.de>
+
+ 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 SLOXFOLDER_H
+#define SLOXFOLDER_H
+
+#include <qstring.h>
+#include <kdepimmacros.h>
+
+class KListViewItem;
+
+enum FolderType {
+ Unbound,
+ Calendar,
+ Tasks,
+ Contacts
+};
+
+class KDE_EXPORT SloxFolder
+{
+ public:
+ SloxFolder( const QString &id, const QString &parentId, const QString &type, const QString &name, bool def = false );
+
+ QString id() const { return mId; }
+ QString parentId() const { return mParentId; }
+ FolderType type() const { return mType; }
+ QString name() const;
+ bool isDefault() const { return mDefault; }
+
+ KListViewItem *item;
+
+ private:
+ QString mId, mParentId;
+ FolderType mType;
+ QString mName;
+ bool mDefault;
+};
+
+#endif
diff --git a/kresources/slox/sloxfolderdialog.cpp b/kresources/slox/sloxfolderdialog.cpp
new file mode 100644
index 000000000..b188fb2fa
--- /dev/null
+++ b/kresources/slox/sloxfolderdialog.cpp
@@ -0,0 +1,125 @@
+/*
+ Copyright (c) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
+
+ 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 <kiconloader.h>
+#include <kguiitem.h>
+#include <klistview.h>
+#include <klocale.h>
+
+#include "sloxfolderdialog.h"
+#include "sloxfoldermanager.h"
+
+SloxFolderDialog::SloxFolderDialog( SloxFolderManager *manager, FolderType type, QWidget *parent, const char *name ) :
+ KDialogBase( parent, name, true, i18n("Select Folder"), Ok|Cancel|User1, Ok, false, KGuiItem( i18n("Reload"), "reload" ) ),
+ mManager( manager ),
+ mFolderType( type )
+{
+ mListView = new KListView( this );
+ mListView->setRootIsDecorated( true );
+ mListView->setShowSortIndicator( true );
+ mListView->addColumn( i18n("Folder") );
+ mListView->addColumn( i18n("Folder ID"), 0 );
+ setMainWidget( mListView );
+ updateFolderView();
+ connect( manager, SIGNAL( foldersUpdated() ), SLOT( updateFolderView() ) );
+}
+
+SloxFolderDialog::~SloxFolderDialog()
+{
+ QMap<QString, SloxFolder*> folders = mManager->folders();
+ QMap<QString, SloxFolder*>::Iterator it;
+ for ( it = folders.begin(); it != folders.end(); ++it )
+ (*it)->item = 0;
+}
+
+void SloxFolderDialog::updateFolderView()
+{
+ QString selected = selectedFolder();
+ mListView->clear();
+ QMap<QString, SloxFolder*> folders = mManager->folders();
+ QMap<QString, SloxFolder*>::Iterator it;
+ for ( it = folders.begin(); it != folders.end(); ++it )
+ createFolderViewItem( *it );
+ setSelectedFolder( selected );
+}
+
+void SloxFolderDialog::slotUser1( )
+{
+ mManager->requestFolders();
+}
+
+void SloxFolderDialog::createFolderViewItem( SloxFolder *folder )
+{
+ if ( folder->item )
+ return;
+ if ( folder->type() != mFolderType && folder->type() != Unbound )
+ return;
+ if( mManager->folders().contains( folder->parentId() ) ) {
+ SloxFolder *parent = mManager->folders()[folder->parentId()];
+ createFolderViewItem( parent );
+ if ( parent->item )
+ folder->item = new KListViewItem( parent->item );
+ else
+ folder->item = new KListViewItem( mListView );
+ } else {
+ folder->item = new KListViewItem( mListView );
+ }
+ folder->item->setText( 0, folder->name() );
+ folder->item->setText( 1, folder->id() );
+ KGlobal::instance()->iconLoader()->addAppDir( "kmail" );
+ switch ( folder->type() ) {
+ case Calendar:
+ folder->item->setPixmap( 0, SmallIcon( "kmgroupware_folder_calendar" ) );
+ break;
+ case Tasks:
+ folder->item->setPixmap( 0, SmallIcon( "kmgroupware_folder_tasks" ) );
+ break;
+ case Contacts:
+ folder->item->setPixmap( 0, SmallIcon( "kmgroupware_folder_contacts" ) );
+ break;
+ default:
+ folder->item->setPixmap( 0, SmallIcon( "folder" ) );
+ break;
+ }
+}
+
+QString SloxFolderDialog::selectedFolder() const
+{
+ QListViewItem *item = mListView->selectedItem();
+ if ( item )
+ return item->text( 1 );
+ return "-1"; // OX default folder
+}
+
+void SloxFolderDialog::setSelectedFolder( const QString &id )
+{
+ QMap<QString, SloxFolder*> folders = mManager->folders();
+ QMap<QString, SloxFolder*>::Iterator it;
+ for ( it = folders.begin(); it != folders.end(); ++it ) {
+ if ( !(*it)->item )
+ continue;
+ if ( (*it)->id() == id || ( ( id.isEmpty() || id == "-1" ) && (*it)->isDefault() ) ) {
+ mListView->setSelected( (*it)->item, true );
+ mListView->ensureItemVisible( (*it)->item );
+ break;
+ }
+ }
+}
+
+#include "sloxfolderdialog.moc"
diff --git a/kresources/slox/sloxfolderdialog.h b/kresources/slox/sloxfolderdialog.h
new file mode 100644
index 000000000..37287d1b1
--- /dev/null
+++ b/kresources/slox/sloxfolderdialog.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (c) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
+
+ 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 SLOXFOLDERDIALOG_H
+#define SLOXFOLDERDIALOG_H
+
+#include <qstring.h>
+#include <kdialogbase.h>
+
+#include "sloxfolder.h"
+
+class KListView;
+class SloxFolder;
+class SloxFolderManager;
+
+class SloxFolderDialog : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ SloxFolderDialog( SloxFolderManager *manager, FolderType type, QWidget* parent = 0, const char *name = 0 );
+ ~SloxFolderDialog();
+
+ QString selectedFolder() const;
+ void setSelectedFolder( const QString &id );
+
+ protected slots:
+ virtual void slotUser1();
+ void updateFolderView();
+
+ private:
+ void createFolderViewItem( SloxFolder *folder );
+
+ private:
+ KListView *mListView;
+ SloxFolderManager *mManager;
+ QString mFolderId;
+ FolderType mFolderType;
+};
+
+#endif
diff --git a/kresources/slox/sloxfoldermanager.cpp b/kresources/slox/sloxfoldermanager.cpp
new file mode 100644
index 000000000..b693767ca
--- /dev/null
+++ b/kresources/slox/sloxfoldermanager.cpp
@@ -0,0 +1,172 @@
+/*
+ Copyright (c) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
+ Copyright (c) 2005 by Florian Schröder <florian@deltatauchi.de>
+
+ 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 <qfile.h>
+#include <qdom.h>
+#include <qstring.h>
+
+#include <kdebug.h>
+#include <kio/job.h>
+#include <kio/davjob.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include "sloxbase.h"
+#include "sloxfolder.h"
+#include "sloxfoldermanager.h"
+#include "webdavhandler.h"
+
+
+SloxFolderManager::SloxFolderManager( SloxBase *res, const KURL & baseUrl ) :
+ mDownloadJob( 0 ),
+ mBaseUrl( baseUrl ),
+ mRes( res )
+{
+ kdDebug() << k_funcinfo << baseUrl << endl;
+ readFolders();
+}
+
+SloxFolderManager::~SloxFolderManager()
+{
+ if ( mDownloadJob )
+ mDownloadJob->kill();
+ QMap<QString, SloxFolder*>::Iterator it;
+ for ( it = mFolders.begin(); it != mFolders.end(); ++it )
+ delete *it;
+ mFolders.clear();
+}
+
+void SloxFolderManager::requestFolders()
+{
+ kdDebug() << k_funcinfo << endl;
+
+ if ( mDownloadJob ) {
+ kdDebug() << k_funcinfo << "Download still in progress" << endl;
+ return;
+ }
+
+ KURL url = mBaseUrl;
+ url.setPath( "/servlet/webdav.folders/file.xml" );
+
+ QDomDocument doc;
+ QDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ QDomElement prop = WebdavHandler::addDavElement( doc, root, "prop" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "objectmode", "NEW_AND_MODIFIED" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "lastsync", "0" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "foldertype", "PRIVATE" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "foldertype", "PUBLIC" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "foldertype", "SHARED" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "foldertype", "GLOBALADDRESSBOOK" );
+ WebdavHandler::addSloxElement( mRes, doc, prop, "foldertype", "INTERNALUSERS" );
+
+ kdDebug() << k_funcinfo << doc.toString( 2 ) << endl;
+
+ mDownloadJob = KIO::davPropFind( url, doc, "0", false );
+
+ connect( mDownloadJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotResult( KIO::Job * ) ) );
+}
+
+void SloxFolderManager::slotResult( KIO::Job *job )
+{
+ kdDebug() << k_funcinfo << endl;
+
+ if ( job->error() ) {
+ job->showErrorDialog( 0 );
+ } else {
+ kdDebug() << k_funcinfo << " success, writing to " << cacheFile() << endl;
+ QFile f( cacheFile() );
+ if ( !f.open( IO_WriteOnly ) ) {
+ kdDebug() << "Unable to open '" << cacheFile() << "'" << endl;
+ return;
+ }
+ QTextStream stream ( &f );
+ stream << mDownloadJob->response();
+ f.close();
+ readFolders();
+ }
+
+ mDownloadJob = 0;
+ emit foldersUpdated();
+}
+
+QString SloxFolderManager::cacheFile() const
+{
+ QString host = mBaseUrl.host();
+
+ QString file = locateLocal( "cache", "slox/folders_" + host );
+
+ kdDebug() << k_funcinfo << file << endl;
+
+ return file;
+}
+
+void SloxFolderManager::readFolders()
+{
+ kdDebug() << k_funcinfo << endl;
+
+ QFile f( cacheFile() );
+ if ( !f.open( IO_ReadOnly ) ) {
+ kdDebug() << "Unable to open '" << cacheFile() << "'" << endl;
+ requestFolders();
+ return;
+ }
+
+ QDomDocument doc;
+ doc.setContent( &f );
+
+ mFolders.clear();
+
+ QDomNodeList nodes = doc.elementsByTagName( "D:prop" );
+ for( uint i = 0; i < nodes.count(); ++i ) {
+ QDomElement element = nodes.item(i).toElement();
+ QString id = "-1", parentId = "-1"; // OX default folder
+ bool def = false;
+ QString name, type;
+ QDomNode n;
+ for( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement e = n.toElement();
+ QString tag = e.tagName();
+ QString value = e.text();
+ if ( tag == "ox:object_id" ) id = value;
+ else if ( tag == "ox:folder_id" ) parentId = value;
+ else if ( tag == "ox:title" ) name = value;
+ else if ( tag == "ox:module" ) type = value;
+ else if ( tag == "ox:defaultfolder" ) def = (value == "true");
+ }
+ if ( id != "-1" && parentId != "-1" ) {
+ SloxFolder *folder = new SloxFolder( id, parentId, type, name, def );
+ mFolders[id] = folder;
+ kdDebug() << k_funcinfo << "Found folder: " << folder->name() << endl;
+ }
+ }
+
+ // add top-level system folders that are not contained in the folder listing
+ SloxFolder *folder = new SloxFolder( "1", "0", "unbound", i18n("Private Folder") );
+ mFolders[folder->id()] = folder;
+ folder = new SloxFolder( "2", "0", "unbound", i18n("Public Folder") );
+ mFolders[folder->id()] = folder;
+ folder = new SloxFolder( "3", "0", "unbound", i18n("Shared Folder") );
+ mFolders[folder->id()] = folder;
+ folder = new SloxFolder( "4", "0", "unbound", i18n("System Folder") );
+ mFolders[folder->id()] = folder;
+}
+
+
+#include "sloxfoldermanager.moc"
diff --git a/kresources/slox/sloxfoldermanager.h b/kresources/slox/sloxfoldermanager.h
new file mode 100644
index 000000000..3adac2061
--- /dev/null
+++ b/kresources/slox/sloxfoldermanager.h
@@ -0,0 +1,66 @@
+/*
+ Copyright (c) 2005 by Volker Krause <volker.krause@rwth-aachen.de>
+ Copyright (c) 2005 by Florian Schröder <florian@deltatauchi.de>
+
+ 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 SLOXFOLDERMANAGER_H
+#define SLOXFOLDERMANAGER_H
+
+#include <qmap.h>
+#include <qobject.h>
+
+#include <kurl.h>
+
+#include <kdepimmacros.h>
+
+namespace KIO {
+class Job;
+class DavJob;
+}
+
+class SloxBase;
+class SloxFolder;
+
+class KDE_EXPORT SloxFolderManager : public QObject
+{
+ Q_OBJECT
+ public:
+ SloxFolderManager( SloxBase *res, const KURL &baseUrl );
+ ~SloxFolderManager();
+
+ QMap<QString, SloxFolder*> folders() const { return mFolders; }
+ void requestFolders();
+
+ signals:
+ void foldersUpdated();
+
+ protected:
+ void readFolders();
+
+ QString cacheFile() const;
+
+ protected slots:
+ void slotResult( KIO::Job * );
+
+ private:
+ KIO::DavJob *mDownloadJob;
+ KURL mBaseUrl;
+ QMap<QString, SloxFolder*> mFolders;
+ SloxBase *mRes;
+};
+
+#endif
diff --git a/kresources/slox/testsloxaccounts.cpp b/kresources/slox/testsloxaccounts.cpp
new file mode 100644
index 000000000..c1cc75d3e
--- /dev/null
+++ b/kresources/slox/testsloxaccounts.cpp
@@ -0,0 +1,61 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 "sloxaccounts.h"
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kcmdlineargs.h>
+
+#include <qpushbutton.h>
+
+static const KCmdLineOptions options[] =
+{
+ {"verbose", "Verbose output", 0},
+ KCmdLineLastOption
+};
+
+int main(int argc,char **argv)
+{
+ KAboutData aboutData( "textsloxaccounts",
+ "SUSE LINUX Openexchange Server Configuration Wizard",
+ "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KApplication app;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ bool verbose = false;
+ if ( args->isSet( "verbose" ) ) verbose = true;
+
+ QPushButton button( "Close", 0 );
+
+ SloxAccounts::setServer( "f85.suse.de" );
+ SloxAccounts::self();
+
+ app.setMainWidget( &button );
+ button.show();
+ QObject::connect( &button, SIGNAL( clicked() ), &app, SLOT( quit() ) );
+
+ app.exec();
+}
diff --git a/kresources/slox/webdavhandler.cpp b/kresources/slox/webdavhandler.cpp
new file mode 100644
index 000000000..511373d51
--- /dev/null
+++ b/kresources/slox/webdavhandler.cpp
@@ -0,0 +1,295 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 "webdavhandler.h"
+#include "sloxbase.h"
+
+#ifdef HAVE_VALUES_H
+#include <values.h>
+#else
+#ifdef HAVE_SYS_LIMITS_H
+#include <sys/limits.h>
+#endif
+#endif
+
+#include <config.h>
+#include <stdlib.h>
+
+#include <libkcal/incidence.h>
+
+#include <libkdepim/kpimprefs.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+
+#include <qfile.h>
+
+SloxItem::SloxItem()
+ : status( Invalid )
+{
+}
+
+WebdavHandler::WebdavHandler()
+ : mLogCount( 0 )
+{
+ KConfig cfg( "sloxrc" );
+
+ cfg.setGroup( "General" );
+ mLogFile = cfg.readEntry( "LogFile" );
+
+ kdDebug() << "LOG FILE: " << mLogFile << endl;
+}
+
+void WebdavHandler::setUserId( const QString &id )
+{
+ mUserId = id;
+}
+
+QString WebdavHandler::userId() const
+{
+ return mUserId;
+}
+
+
+void WebdavHandler::log( const QString &text )
+{
+ if ( mLogFile.isEmpty() ) return;
+
+ QString filename = mLogFile + "-" + QString::number( mLogCount );
+ QFile file( filename );
+ if ( !file.open( IO_WriteOnly ) ) {
+ kdWarning() << "Unable to open log file '" << filename << "'" << endl;
+ return;
+ }
+
+ QCString textUtf8 = text.utf8();
+ file.writeBlock( textUtf8.data(), textUtf8.size() - 1 );
+
+ if ( ++mLogCount > 5 ) mLogCount = 0;
+}
+
+QValueList<SloxItem> WebdavHandler::getSloxItems( SloxBase *res, const QDomDocument &doc )
+{
+ kdDebug() << "getSloxItems" << endl;
+
+ QValueList<SloxItem> items;
+
+ QDomElement docElement = doc.documentElement();
+
+ QDomNode responseNode;
+ for( responseNode = docElement.firstChild(); !responseNode.isNull();
+ responseNode = responseNode.nextSibling() ) {
+ QDomElement responseElement = responseNode.toElement();
+ if ( responseElement.tagName() == "response" ) {
+ SloxItem item;
+
+ QDomNode propstat = responseElement.namedItem( "propstat" );
+ if ( propstat.isNull() ) {
+ kdError() << "Unable to find propstat tag." << endl;
+ continue;
+ }
+
+ QDomNode prop = propstat.namedItem( "prop" );
+ if ( prop.isNull() ) {
+ kdError() << "Unable to find WebDAV property" << endl;
+ continue;
+ }
+ item.domNode = prop;
+
+ QDomNode sloxIdNode = prop.namedItem( res->fieldName( SloxBase::ObjectId ) );
+ if ( sloxIdNode.isNull() ) {
+ kdError() << "Unable to find SLOX id." << endl;
+ continue;
+ }
+ QDomElement sloxIdElement = sloxIdNode.toElement();
+ item.sloxId = sloxIdElement.text();
+
+ QDomNode clientIdNode = prop.namedItem( res->fieldName( SloxBase::ClientId ) );
+ if ( !clientIdNode.isNull() ) {
+ QDomElement clientIdElement = clientIdNode.toElement();
+ item.clientId = clientIdElement.text();
+ if ( item.clientId != item.sloxId )
+ item.status = SloxItem::New;
+ }
+
+ QDomNode sloxStatus = prop.namedItem( res->fieldName( SloxBase::ObjectStatus ) );
+ if ( !sloxStatus.isNull() ) {
+ QDomElement sloxStatusElement = sloxStatus.toElement();
+ if ( sloxStatusElement.text() == "DELETE" ) {
+ item.status = SloxItem::Delete;
+ } else if ( sloxStatusElement.text() == "CREATE" ) {
+ item.status = SloxItem::Create;
+ }
+ }
+
+ QDomNode status = propstat.namedItem( "status" );
+ if ( status.isNull() ) {
+ kdError() << "Unable to find WebDAV status" << endl;
+ continue;
+ }
+ item.response = status.toElement().text();
+
+ QDomNode desc = propstat.namedItem( "responsedescription" );
+ if ( desc.isNull() ) {
+ kdError() << "Unable to find WebDAV responsedescription" << endl;
+ continue;
+ }
+ item.responseDescription = desc.toElement().text();
+
+ items.append( item );
+ }
+ }
+
+ return items;
+}
+
+QString WebdavHandler::qDateTimeToSlox( const QDateTime &dt )
+{
+ uint ticks = -dt.secsTo( QDateTime( QDate( 1970, 1, 1 ), QTime( 0, 0 ) ) );
+
+ return QString::number( ticks ) + "000";
+}
+
+QString WebdavHandler::qDateTimeToSlox( const QDateTime &dt,
+ const QString &timeZoneId )
+{
+ QDateTime utc = KPimPrefs::localTimeToUtc( dt, timeZoneId );
+
+ // secsTo and toTime_t etc also perform a timezone conversion using the system timezone,
+ // but we want to use the calendar timezone, so we have to convert ourself and spoof the tz to UTC before
+ // converting to ticks to prevent this
+ QCString origTz = getenv("TZ");
+ setenv( "TZ", "UTC", 1 );
+ uint ticks = utc.toTime_t();
+ if ( origTz.isNull() )
+ unsetenv( "TZ" );
+ else
+ setenv( "TZ", origTz, 1 );
+
+ return QString::number( ticks ) + "000";
+}
+
+QDateTime WebdavHandler::sloxToQDateTime( const QString &str )
+{
+ QString s = str.mid( 0, str.length() - 3 );
+
+ bool preEpoch = s.startsWith("-");
+ if (preEpoch)
+ s = s.mid(1);
+
+ unsigned long ticks = s.toULong();
+
+ QDateTime dt;
+
+ if (preEpoch) {
+ dt.setTime_t( 0, Qt::UTC );
+ if (ticks > INT_MAX) {
+ dt = dt.addSecs(-INT_MAX);
+ ticks -= INT_MAX;
+ }
+ dt = dt.addSecs(-((long) ticks));
+ }
+ else
+ {
+ dt.setTime_t( ticks, Qt::UTC );
+ }
+
+ return dt;
+}
+
+QDateTime WebdavHandler::sloxToQDateTime( const QString &str,
+ const QString &timeZoneId )
+{
+ return KPimPrefs::utcToLocalTime( sloxToQDateTime(str), timeZoneId );
+}
+
+QDomElement WebdavHandler::addElement( QDomDocument &doc, QDomNode &node,
+ const QString &tag )
+{
+ QDomElement el = doc.createElement( tag );
+ node.appendChild( el );
+ return el;
+}
+
+QDomElement WebdavHandler::addDavElement( QDomDocument &doc, QDomNode &node,
+ const QString &tag )
+{
+ QDomElement el = doc.createElementNS( "DAV:", "D:" + tag );
+ node.appendChild( el );
+ return el;
+}
+
+QDomElement WebdavHandler::addSloxElement( SloxBase *res,
+ QDomDocument &doc, QDomNode &node,
+ const QString &tag,
+ const QString &text )
+{
+ QDomElement el;
+ if ( res->resType() == "ox" )
+ el = doc.createElementNS( "http://www.open-xchange.org", "ox:" + tag );
+ else
+ el = doc.createElementNS( "SLOX", "S:" + tag );
+ if ( !text.isEmpty() ) {
+ QDomText textnode = doc.createTextNode( text );
+ el.appendChild( textnode );
+ }
+ node.appendChild( el );
+ return el;
+}
+
+void WebdavHandler::parseSloxAttribute( const QDomElement &e )
+{
+// kdDebug() << "parseSloxAttribute" << endl;
+
+ QString tag = e.tagName();
+ QString text = QString::fromUtf8( e.text().latin1() );
+ if ( text.isEmpty() ) return;
+
+ if ( tag == "owner" ) {
+ if ( text == mUserId ) mWritable = true;
+ } else if ( tag == "writerights" ) {
+ QDomNode n;
+ for( n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ QDomElement e2 = n.toElement();
+ if ( e2.tagName() == "member" ) {
+ if ( e2.text() == mUserId ) mWritable = true;
+ }
+ // TODO: Process group write rights
+ }
+ }
+}
+
+void WebdavHandler::clearSloxAttributeStatus()
+{
+ if ( mRes->resType() == "ox" )
+ mWritable = true; // parseSloxAttribute() won't work for OX
+ else
+ mWritable = false;
+}
+
+void WebdavHandler::setSloxAttributes( KCal::Incidence *i )
+{
+ i->setReadOnly( !mWritable );
+}
+
+void WebdavHandler::setSloxAttributes( KABC::Addressee & )
+{
+ // FIXME: libkabc doesn't allow to set an individual addressee to read-only
+}
diff --git a/kresources/slox/webdavhandler.h b/kresources/slox/webdavhandler.h
new file mode 100644
index 000000000..b41499a4a
--- /dev/null
+++ b/kresources/slox/webdavhandler.h
@@ -0,0 +1,96 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ 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 WEBDAVHANDLER_H
+#define WEBDAVHANDLER_H
+
+#include <qvaluelist.h>
+#include <qstring.h>
+#include <qdatetime.h>
+#include <qdom.h>
+
+#include <kdepimmacros.h>
+#include <kabc/addressee.h>
+
+namespace KCal {
+class Incidence;
+}
+
+class SloxBase;
+
+class KDE_EXPORT SloxItem
+{
+ public:
+ enum Status { Invalid, Delete, Create, New };
+
+ SloxItem();
+
+ QDomNode domNode;
+ QString sloxId;
+ QString clientId;
+ Status status;
+ QString response;
+ QString responseDescription;
+};
+
+class KDE_EXPORT WebdavHandler
+{
+ public:
+ WebdavHandler();
+
+ void setUserId( const QString & );
+ QString userId() const;
+ void setResource( SloxBase *res ) { mRes = res; }
+
+ void log( const QString & );
+
+ static QDomElement addElement( QDomDocument &, QDomNode &,
+ const QString &tag );
+ static QDomElement addDavElement( QDomDocument &, QDomNode &,
+ const QString &tag );
+ static QDomElement addSloxElement( SloxBase *res,
+ QDomDocument &, QDomNode &,
+ const QString &tag,
+ const QString &text = QString::null );
+
+ static QDateTime sloxToQDateTime( const QString &str );
+ static QDateTime sloxToQDateTime( const QString &str,
+ const QString &timeZoneId );
+ static QString qDateTimeToSlox( const QDateTime &dt );
+ static QString qDateTimeToSlox( const QDateTime &dt,
+ const QString &timeZoneId );
+
+ static QValueList<SloxItem> getSloxItems( SloxBase *res, const QDomDocument &doc );
+
+ void clearSloxAttributeStatus();
+ void parseSloxAttribute( const QDomElement & );
+ void setSloxAttributes( KCal::Incidence * );
+ void setSloxAttributes( KABC::Addressee & );
+
+ private:
+ QString mLogFile;
+ int mLogCount;
+ SloxBase *mRes;
+
+ QString mUserId;
+
+ bool mWritable;
+};
+
+#endif