summaryrefslogtreecommitdiffstats
path: root/tderesources/slox
diff options
context:
space:
mode:
Diffstat (limited to 'tderesources/slox')
-rw-r--r--tderesources/slox/CMakeLists.txt81
-rw-r--r--tderesources/slox/Makefile.am51
-rw-r--r--tderesources/slox/kabc_ox.desktop46
-rw-r--r--tderesources/slox/kabc_slox.desktop51
-rw-r--r--tderesources/slox/kabcresourceslox.cpp684
-rw-r--r--tderesources/slox/kabcresourceslox.h114
-rw-r--r--tderesources/slox/kabcresourceslox_plugin.cpp39
-rw-r--r--tderesources/slox/kabcresourcesloxconfig.cpp121
-rw-r--r--tderesources/slox/kabcresourcesloxconfig.h62
-rw-r--r--tderesources/slox/kabcsloxprefs.kcfgc11
-rw-r--r--tderesources/slox/kcal_ox.desktop46
-rw-r--r--tderesources/slox/kcal_slox.desktop51
-rw-r--r--tderesources/slox/kcalresourceslox.cpp1328
-rw-r--r--tderesources/slox/kcalresourceslox.h168
-rw-r--r--tderesources/slox/kcalresourceslox_plugin.cpp40
-rw-r--r--tderesources/slox/kcalresourcesloxconfig.cpp145
-rw-r--r--tderesources/slox/kcalresourcesloxconfig.h76
-rw-r--r--tderesources/slox/kcalsloxprefs.kcfgc11
-rw-r--r--tderesources/slox/sloxaccounts.cpp222
-rw-r--r--tderesources/slox/sloxaccounts.h67
-rw-r--r--tderesources/slox/sloxbase.cpp139
-rw-r--r--tderesources/slox/sloxbase.h115
-rw-r--r--tderesources/slox/sloxfolder.cpp49
-rw-r--r--tderesources/slox/sloxfolder.h55
-rw-r--r--tderesources/slox/sloxfolderdialog.cpp125
-rw-r--r--tderesources/slox/sloxfolderdialog.h56
-rw-r--r--tderesources/slox/sloxfoldermanager.cpp172
-rw-r--r--tderesources/slox/sloxfoldermanager.h67
-rw-r--r--tderesources/slox/tderesources_kabc_slox.kcfg31
-rw-r--r--tderesources/slox/tderesources_kcal_slox.kcfg38
-rw-r--r--tderesources/slox/testsloxaccounts.cpp61
-rw-r--r--tderesources/slox/webdavhandler.cpp295
-rw-r--r--tderesources/slox/webdavhandler.h96
33 files changed, 4713 insertions, 0 deletions
diff --git a/tderesources/slox/CMakeLists.txt b/tderesources/slox/CMakeLists.txt
new file mode 100644
index 000000000..51d974c49
--- /dev/null
+++ b/tderesources/slox/CMakeLists.txt
@@ -0,0 +1,81 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/libtdepim
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kcal_slox.desktop kcal_ox.desktop DESTINATION ${SERVICES_INSTALL_DIR}/tderesources/kcal )
+install( FILES kabc_slox.desktop kabc_ox.desktop DESTINATION ${SERVICES_INSTALL_DIR}/tderesources/kabc )
+
+
+##### kcal_slox (module) ########################
+
+tde_add_kpart( kcal_slox AUTOMOC
+ SOURCES kcalresourceslox_plugin.cpp
+ LINK kcal_slox-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
+
+
+##### kabc_slox (module) ########################
+
+tde_add_kpart( kabc_slox AUTOMOC
+ SOURCES kabcresourceslox_plugin.cpp
+ LINK kabc_slox-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
+
+
+##### kslox (shared) ############################
+
+tde_add_library( kslox SHARED AUTOMOC
+ SOURCES
+ sloxaccounts.cpp webdavhandler.cpp sloxfolder.cpp sloxfoldermanager.cpp
+ sloxfolderdialog.cpp sloxbase.cpp
+ VERSION 0.0.0
+ LINK tdepim-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+)
+
+
+##### kabc_slox (shared) ########################
+
+tde_add_library( kabc_slox SHARED AUTOMOC
+ SOURCES
+ kabcresourceslox.cpp kabcresourcesloxconfig.cpp kabcsloxprefs.kcfgc
+ VERSION 0.0.0
+ LINK kslox-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+)
+
+
+##### kcal_slox (shared) ########################
+
+tde_add_library( kcal_slox SHARED AUTOMOC
+ SOURCES
+ kcalresourceslox.cpp kcalresourcesloxconfig.cpp kcalsloxprefs.kcfgc
+ VERSION 0.0.0
+ LINK kslox-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+)
diff --git a/tderesources/slox/Makefile.am b/tderesources/slox/Makefile.am
new file mode 100644
index 000000000..7189d6338
--- /dev/null
+++ b/tderesources/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)/libtdepim/libtdepim.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) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor
+testsloxaccounts_LDADD = libkslox.la
+testsloxaccounts_SOURCES = testsloxaccounts.cpp
+
+
+kcal_servicedir = $(kde_servicesdir)/tderesources/kcal
+kcal_service_DATA = kcal_slox.desktop kcal_ox.desktop
+
+kabc_servicedir = $(kde_servicesdir)/tderesources/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/tderesources/slox/kabc_ox.desktop b/tderesources/slox/kabc_ox.desktop
new file mode 100644
index 000000000..39570ad29
--- /dev/null
+++ b/tderesources/slox/kabc_ox.desktop
@@ -0,0 +1,46 @@
+[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[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-TDE-Library=kabc_slox
+Type=Service
+ServiceTypes=KResources/Plugin
+X-TDE-ResourceFamily=contact
+X-TDE-ResourceType=ox
diff --git a/tderesources/slox/kabc_slox.desktop b/tderesources/slox/kabc_slox.desktop
new file mode 100644
index 000000000..6c7b0352c
--- /dev/null
+++ b/tderesources/slox/kabc_slox.desktop
@@ -0,0 +1,51 @@
+[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[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-TDE-Library=kabc_slox
+Type=Service
+ServiceTypes=KResources/Plugin
+X-TDE-ResourceFamily=contact
+X-TDE-ResourceType=slox
diff --git a/tderesources/slox/kabcresourceslox.cpp b/tderesources/slox/kabcresourceslox.cpp
new file mode 100644
index 000000000..e7ab6ecae
--- /dev/null
+++ b/tderesources/slox/kabcresourceslox.cpp
@@ -0,0 +1,684 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tqapplication.h>
+
+#include <kabc/picture.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmdcodec.h>
+#include <kstandarddirs.h>
+#include <kstringhandler.h>
+#include <libtdepim/kpimprefs.h>
+#include <libtdepim/progressmanager.h>
+#include <kio/davjob.h>
+
+#include "webdavhandler.h"
+#include "sloxaccounts.h"
+#include "kabcsloxprefs.h"
+
+#include "kabcresourceslox.h"
+
+using namespace KABC;
+
+ResourceSlox::ResourceSlox( const TDEConfig *config )
+ : ResourceCached( config ), SloxBase( this )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ if ( config ) {
+ readConfig( config );
+ } else {
+ setResourceName( i18n( "OpenXchange Server" ) );
+ }
+}
+
+ResourceSlox::ResourceSlox( const KURL &url,
+ const TQString &user, const TQString &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 TDEConfig * )
+{
+ mPrefs->readConfig();
+}
+
+void ResourceSlox::writeConfig( TDEConfig *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() );
+
+ TQString lastsync = "0";
+ if ( mPrefs->useLastSync() ) {
+ TQDateTime dt = mPrefs->lastSync();
+ if ( dt.isValid() )
+ lastsync = WebdavHandler::qDateTimeToSlox( dt.addDays( -1 ) );
+ }
+
+ TQDomDocument doc;
+ TQDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ TQDomElement 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 = TDEIO::davPropFind( url, doc, "0", false );
+ connect( mDownloadJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ TQT_SLOT( slotResult( TDEIO::Job * ) ) );
+ connect( mDownloadJob, TQT_SIGNAL( percent( TDEIO::Job *, unsigned long ) ),
+ TQT_SLOT( slotProgress( TDEIO::Job *, unsigned long ) ) );
+
+ mDownloadProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Downloading contacts") );
+ connect( mDownloadProgress,
+ TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ TQT_SLOT( cancelDownload() ) );
+
+ mPrefs->setLastSync( TQDateTime::currentDateTime() );
+
+ return true;
+}
+
+void ResourceSlox::slotResult( TDEIO::Job *job )
+{
+ kdDebug() << "ResourceSlox::slotResult()" << endl;
+
+ if ( job->error() ) {
+ job->showErrorDialog( 0 );
+ } else {
+ kdDebug() << "ResourceSlox::slotResult() success" << endl;
+
+ TQDomDocument doc = mDownloadJob->response();
+
+ mWebdavHandler.log( doc.toString( 2 ) );
+
+ TQValueList<SloxItem> items = WebdavHandler::getSloxItems( this, doc );
+
+ bool changed = false;
+
+ TQValueList<SloxItem>::ConstIterator it;
+ for( it = items.begin(); it != items.end(); ++it ) {
+ SloxItem item = *it;
+ TQString uid = "tderesources_slox_kabc_" + item.sloxId;
+ if ( item.status == SloxItem::Delete ) {
+ TQMap<TQString,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();
+
+ TQDomNode n;
+ for( n = item.domNode.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ TQDomElement 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( TDEIO::Job *job )
+{
+ kdDebug() << "ResourceSlox::slotUploadResult()" << endl;
+
+ if ( job->error() ) {
+ job->showErrorDialog( 0 );
+ } else {
+ kdDebug() << "ResourceSlox::slotUploadResult() success" << endl;
+
+ TQDomDocument doc = mUploadJob->response();
+ kdDebug() << k_funcinfo << "Upload result: " << endl;
+ kdDebug() << doc.toString() << endl;
+
+ TQValueList<SloxItem> items = WebdavHandler::getSloxItems( this, doc );
+
+ TQValueList<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 ) {
+ TQMap<TQString,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( "tderesources_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 TQDomElement &e, Addressee &a )
+{
+ TQString text = decodeText( e.text() );
+ if ( text.isEmpty() ) return;
+ TQString tag = e.tagName();
+ int pnType = 0;
+
+ if ( tag == fieldName( Birthday ) ) {
+ TQDateTime dt = WebdavHandler::sloxToTQDateTime( 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 ) ) {
+#if KDE_IS_VERSION(3,5,8)
+ a.setDepartment( text );
+#else
+ a.insertCustom( "KADDRESSBOOK", "X-Department", text );
+#endif
+ } 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 ) ) {
+ TQByteArray decodedPicture;
+ KCodecs::base64Decode( text.utf8(), decodedPicture );
+ a.setPhoto( Picture( TQImage( 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 ) ) {
+ TQDateTime dt = WebdavHandler::sloxToTQDateTime( text );
+ a.insertCustom( "KADDRESSBOOK", "X-Anniversary", dt.toString( Qt::ISODate ) );
+ } else if ( tag == fieldName( Categories ) ) {
+ a.setCategories( TQStringList::split( TQRegExp(",\\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 TQString &fieldName ) const
+{
+ TQMap<int, TQStringList> pnmap;
+ if ( type() == "ox" )
+ pnmap = mPhoneNumberOxMap;
+ else
+ pnmap = mPhoneNumberSloxMap;
+ TQMap<int, TQStringList>::ConstIterator it;
+ for ( it = pnmap.begin(); it != pnmap.end(); ++it ) {
+ TQStringList l = it.data();
+ TQStringList::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()
+{
+ TQDomDocument doc;
+ TQDomElement root = WebdavHandler::addDavElement( doc, doc, "propertyupdate" );
+ TQDomElement set = WebdavHandler::addDavElement( doc, root, "set" );
+ TQDomElement 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("tderesources_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 {
+ TQString tmp_uid = mUploadAddressee.uid().remove( 0, sizeof("tderesources_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 = TDEIO::davPropPatch( url, doc, false );
+ connect( mUploadJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ TQT_SLOT( slotUploadResult( TDEIO::Job * ) ) );
+ connect( mUploadJob, TQT_SIGNAL( percent( TDEIO::Job *, unsigned long ) ),
+ TQT_SLOT( slotProgress( TDEIO::Job *, unsigned long ) ) );
+
+ mUploadProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Uploading contacts") );
+ connect( mUploadProgress,
+ TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ TQT_SLOT( cancelUpload() ) );
+}
+
+void ResourceSlox::createAddresseeFields( TQDomDocument &doc, TQDomElement &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() );
+#if KDE_IS_VERSION(3,5,8)
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Department ),
+ a.department( ) );
+#else
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Department ),
+ a.custom( "KADDRESSBOOK", "X-Department" ) );
+#endif
+ 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" ) );
+ TQString anniversary = a.custom( "KADDRESSBOOK", "X-Anniversary" );
+ if ( !anniversary.isEmpty() )
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Anniversary ),
+ WebdavHandler::qDateTimeToSlox( TQDateTime::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
+ TQStringList email_list = a.emails();
+ TQStringList::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();
+ TQMap<int, TQStringList> 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() ) ) {
+ TQStringList l = pnSaveMap[(*it).type()];
+ TQString 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 ( TQMap<int, TQStringList>::ConstIterator it = pnSaveMap.begin(); it != pnSaveMap.end(); ++it ) {
+ TQStringList l = it.data();
+ for ( TQStringList::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( TQDomDocument &doc, TQDomElement &parent,
+ const TQString &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( TDEIO::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/tderesources/slox/kabcresourceslox.h b/tderesources/slox/kabcresourceslox.h
new file mode 100644
index 000000000..d5251bdc7
--- /dev/null
+++ b/tderesources/slox/kabcresourceslox.h
@@ -0,0 +1,114 @@
+/*
+ This file is part of tdepim.
+
+ 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 <libtdepim/kabcresourcecached.h>
+#include <tdepimmacros.h>
+#include <kabc/addressee.h>
+
+#include <tqmap.h>
+#include <tqdom.h>
+
+namespace TDEIO {
+class DavJob;
+class Job;
+}
+
+namespace KPIM {
+class ProgressItem;
+}
+
+class TDEConfig;
+
+namespace KABC {
+
+class SloxPrefs;
+
+class KDE_EXPORT ResourceSlox : public ResourceCached, public SloxBase
+{
+ Q_OBJECT
+
+ public:
+ ResourceSlox( const TDEConfig * );
+ ResourceSlox( const KURL &url,
+ const TQString &user, const TQString &password );
+ ~ResourceSlox();
+
+ void readConfig( const TDEConfig * );
+ void writeConfig( TDEConfig * );
+
+ 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 TQString &fieldName ) const;
+ void parseContactAttribute( const TQDomElement &e, Addressee &a );
+
+ void createAddresseeFields( TQDomDocument &doc, TQDomElement &prop, const Addressee &a );
+ void createAddressFields( TQDomDocument &doc, TQDomElement &parent,
+ const TQString &prefix, const KABC::Address &addr );
+
+ void uploadContacts();
+
+ protected slots:
+ void slotResult( TDEIO::Job *job );
+ void slotUploadResult( TDEIO::Job *job );
+ void slotProgress( TDEIO::Job *job, unsigned long percent );
+
+ void cancelDownload();
+ void cancelUpload();
+
+ private:
+ SloxPrefs *mPrefs;
+
+ TDEIO::DavJob *mDownloadJob;
+ TDEIO::DavJob *mUploadJob;
+ KPIM::ProgressItem *mDownloadProgress;
+ KPIM::ProgressItem *mUploadProgress;
+
+ WebdavHandler mWebdavHandler;
+
+ KABC::Addressee mUploadAddressee;
+
+ TQMap<int, TQStringList> mPhoneNumberSloxMap, mPhoneNumberOxMap;
+};
+
+}
+
+#endif
diff --git a/tderesources/slox/kabcresourceslox_plugin.cpp b/tderesources/slox/kabcresourceslox_plugin.cpp
new file mode 100644
index 000000000..cbc02f25e
--- /dev/null
+++ b/tderesources/slox/kabcresourceslox_plugin.cpp
@@ -0,0 +1,39 @@
+/*
+ This file is part of tdepim.
+
+ 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()
+ {
+ TDEGlobal::locale()->insertCatalogue( "libkcal" );
+ TDEGlobal::locale()->insertCatalogue( "kabc_slox" );
+ return new SloxFactory;
+ }
+}
diff --git a/tderesources/slox/kabcresourcesloxconfig.cpp b/tderesources/slox/kabcresourcesloxconfig.cpp
new file mode 100644
index 000000000..d9e32a556
--- /dev/null
+++ b/tderesources/slox/kabcresourcesloxconfig.cpp
@@ -0,0 +1,121 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tqcheckbox.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+
+using namespace KABC;
+
+ResourceSloxConfig::ResourceSloxConfig( TQWidget* parent, const char* name )
+ : KRES::ConfigWidget( parent, name ), mRes( 0 )
+{
+ TQGridLayout *mainLayout = new TQGridLayout( this, 5, 2, 0, KDialog::spacingHint() );
+
+ TQLabel *label = new TQLabel( i18n( "URL:" ), this );
+ mURL = new KURLRequester( this );
+
+ mainLayout->addWidget( label, 0, 0 );
+ mainLayout->addWidget( mURL, 0, 1 );
+
+ label = new TQLabel( i18n( "User:" ), this );
+ mUser = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mUser, 1, 1 );
+
+ label = new TQLabel( i18n( "Password:" ), this );
+ mPassword = new KLineEdit( this );
+ mPassword->setEchoMode( TQLineEdit::Password );
+
+ mainLayout->addWidget( label, 2, 0 );
+ mainLayout->addWidget( mPassword, 2, 1 );
+
+ mLastSyncCheck = new TQCheckBox( 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, TQT_SIGNAL( clicked() ), TQT_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() == TQDialog::Accepted )
+ mFolderId = dialog->selectedFolder();
+}
+
+#include "kabcresourcesloxconfig.moc"
diff --git a/tderesources/slox/kabcresourcesloxconfig.h b/tderesources/slox/kabcresourcesloxconfig.h
new file mode 100644
index 000000000..9cd54d831
--- /dev/null
+++ b/tderesources/slox/kabcresourcesloxconfig.h
@@ -0,0 +1,62 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tderesources/configwidget.h>
+#include <tdepimmacros.h>
+
+class TQCheckBox;
+class KLineEdit;
+class KURLRequester;
+class KPushButton;
+
+class SloxBase;
+
+namespace KABC {
+
+class KDE_EXPORT ResourceSloxConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+
+ public:
+ ResourceSloxConfig( TQWidget* 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;
+ TQCheckBox *mLastSyncCheck;
+ KPushButton *mFolderButton;
+ TQString mFolderId;
+ SloxBase *mRes;
+};
+
+}
+
+#endif
diff --git a/tderesources/slox/kabcsloxprefs.kcfgc b/tderesources/slox/kabcsloxprefs.kcfgc
new file mode 100644
index 000000000..11e2f2c21
--- /dev/null
+++ b/tderesources/slox/kabcsloxprefs.kcfgc
@@ -0,0 +1,11 @@
+# Code generation options for kconfig_compiler
+File=tderesources_kabc_slox.kcfg
+ClassName=SloxPrefs
+NameSpace=KABC
+Singleton=false
+Mutators=true
+Inherits=KResourcePrefs
+IncludeFiles=libtdepim/kresourceprefs.h
+GlobalEnums=true
+#ItemAccessors=true
+#SetUserTexts=true
diff --git a/tderesources/slox/kcal_ox.desktop b/tderesources/slox/kcal_ox.desktop
new file mode 100644
index 000000000..6d0e5ec66
--- /dev/null
+++ b/tderesources/slox/kcal_ox.desktop
@@ -0,0 +1,46 @@
+[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[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-TDE-Library=kcal_slox
+Type=Service
+ServiceTypes=KResources/Plugin
+X-TDE-ResourceFamily=calendar
+X-TDE-ResourceType=ox
diff --git a/tderesources/slox/kcal_slox.desktop b/tderesources/slox/kcal_slox.desktop
new file mode 100644
index 000000000..9b9198d73
--- /dev/null
+++ b/tderesources/slox/kcal_slox.desktop
@@ -0,0 +1,51 @@
+[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[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-TDE-Library=kcal_slox
+Type=Service
+ServiceTypes=KResources/Plugin
+X-TDE-ResourceFamily=calendar
+X-TDE-ResourceType=slox
diff --git a/tderesources/slox/kcalresourceslox.cpp b/tderesources/slox/kcalresourceslox.cpp
new file mode 100644
index 000000000..1311ebc52
--- /dev/null
+++ b/tderesources/slox/kcalresourceslox.cpp
@@ -0,0 +1,1328 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tqdatetime.h>
+#include <tqstring.h>
+#include <tqptrlist.h>
+#include <tqfile.h>
+#include <tqregexp.h>
+
+#include <kdebug.h>
+#include <kurl.h>
+#include <kio/job.h>
+#include <kio/davjob.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include <libtdepim/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 <tderesources/configwidget.h>
+
+#include "webdavhandler.h"
+#include "kcalsloxprefs.h"
+#include "sloxaccounts.h"
+
+#include "kcalresourceslox.h"
+
+using namespace KCal;
+
+KCalResourceSlox::KCalResourceSlox( const TDEConfig *config )
+ : ResourceCached( config ), SloxBase( this )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ if ( config ) {
+ readConfig( config );
+ } else {
+ setResourceName( i18n( "OpenXchange Server" ) );
+ }
+}
+
+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 TDEConfig *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( TDEConfig *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();
+
+ TQString p = KURL( mPrefs->url() ).protocol();
+ if ( p != "http" && p != "https" && p != "webdav" && p != "webdavs" ) {
+ TQString 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;
+
+ TQString lastsync = "0";
+ if ( mPrefs->useLastSync() ) {
+ TQDateTime dt = mPrefs->lastEventSync();
+ if ( dt.isValid() ) {
+ lastsync = WebdavHandler::qDateTimeToSlox( dt.addDays( -1 ) );
+ }
+ }
+
+ TQDomDocument doc;
+ TQDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ TQDomElement 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 = TDEIO::davPropFind( url, doc, "0", false );
+ connect( mLoadEventsJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ TQT_SLOT( slotLoadEventsResult( TDEIO::Job * ) ) );
+ connect( mLoadEventsJob, TQT_SIGNAL( percent( TDEIO::Job *, unsigned long ) ),
+ TQT_SLOT( slotEventsProgress( TDEIO::Job *, unsigned long ) ) );
+
+ mLoadEventsProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Downloading events") );
+ connect( mLoadEventsProgress,
+ TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ TQT_SLOT( cancelLoadEvents() ) );
+
+ mPrefs->setLastEventSync( TQDateTime::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;
+
+ TQString lastsync = "0";
+ if ( mPrefs->useLastSync() ) {
+ TQDateTime dt = mPrefs->lastTodoSync();
+ if ( dt.isValid() ) {
+ lastsync = WebdavHandler::qDateTimeToSlox( dt.addDays( -1 ) );
+ }
+ }
+
+ TQDomDocument doc;
+ TQDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ TQDomElement 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 = TDEIO::davPropFind( url, doc, "0", false );
+ connect( mLoadTodosJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ TQT_SLOT( slotLoadTodosResult( TDEIO::Job * ) ) );
+ connect( mLoadTodosJob, TQT_SIGNAL( percent( TDEIO::Job *, unsigned long ) ),
+ TQT_SLOT( slotTodosProgress( TDEIO::Job *, unsigned long ) ) );
+
+ mLoadTodosProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Downloading to-dos") );
+ connect( mLoadTodosProgress,
+ TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ TQT_SLOT( cancelLoadTodos() ) );
+
+ mPrefs->setLastTodoSync( TQDateTime::currentDateTime() );
+}
+
+void KCalResourceSlox::uploadIncidences()
+{
+ TQDomDocument doc;
+ TQDomElement ms = WebdavHandler::addDavElement( doc, doc, "multistatus" );
+ TQDomElement pu = WebdavHandler::addDavElement( doc, ms, "propertyupdate" );
+ TQDomElement set = WebdavHandler::addElement( doc, pu, "D:set" );
+ TQDomElement 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();
+
+ TQString 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 {
+ TQDomElement remove = WebdavHandler::addElement( doc, pu, "D:remove" );
+ TQDomElement 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 = TDEIO::davPropPatch( url, doc, false );
+ connect( mUploadJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ TQT_SLOT( slotUploadResult( TDEIO::Job * ) ) );
+ connect( mUploadJob, TQT_SIGNAL( percent( TDEIO::Job *, unsigned long ) ),
+ TQT_SLOT( slotUploadProgress( TDEIO::Job *, unsigned long ) ) );
+
+ mUploadProgress = KPIM::ProgressManager::instance()->createProgressItem(
+ KPIM::ProgressManager::getUniqueID(), i18n("Uploading incidence") );
+ connect( mUploadProgress,
+ TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem * ) ),
+ TQT_SLOT( cancelUpload() ) );
+}
+
+void KCalResourceSlox::createIncidenceAttributes( TQDomDocument &doc,
+ TQDomElement &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 ) {
+ TQDomElement 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 ) {
+ TQString userId = mAccounts->lookupId( (*it)->email() );
+ TQString status;
+ switch ( (*it)->status() ) {
+ case Attendee::Accepted: status = "accept"; break;
+ case Attendee::Declined: status = "decline"; break;
+ default: status = "none"; break;
+ }
+ TQDomElement 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" )
+ {
+ TQDomElement 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 ),
+ TQString::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( TQDomDocument &doc,
+ TQDomElement &parent,
+ Event *event )
+{
+ TQString 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( TQDomDocument &doc,
+ TQDomElement &parent,
+ Todo *todo )
+{
+ TQString 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();
+ TQString 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 ),
+ TQString::number( todo->percentComplete() ) );
+}
+
+void KCalResourceSlox::createRecurrenceAttributes( TQDomDocument &doc,
+ TQDomElement &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 ),
+ TQString::number( r->frequency() ) );
+ break;
+ case Recurrence::rWeekly: {
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "weekly" );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceWeeklyFreq ),
+ TQString::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", TQString::number( oxDays ) );
+ break; }
+ case Recurrence::rMonthlyDay:
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "monthly" );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthlyFreq ),
+ TQString::number( r->frequency() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthlyDay ),
+ TQString::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 ),
+ TQString::number( r->frequency() ) );
+ RecurrenceRule::WDayPos wdp = r->monthPositions().first();
+ // TODO: SLOX support
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthly2Day ),
+ TQString::number( 1 << wdp.day() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceMonthly2Pos ),
+ TQString::number( wdp.pos() ) );
+ break; }
+ case Recurrence::rYearlyMonth:
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceType ), "yearly" );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearlyDay ),
+ TQString::number( r->yearDates().first() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearlyMonth ),
+ TQString::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 ),
+ TQString::number( 1 << wdp.day() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearly2Pos ),
+ TQString::number( wdp.pos() ) );
+ WebdavHandler::addSloxElement( this, doc, parent, fieldName( RecurrenceYearly2Month ),
+ TQString::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();
+ TQStringList 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 TQDomElement &e,
+ Incidence *incidence )
+{
+ incidence->clearAttendees();
+
+ TQDomNode n;
+ for( n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ TQDomElement memberElement = n.toElement();
+ if ( memberElement.tagName() == fieldName( Participant ) ) {
+ TQString member = memberElement.text();
+ KABC::Addressee account;
+ if ( mAccounts ) account = mAccounts->lookupUser( member );
+ else kdError() << "KCalResourceSlox: no accounts set" << endl;
+ TQString name;
+ TQString 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 );
+ }
+ TQString 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 TQDomElement &e,
+ Incidence *incidence )
+{
+ TQDomNode n;
+ for( n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ TQDomElement rightElement = n.toElement();
+ if ( rightElement.tagName() == "group" ) {
+ TQString groupName = rightElement.text();
+ if ( groupName == "users" )
+ incidence->setSecrecy( Incidence::SecrecyPublic );
+ }
+ }
+}
+
+void KCalResourceSlox::parseIncidenceAttribute( const TQDomElement &e,
+ Incidence *incidence )
+{
+ TQString tag = e.tagName();
+ TQString 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( TQStringList::split( TQRegExp(",\\s*"), text ) );
+ }
+}
+
+void KCalResourceSlox::parseEventAttribute( const TQDomElement &e,
+ Event *event )
+{
+ TQString tag = e.tagName();
+ TQString text = decodeText( e.text() );
+ if ( text.isEmpty() ) return;
+
+ if ( tag == fieldName( EventBegin ) ) {
+ TQDateTime dt;
+ if ( event->doesFloat() ) {
+ if ( type() == "ox" )
+ dt = WebdavHandler::sloxToTQDateTime( text, timeZoneId() );
+ else
+ dt = WebdavHandler::sloxToTQDateTime( text ); // ### is this really correct for SLOX?
+ } else
+ dt = WebdavHandler::sloxToTQDateTime( text, timeZoneId() );
+ event->setDtStart( dt );
+ } else if ( tag == fieldName( EventEnd ) ) {
+ TQDateTime dt;
+ if ( event->doesFloat() ) {
+ dt = WebdavHandler::sloxToTQDateTime( text );
+ dt = dt.addSecs( -1 );
+ }
+ else dt = WebdavHandler::sloxToTQDateTime( text, timeZoneId() );
+ event->setDtEnd( dt );
+ } else if ( tag == fieldName( Location ) ) {
+ event->setLocation( text );
+ }
+}
+
+void KCalResourceSlox::parseRecurrence( const TQDomNode &node, Event *event )
+{
+ TQString type;
+
+ int dailyValue = -1;
+ TQDateTime end;
+
+ int weeklyValue = -1;
+ TQBitArray 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;
+
+ TQDomNode n;
+
+ for( n = node.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ TQDomElement e = n.toElement();
+ TQString tag = e.tagName();
+ TQString 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::sloxToTQDateTime( 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 ) ) {
+ TQStringList exdates = TQStringList::split( ",", text );
+ TQStringList::Iterator it;
+ for ( it = exdates.begin(); it != exdates.end(); ++it )
+ deleteExceptions.append( WebdavHandler::sloxToTQDateTime( *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 );
+ TQBitArray _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 );
+ TQBitArray _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 TQDomElement &e,
+ Todo *todo )
+{
+ TQString tag = e.tagName();
+ TQString text = decodeText( e.text() );
+ if ( text.isEmpty() ) return;
+
+ if ( tag == fieldName( TaskBegin ) ) {
+ TQDateTime dt = WebdavHandler::sloxToTQDateTime( text );
+ if ( dt.isValid() ) {
+ todo->setDtStart( dt );
+ todo->setHasStartDate( true );
+ }
+ } else if ( tag == fieldName( TaskEnd ) ) {
+ TQDateTime dt = WebdavHandler::sloxToTQDateTime( 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( TDEIO::Job *job )
+{
+ kdDebug() << "KCalResourceSlox::slotLoadTodosJobResult()" << endl;
+
+ if ( job->error() ) {
+ loadError( job->errorString() );
+ } else {
+ kdDebug() << "KCalResourceSlox::slotLoadTodosJobResult() success" << endl;
+
+ TQDomDocument doc = mLoadTodosJob->response();
+
+ mWebdavHandler.log( doc.toString( 2 ) );
+
+ TQValueList<SloxItem> items = WebdavHandler::getSloxItems( this, doc );
+
+ bool changed = false;
+
+ disableChangeNotification();
+
+ TQValueList<SloxItem>::ConstIterator it;
+ for( it = items.begin(); it != items.end(); ++it ) {
+ SloxItem item = *it;
+ TQString 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();
+
+ TQDomNode n;
+ for( n = item.domNode.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ TQDomElement 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( TDEIO::Job *job )
+{
+ kdDebug() << "KCalResourceSlox::slotLoadEventsResult() " << long( this ) << endl;
+
+ if ( job->error() ) {
+ loadError( job->errorString() );
+ } else {
+ kdDebug() << "KCalResourceSlox::slotLoadEventsResult() success" << endl;
+
+ TQDomDocument doc = mLoadEventsJob->response();
+
+ mWebdavHandler.log( doc.toString( 2 ) );
+
+ TQValueList<SloxItem> items = WebdavHandler::getSloxItems( this, doc );
+
+ bool changed = false;
+
+ disableChangeNotification();
+
+ TQValueList<SloxItem>::ConstIterator it;
+ for( it = items.begin(); it != items.end(); ++it ) {
+ SloxItem item = *it;
+ TQString 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 );
+
+ TQDomNode 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() ) {
+ TQDomElement 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( TDEIO::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;
+ }
+
+ TQDomDocument doc = mUploadJob->response();
+
+ kdDebug() << "UPLOAD RESULT:" << endl;
+ kdDebug() << doc.toString( 2 ) << endl;
+
+ TQDomElement docElement = doc.documentElement();
+
+ TQDomNode responseNode;
+ for( responseNode = docElement.firstChild(); !responseNode.isNull();
+ responseNode = responseNode.nextSibling() ) {
+ TQDomElement responseElement = responseNode.toElement();
+ if ( responseElement.tagName() == "response" ) {
+ TQDomNode propstat = responseElement.namedItem( "propstat" );
+ if ( propstat.isNull() ) {
+ kdError() << "Unable to find propstat tag." << endl;
+ continue;
+ }
+
+ TQDomNode status = propstat.namedItem( "status" );
+ if ( !status.isNull() ) {
+ TQDomElement statusElement = status.toElement();
+ TQString response = statusElement.text();
+ if ( !response.contains( "200" ) ) {
+ TQString error = "'" + mUploadedIncidence->summary() + "'\n";
+ error += response;
+ TQDomNode dn = propstat.namedItem( "responsedescription" );
+ TQString d = dn.toElement().text();
+ if ( !d.isEmpty() ) error += "\n" + d;
+ saveError( error );
+ continue;
+ }
+ }
+
+ TQDomNode prop = propstat.namedItem( "prop" );
+ if ( prop.isNull() ) {
+ kdError() << "Unable to find WebDAV property" << endl;
+ continue;
+ }
+
+ TQDomNode sloxIdNode = prop.namedItem( fieldName( ObjectId ) );
+ if ( sloxIdNode.isNull() ) {
+ kdError() << "Unable to find SLOX id." << endl;
+ continue;
+ }
+ TQDomElement sloxIdElement = sloxIdNode.toElement();
+ TQString sloxId = sloxIdElement.text();
+ kdDebug() << "SLOXID: " << sloxId << endl;
+
+ if ( mUploadIsDelete ) {
+ kdDebug() << "Incidence deleted" << endl;
+ } else {
+ TQDomNode clientIdNode = prop.namedItem( fieldName( ClientId ) );
+ if ( clientIdNode.isNull() ) {
+ kdError() << "Unable to find client id." << endl;
+ continue;
+ }
+ TQDomElement clientidElement = clientIdNode.toElement();
+ TQString clientId = clientidElement.text();
+
+ kdDebug() << "CLIENTID: " << clientId << endl;
+
+ Incidence *i = mUploadedIncidence->clone();
+ TQString 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( TDEIO::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( TDEIO::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( TDEIO::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 == TQDialog::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();
+}
+
+TQString KCalResourceSlox::sloxIdToEventUid( const TQString &sloxId )
+{
+ return "KResources_SLOX_Event_" + sloxId;
+}
+
+TQString KCalResourceSlox::sloxIdToTodoUid( const TQString &sloxId )
+{
+ return "KResources_SLOX_Todo_" + sloxId;
+}
+
+#include "kcalresourceslox.moc"
diff --git a/tderesources/slox/kcalresourceslox.h b/tderesources/slox/kcalresourceslox.h
new file mode 100644
index 000000000..6735b9934
--- /dev/null
+++ b/tderesources/slox/kcalresourceslox.h
@@ -0,0 +1,168 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tqptrlist.h>
+#include <tqstring.h>
+#include <tqdatetime.h>
+#include <tqdom.h>
+
+#include <kurl.h>
+#include <kconfig.h>
+#include <kdirwatch.h>
+#include <tdepimmacros.h>
+
+#include <libkcal/incidence.h>
+#include <libkcal/todo.h>
+#include <libkcal/calendarlocal.h>
+#include <libkcal/icalformat.h>
+#include <libkcal/resourcecached.h>
+
+namespace TDEIO {
+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 TDEConfig object.
+ */
+ KCalResourceSlox( const TDEConfig * );
+ KCalResourceSlox( const KURL &url );
+ ~KCalResourceSlox();
+
+ void readConfig( const TDEConfig *config );
+ void writeConfig( TDEConfig *config );
+
+ KCal::SloxPrefs *prefs() const { return mPrefs; }
+
+ KABC::Lock *lock();
+
+ bool isSaving();
+
+ void dump() const;
+
+ protected slots:
+ void slotLoadEventsResult( TDEIO::Job * );
+ void slotLoadTodosResult( TDEIO::Job * );
+ void slotUploadResult( TDEIO::Job * );
+
+ void slotEventsProgress( TDEIO::Job *job, unsigned long percent );
+ void slotTodosProgress( TDEIO::Job *job, unsigned long percent );
+ void slotUploadProgress( TDEIO::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 TQDomElement &e,
+ KCal::Incidence *incidence );
+ void parseReadRightsAttribute( const TQDomElement &e,
+ KCal::Incidence *incidence );
+ void parseIncidenceAttribute( const TQDomElement &e,
+ KCal::Incidence *incidence );
+ void parseTodoAttribute( const TQDomElement &e, KCal::Todo *todo );
+ void parseEventAttribute( const TQDomElement &e, KCal::Event *event );
+ void parseRecurrence( const TQDomNode &n, KCal::Event *event );
+
+ void createIncidenceAttributes( TQDomDocument &doc,
+ TQDomElement &parent,
+ KCal::Incidence *incidence );
+ void createEventAttributes( TQDomDocument &doc,
+ TQDomElement &parent,
+ KCal::Event *event );
+ void createTodoAttributes( TQDomDocument &doc,
+ TQDomElement &parent,
+ KCal::Todo *todo );
+ void createRecurrenceAttributes( TQDomDocument &doc,
+ TQDomElement &parent,
+ KCal::Incidence *incidence );
+
+ bool confirmSave();
+
+ TQString sloxIdToEventUid( const TQString &sloxId );
+ TQString sloxIdToTodoUid( const TQString &sloxId );
+
+ private:
+ void init();
+
+ KCal::SloxPrefs *mPrefs;
+
+ TDEIO::DavJob *mLoadEventsJob;
+ TDEIO::DavJob *mLoadTodosJob;
+ TDEIO::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/tderesources/slox/kcalresourceslox_plugin.cpp b/tderesources/slox/kcalresourceslox_plugin.cpp
new file mode 100644
index 000000000..8a5cf6906
--- /dev/null
+++ b/tderesources/slox/kcalresourceslox_plugin.cpp
@@ -0,0 +1,40 @@
+/*
+ This file is part of tdepim.
+
+ 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()
+ {
+ TDEGlobal::locale()->insertCatalogue( "libkcal" );
+ TDEGlobal::locale()->insertCatalogue( "kabc_slox" );
+ return new SLOXFactory;
+ }
+}
diff --git a/tderesources/slox/kcalresourcesloxconfig.cpp b/tderesources/slox/kcalresourcesloxconfig.cpp
new file mode 100644
index 000000000..e09cf85c1
--- /dev/null
+++ b/tderesources/slox/kcalresourcesloxconfig.cpp
@@ -0,0 +1,145 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tqlabel.h>
+#include <tqlayout.h>
+#include <tqcheckbox.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( TQWidget* parent, const char* name ) :
+ KRES::ConfigWidget( parent, name ), mRes( 0 )
+{
+ resize( 245, 115 );
+ TQGridLayout *mainLayout = new TQGridLayout( this, 6, 2, KDialog::spacingHint(), KDialog::spacingHint() );
+
+ TQLabel *label = new TQLabel( i18n( "Download from:" ), this );
+
+ mDownloadUrl = new KURLRequester( this );
+ mDownloadUrl->setMode( KFile::File );
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mDownloadUrl, 1, 1 );
+
+ label = new TQLabel( i18n("User:"), this );
+ mainLayout->addWidget( label, 2, 0 );
+
+ mUserEdit = new KLineEdit( this );
+ mainLayout->addWidget( mUserEdit, 2, 1 );
+
+ label = new TQLabel( i18n("Password:"), this );
+ mainLayout->addWidget( label, 3, 0 );
+
+ mPasswordEdit = new KLineEdit( this );
+ mainLayout->addWidget( mPasswordEdit, 3, 1 );
+ mPasswordEdit->setEchoMode( KLineEdit::Password );
+
+ mLastSyncCheck = new TQCheckBox( 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, TQT_SIGNAL( clicked() ), TQT_SLOT( selectCalendarFolder() ) );
+
+ mTaskButton = new KPushButton( i18n("Task Folder..."), this );
+ mainLayout->addWidget( mTaskButton, 5, 1 );
+ connect( mTaskButton, TQT_SIGNAL( clicked() ), TQT_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() == TQDialog::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() == TQDialog::Accepted )
+ mTaskFolderId = dialog->selectedFolder();
+}
+
+#include "kcalresourcesloxconfig.moc"
diff --git a/tderesources/slox/kcalresourcesloxconfig.h b/tderesources/slox/kcalresourcesloxconfig.h
new file mode 100644
index 000000000..e2a666c0b
--- /dev/null
+++ b/tderesources/slox/kcalresourcesloxconfig.h
@@ -0,0 +1,76 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tdepimmacros.h>
+
+#include <tderesources/resource.h>
+#include <tderesources/configwidget.h>
+
+class TQCheckBox;
+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( TQWidget *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;
+ TQCheckBox *mLastSyncCheck;
+ KPushButton *mCalButton;
+ KPushButton *mTaskButton;
+ TQString mCalendarFolderId;
+ TQString mTaskFolderId;
+
+ KCal::ResourceCachedReloadConfig *mReloadConfig;
+ KCal::ResourceCachedSaveConfig *mSaveConfig;
+
+ SloxBase *mRes;
+};
+
+#endif
diff --git a/tderesources/slox/kcalsloxprefs.kcfgc b/tderesources/slox/kcalsloxprefs.kcfgc
new file mode 100644
index 000000000..3b352a214
--- /dev/null
+++ b/tderesources/slox/kcalsloxprefs.kcfgc
@@ -0,0 +1,11 @@
+# Code generation options for kconfig_compiler
+File=tderesources_kcal_slox.kcfg
+ClassName=SloxPrefs
+NameSpace=KCal
+Singleton=false
+Mutators=true
+Inherits=KResourcePrefs
+IncludeFiles=libtdepim/kresourceprefs.h
+GlobalEnums=true
+#ItemAccessors=true
+#SetUserTexts=true
diff --git a/tderesources/slox/sloxaccounts.cpp b/tderesources/slox/sloxaccounts.cpp
new file mode 100644
index 000000000..aa648d1bc
--- /dev/null
+++ b/tderesources/slox/sloxaccounts.cpp
@@ -0,0 +1,222 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tqfile.h>
+#include <tqdom.h>
+#include <tqstring.h>
+
+SloxAccounts::SloxAccounts( SloxBase *res, const KURL &baseUrl )
+ : mBaseUrl( baseUrl ), mRes( res )
+{
+ kdDebug() << "SloxAccounts(): " << baseUrl << endl;
+
+ mDownloadJob = 0;
+
+ TQString server = mBaseUrl.host();
+
+ TQStringList l = TQStringList::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 TQString &id, const KABC::Addressee &a )
+{
+ kdDebug() << "SloxAccount::insertUser() " << id << endl;
+
+ mUsers.replace( id, a );
+
+ TQString email = a.preferredEmail();
+
+ TQString url = "http://" + mBaseUrl.host() + "/servlet/webdav.freebusy?username=";
+ url += id + "&server=" + mDomain;
+
+ KCal::FreeBusyUrlStore::self()->writeUrl( email, url );
+}
+
+KABC::Addressee SloxAccounts::lookupUser( const TQString &id )
+{
+ TQMap<TQString, KABC::Addressee>::ConstIterator it;
+ it = mUsers.find( id );
+ if ( it == mUsers.end() ) {
+ requestAccounts();
+ return KABC::Addressee();
+ } else {
+ return *it;
+ }
+}
+
+TQString SloxAccounts::lookupId( const TQString &email )
+{
+ kdDebug() << "SloxAccounts::lookupId() " << email << endl;
+
+ TQMap<TQString, 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 = TDEIO::file_copy( url, cacheFile(), -1, true, false, false );
+ } else if ( mRes->resType() == "ox" ) {
+ KURL url = mBaseUrl;
+ url.setPath( "/servlet/webdav.groupuser/" );
+
+ TQDomDocument doc;
+ TQDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ TQDomElement 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 = TDEIO::davPropFind( url, doc, "0", false );
+ }
+
+ connect( mDownloadJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ TQT_SLOT( slotResult( TDEIO::Job * ) ) );
+}
+
+void SloxAccounts::slotResult( TDEIO::Job *job )
+{
+ kdDebug() << "SloxAccounts::slotResult()" << endl;
+
+ if ( job->error() ) {
+ job->showErrorDialog( 0 );
+ } else {
+ if ( mRes->resType() == "ox" ) {
+ TQFile f( cacheFile() );
+ if ( !f.open( IO_WriteOnly ) ) {
+ kdWarning() << "Unable to open '" << cacheFile() << "'" << endl;
+ return;
+ }
+ TQTextStream stream ( &f );
+ stream << static_cast<TDEIO::DavJob*>( mDownloadJob )->response();
+ f.close();
+ }
+ readAccounts();
+ }
+
+ mDownloadJob = 0;
+}
+
+TQString SloxAccounts::cacheFile() const
+{
+ TQString host = mBaseUrl.host();
+
+ TQString file = locateLocal( "cache", "slox/accounts_" + host );
+
+ kdDebug() << "SloxAccounts::cacheFile(): " << file << endl;
+
+ return file;
+}
+
+void SloxAccounts::readAccounts()
+{
+ kdDebug() << "SloxAccounts::readAccounts()" << endl;
+
+ TQFile f( cacheFile() );
+ if ( !f.open( IO_ReadOnly ) ) {
+ kdDebug() << "Unable to open '" << cacheFile() << "'" << endl;
+ requestAccounts();
+ return;
+ }
+
+ TQDomDocument doc;
+ doc.setContent( &f );
+
+// kdDebug() << "SLOX ACCOUNTS: " << doc.toString( 2 ) << endl;
+
+ TQDomElement docElement = doc.documentElement();
+
+ mUsers.clear();
+
+ TQDomNodeList nodes = doc.elementsByTagName( mRes->resType() == "ox" ? "ox:user" : "user" );
+ for( uint i = 0; i < nodes.count(); ++i ) {
+ TQDomElement element = nodes.item(i).toElement();
+ TQString id;
+ KABC::Addressee a;
+ TQDomNode n;
+ for( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ TQDomElement e = n.toElement();
+ TQString tag = e.tagName();
+ // remove XML namespace
+ tag = tag.right( tag.length() - ( tag.find( ':' ) + 1 ) );
+ TQString 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/tderesources/slox/sloxaccounts.h b/tderesources/slox/sloxaccounts.h
new file mode 100644
index 000000000..214e3c707
--- /dev/null
+++ b/tderesources/slox/sloxaccounts.h
@@ -0,0 +1,67 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tdepimmacros.h>
+#include <tqobject.h>
+
+namespace TDEIO {
+class Job;
+}
+
+class SloxBase;
+
+class KDE_EXPORT SloxAccounts : public TQObject
+{
+ Q_OBJECT
+
+ public:
+ SloxAccounts( SloxBase *res, const KURL &baseUrl );
+ ~SloxAccounts();
+
+ void insertUser( const TQString &id, const KABC::Addressee &a );
+
+ KABC::Addressee lookupUser( const TQString &id );
+
+ TQString lookupId( const TQString &email );
+
+ protected:
+ void requestAccounts();
+ void readAccounts();
+
+ TQString cacheFile() const;
+
+ protected slots:
+ void slotResult( TDEIO::Job * );
+
+ private:
+ TQString mDomain;
+
+ TDEIO::Job *mDownloadJob;
+
+ TQMap<TQString, KABC::Addressee> mUsers; // map users ids to addressees.
+
+ KURL mBaseUrl;
+ SloxBase *mRes;
+};
+
+#endif
diff --git a/tderesources/slox/sloxbase.cpp b/tderesources/slox/sloxbase.cpp
new file mode 100644
index 000000000..a27652c9c
--- /dev/null
+++ b/tderesources/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 <tderesources/resource.h>
+
+static TQString 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 )
+{
+}
+
+TQString SloxBase::decodeText( const TQString & text )
+{
+ if ( mRes->type() == "ox" )
+ return text;
+ return TQString::fromUtf8( text.latin1() );
+}
+
+TQString SloxBase::fieldName( Field f )
+{
+ int t = 0;
+ if ( mRes->type() == "ox" )
+ t = 1;
+ return mFieldNameMap[f][t];
+}
+
+TQString SloxBase::resType( ) const
+{
+ return mRes->type();
+}
+
+TQString SloxBase::boolToStr( bool b )
+{
+ if ( mRes->type() == "ox" ) {
+ if ( b )
+ return "true";
+ return "false";
+ }
+ if ( b )
+ return "yes";
+ return "no";
+}
diff --git a/tderesources/slox/sloxbase.h b/tderesources/slox/sloxbase.h
new file mode 100644
index 000000000..8e9309c9d
--- /dev/null
+++ b/tderesources/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 <tqstring.h>
+#include <tdepimmacros.h>
+
+namespace KRES {
+class Resource;
+}
+
+class KDE_EXPORT SloxBase {
+ public:
+ enum Field {
+ ObjectId = 0, // system fields
+ ClientId,
+ FolderId,
+ LastSync,
+ ObjectType,
+ ObjecStatus,
+ 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 );
+
+ TQString decodeText( const TQString &text );
+ TQString fieldName( Field f );
+ TQString resType() const;
+ TQString boolToStr( bool b );
+
+ private:
+ KRES::Resource *mRes;
+};
+
+#endif
diff --git a/tderesources/slox/sloxfolder.cpp b/tderesources/slox/sloxfolder.cpp
new file mode 100644
index 000000000..fbfb9f051
--- /dev/null
+++ b/tderesources/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 TQString &id, const TQString &parentId, const TQString &type, const TQString &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;
+}
+
+TQString 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/tderesources/slox/sloxfolder.h b/tderesources/slox/sloxfolder.h
new file mode 100644
index 000000000..e722dfd4c
--- /dev/null
+++ b/tderesources/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 <tqstring.h>
+#include <tdepimmacros.h>
+
+class KListViewItem;
+
+enum FolderType {
+ Unbound,
+ Calendar,
+ Tasks,
+ Contacts
+};
+
+class KDE_EXPORT SloxFolder
+{
+ public:
+ SloxFolder( const TQString &id, const TQString &parentId, const TQString &type, const TQString &name, bool def = false );
+
+ TQString id() const { return mId; }
+ TQString parentId() const { return mParentId; }
+ FolderType type() const { return mType; }
+ TQString name() const;
+ bool isDefault() const { return mDefault; }
+
+ KListViewItem *item;
+
+ private:
+ TQString mId, mParentId;
+ FolderType mType;
+ TQString mName;
+ bool mDefault;
+};
+
+#endif
diff --git a/tderesources/slox/sloxfolderdialog.cpp b/tderesources/slox/sloxfolderdialog.cpp
new file mode 100644
index 000000000..4d21c2307
--- /dev/null
+++ b/tderesources/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, TQWidget *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, TQT_SIGNAL( foldersUpdated() ), TQT_SLOT( updateFolderView() ) );
+}
+
+SloxFolderDialog::~SloxFolderDialog()
+{
+ TQMap<TQString, SloxFolder*> folders = mManager->folders();
+ TQMap<TQString, SloxFolder*>::Iterator it;
+ for ( it = folders.begin(); it != folders.end(); ++it )
+ (*it)->item = 0;
+}
+
+void SloxFolderDialog::updateFolderView()
+{
+ TQString selected = selectedFolder();
+ mListView->clear();
+ TQMap<TQString, SloxFolder*> folders = mManager->folders();
+ TQMap<TQString, 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() );
+ TDEGlobal::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;
+ }
+}
+
+TQString SloxFolderDialog::selectedFolder() const
+{
+ TQListViewItem *item = mListView->selectedItem();
+ if ( item )
+ return item->text( 1 );
+ return "-1"; // OX default folder
+}
+
+void SloxFolderDialog::setSelectedFolder( const TQString &id )
+{
+ TQMap<TQString, SloxFolder*> folders = mManager->folders();
+ TQMap<TQString, 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/tderesources/slox/sloxfolderdialog.h b/tderesources/slox/sloxfolderdialog.h
new file mode 100644
index 000000000..69b8126bd
--- /dev/null
+++ b/tderesources/slox/sloxfolderdialog.h
@@ -0,0 +1,56 @@
+/*
+ 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 <tqstring.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, TQWidget* parent = 0, const char *name = 0 );
+ ~SloxFolderDialog();
+
+ TQString selectedFolder() const;
+ void setSelectedFolder( const TQString &id );
+
+ protected slots:
+ virtual void slotUser1();
+ void updateFolderView();
+
+ private:
+ void createFolderViewItem( SloxFolder *folder );
+
+ private:
+ KListView *mListView;
+ SloxFolderManager *mManager;
+ TQString mFolderId;
+ FolderType mFolderType;
+};
+
+#endif
diff --git a/tderesources/slox/sloxfoldermanager.cpp b/tderesources/slox/sloxfoldermanager.cpp
new file mode 100644
index 000000000..a60cd7885
--- /dev/null
+++ b/tderesources/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 <tqfile.h>
+#include <tqdom.h>
+#include <tqstring.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();
+ TQMap<TQString, 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" );
+
+ TQDomDocument doc;
+ TQDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" );
+ TQDomElement 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 = TDEIO::davPropFind( url, doc, "0", false );
+
+ connect( mDownloadJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ TQT_SLOT( slotResult( TDEIO::Job * ) ) );
+}
+
+void SloxFolderManager::slotResult( TDEIO::Job *job )
+{
+ kdDebug() << k_funcinfo << endl;
+
+ if ( job->error() ) {
+ job->showErrorDialog( 0 );
+ } else {
+ kdDebug() << k_funcinfo << " success, writing to " << cacheFile() << endl;
+ TQFile f( cacheFile() );
+ if ( !f.open( IO_WriteOnly ) ) {
+ kdDebug() << "Unable to open '" << cacheFile() << "'" << endl;
+ return;
+ }
+ TQTextStream stream ( &f );
+ stream << mDownloadJob->response();
+ f.close();
+ readFolders();
+ }
+
+ mDownloadJob = 0;
+ emit foldersUpdated();
+}
+
+TQString SloxFolderManager::cacheFile() const
+{
+ TQString host = mBaseUrl.host();
+
+ TQString file = locateLocal( "cache", "slox/folders_" + host );
+
+ kdDebug() << k_funcinfo << file << endl;
+
+ return file;
+}
+
+void SloxFolderManager::readFolders()
+{
+ kdDebug() << k_funcinfo << endl;
+
+ TQFile f( cacheFile() );
+ if ( !f.open( IO_ReadOnly ) ) {
+ kdDebug() << "Unable to open '" << cacheFile() << "'" << endl;
+ requestFolders();
+ return;
+ }
+
+ TQDomDocument doc;
+ doc.setContent( &f );
+
+ mFolders.clear();
+
+ TQDomNodeList nodes = doc.elementsByTagName( "D:prop" );
+ for( uint i = 0; i < nodes.count(); ++i ) {
+ TQDomElement element = nodes.item(i).toElement();
+ TQString id = "-1", parentId = "-1"; // OX default folder
+ bool def = false;
+ TQString name, type;
+ TQDomNode n;
+ for( n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ TQDomElement e = n.toElement();
+ TQString tag = e.tagName();
+ TQString 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/tderesources/slox/sloxfoldermanager.h b/tderesources/slox/sloxfoldermanager.h
new file mode 100644
index 000000000..f31c212c7
--- /dev/null
+++ b/tderesources/slox/sloxfoldermanager.h
@@ -0,0 +1,67 @@
+/*
+ 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 <tqmap.h>
+#include <tqobject.h>
+
+#include <kurl.h>
+
+#include <tdepimmacros.h>
+
+namespace TDEIO {
+class Job;
+class DavJob;
+}
+
+class SloxBase;
+class SloxFolder;
+
+class KDE_EXPORT SloxFolderManager : public TQObject
+{
+ Q_OBJECT
+
+ public:
+ SloxFolderManager( SloxBase *res, const KURL &baseUrl );
+ ~SloxFolderManager();
+
+ TQMap<TQString, SloxFolder*> folders() const { return mFolders; }
+ void requestFolders();
+
+ signals:
+ void foldersUpdated();
+
+ protected:
+ void readFolders();
+
+ TQString cacheFile() const;
+
+ protected slots:
+ void slotResult( TDEIO::Job * );
+
+ private:
+ TDEIO::DavJob *mDownloadJob;
+ KURL mBaseUrl;
+ TQMap<TQString, SloxFolder*> mFolders;
+ SloxBase *mRes;
+};
+
+#endif
diff --git a/tderesources/slox/tderesources_kabc_slox.kcfg b/tderesources/slox/tderesources_kabc_slox.kcfg
new file mode 100644
index 000000000..6e3057e64
--- /dev/null
+++ b/tderesources/slox/tderesources_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="tderesources_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/tderesources/slox/tderesources_kcal_slox.kcfg b/tderesources/slox/tderesources_kcal_slox.kcfg
new file mode 100644
index 000000000..9cf358044
--- /dev/null
+++ b/tderesources/slox/tderesources_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="tderesources_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/tderesources/slox/testsloxaccounts.cpp b/tderesources/slox/testsloxaccounts.cpp
new file mode 100644
index 000000000..e173134c5
--- /dev/null
+++ b/tderesources/slox/testsloxaccounts.cpp
@@ -0,0 +1,61 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tqpushbutton.h>
+
+static const KCmdLineOptions options[] =
+{
+ {"verbose", "Verbose output", 0},
+ KCmdLineLastOption
+};
+
+int main(int argc,char **argv)
+{
+ TDEAboutData aboutData( "textsloxaccounts",
+ "SUSE LINUX Openexchange Server Configuration Wizard",
+ "0.1" );
+ TDECmdLineArgs::init( argc, argv, &aboutData );
+ TDECmdLineArgs::addCmdLineOptions( options );
+
+ TDEApplication app;
+
+ TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
+
+ bool verbose = false;
+ if ( args->isSet( "verbose" ) ) verbose = true;
+
+ TQPushButton button( "Close", 0 );
+
+ SloxAccounts::setServer( "f85.suse.de" );
+ SloxAccounts::self();
+
+ app.setMainWidget( &button );
+ button.show();
+ TQObject::connect( &button, TQT_SIGNAL( clicked() ), &app, TQT_SLOT( quit() ) );
+
+ app.exec();
+}
diff --git a/tderesources/slox/webdavhandler.cpp b/tderesources/slox/webdavhandler.cpp
new file mode 100644
index 000000000..32d3c4167
--- /dev/null
+++ b/tderesources/slox/webdavhandler.cpp
@@ -0,0 +1,295 @@
+/*
+ This file is part of tdepim.
+
+ 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 <libtdepim/kpimprefs.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+
+#include <tqfile.h>
+
+SloxItem::SloxItem()
+ : status( Invalid )
+{
+}
+
+WebdavHandler::WebdavHandler()
+ : mLogCount( 0 )
+{
+ TDEConfig cfg( "sloxrc" );
+
+ cfg.setGroup( "General" );
+ mLogFile = cfg.readEntry( "LogFile" );
+
+ kdDebug() << "LOG FILE: " << mLogFile << endl;
+}
+
+void WebdavHandler::setUserId( const TQString &id )
+{
+ mUserId = id;
+}
+
+TQString WebdavHandler::userId() const
+{
+ return mUserId;
+}
+
+
+void WebdavHandler::log( const TQString &text )
+{
+ if ( mLogFile.isEmpty() ) return;
+
+ TQString filename = mLogFile + "-" + TQString::number( mLogCount );
+ TQFile file( filename );
+ if ( !file.open( IO_WriteOnly ) ) {
+ kdWarning() << "Unable to open log file '" << filename << "'" << endl;
+ return;
+ }
+
+ TQCString textUtf8 = text.utf8();
+ file.writeBlock( textUtf8.data(), textUtf8.size() - 1 );
+
+ if ( ++mLogCount > 5 ) mLogCount = 0;
+}
+
+TQValueList<SloxItem> WebdavHandler::getSloxItems( SloxBase *res, const TQDomDocument &doc )
+{
+ kdDebug() << "getSloxItems" << endl;
+
+ TQValueList<SloxItem> items;
+
+ TQDomElement docElement = doc.documentElement();
+
+ TQDomNode responseNode;
+ for( responseNode = docElement.firstChild(); !responseNode.isNull();
+ responseNode = responseNode.nextSibling() ) {
+ TQDomElement responseElement = responseNode.toElement();
+ if ( responseElement.tagName() == "response" ) {
+ SloxItem item;
+
+ TQDomNode propstat = responseElement.namedItem( "propstat" );
+ if ( propstat.isNull() ) {
+ kdError() << "Unable to find propstat tag." << endl;
+ continue;
+ }
+
+ TQDomNode prop = propstat.namedItem( "prop" );
+ if ( prop.isNull() ) {
+ kdError() << "Unable to find WebDAV property" << endl;
+ continue;
+ }
+ item.domNode = prop;
+
+ TQDomNode sloxIdNode = prop.namedItem( res->fieldName( SloxBase::ObjectId ) );
+ if ( sloxIdNode.isNull() ) {
+ kdError() << "Unable to find SLOX id." << endl;
+ continue;
+ }
+ TQDomElement sloxIdElement = sloxIdNode.toElement();
+ item.sloxId = sloxIdElement.text();
+
+ TQDomNode clientIdNode = prop.namedItem( res->fieldName( SloxBase::ClientId ) );
+ if ( !clientIdNode.isNull() ) {
+ TQDomElement clientIdElement = clientIdNode.toElement();
+ item.clientId = clientIdElement.text();
+ if ( item.clientId != item.sloxId )
+ item.status = SloxItem::New;
+ }
+
+ TQDomNode sloxStatus = prop.namedItem( res->fieldName( SloxBase::ObjecStatus ) );
+ if ( !sloxStatus.isNull() ) {
+ TQDomElement sloxStatusElement = sloxStatus.toElement();
+ if ( sloxStatusElement.text() == "DELETE" ) {
+ item.status = SloxItem::Delete;
+ } else if ( sloxStatusElement.text() == "CREATE" ) {
+ item.status = SloxItem::Create;
+ }
+ }
+
+ TQDomNode status = propstat.namedItem( "status" );
+ if ( status.isNull() ) {
+ kdError() << "Unable to find WebDAV status" << endl;
+ continue;
+ }
+ item.response = status.toElement().text();
+
+ TQDomNode 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;
+}
+
+TQString WebdavHandler::qDateTimeToSlox( const TQDateTime &dt )
+{
+ uint ticks = -dt.secsTo( TQDateTime( TQDate( 1970, 1, 1 ), TQTime( 0, 0 ) ) );
+
+ return TQString::number( ticks ) + "000";
+}
+
+TQString WebdavHandler::qDateTimeToSlox( const TQDateTime &dt,
+ const TQString &timeZoneId )
+{
+ TQDateTime 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
+ TQCString origTz = getenv("TZ");
+ setenv( "TZ", "UTC", 1 );
+ uint ticks = utc.toTime_t();
+ if ( origTz.isNull() )
+ unsetenv( "TZ" );
+ else
+ setenv( "TZ", origTz, 1 );
+
+ return TQString::number( ticks ) + "000";
+}
+
+TQDateTime WebdavHandler::sloxToTQDateTime( const TQString &str )
+{
+ TQString s = str.mid( 0, str.length() - 3 );
+
+ bool preEpoch = s.startsWith("-");
+ if (preEpoch)
+ s = s.mid(1);
+
+ unsigned long ticks = s.toULong();
+
+ TQDateTime 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;
+}
+
+TQDateTime WebdavHandler::sloxToTQDateTime( const TQString &str,
+ const TQString &timeZoneId )
+{
+ return KPimPrefs::utcToLocalTime( sloxToTQDateTime(str), timeZoneId );
+}
+
+TQDomElement WebdavHandler::addElement( TQDomDocument &doc, TQDomNode &node,
+ const TQString &tag )
+{
+ TQDomElement el = doc.createElement( tag );
+ node.appendChild( el );
+ return el;
+}
+
+TQDomElement WebdavHandler::addDavElement( TQDomDocument &doc, TQDomNode &node,
+ const TQString &tag )
+{
+ TQDomElement el = doc.createElementNS( "DAV:", "D:" + tag );
+ node.appendChild( el );
+ return el;
+}
+
+TQDomElement WebdavHandler::addSloxElement( SloxBase *res,
+ TQDomDocument &doc, TQDomNode &node,
+ const TQString &tag,
+ const TQString &text )
+{
+ TQDomElement 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() ) {
+ TQDomText textnode = doc.createTextNode( text );
+ el.appendChild( textnode );
+ }
+ node.appendChild( el );
+ return el;
+}
+
+void WebdavHandler::parseSloxAttribute( const TQDomElement &e )
+{
+// kdDebug() << "parseSloxAttribute" << endl;
+
+ TQString tag = e.tagName();
+ TQString text = TQString::fromUtf8( e.text().latin1() );
+ if ( text.isEmpty() ) return;
+
+ if ( tag == "owner" ) {
+ if ( text == mUserId ) mWritable = true;
+ } else if ( tag == "writerights" ) {
+ TQDomNode n;
+ for( n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ TQDomElement 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/tderesources/slox/webdavhandler.h b/tderesources/slox/webdavhandler.h
new file mode 100644
index 000000000..136be879e
--- /dev/null
+++ b/tderesources/slox/webdavhandler.h
@@ -0,0 +1,96 @@
+/*
+ This file is part of tdepim.
+
+ 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 <tqvaluelist.h>
+#include <tqstring.h>
+#include <tqdatetime.h>
+#include <tqdom.h>
+
+#include <tdepimmacros.h>
+#include <kabc/addressee.h>
+
+namespace KCal {
+class Incidence;
+}
+
+class SloxBase;
+
+class KDE_EXPORT SloxItem
+{
+ public:
+ enum Status { Invalid, Delete, Create, New };
+
+ SloxItem();
+
+ TQDomNode domNode;
+ TQString sloxId;
+ TQString clientId;
+ Status status;
+ TQString response;
+ TQString responseDescription;
+};
+
+class KDE_EXPORT WebdavHandler
+{
+ public:
+ WebdavHandler();
+
+ void setUserId( const TQString & );
+ TQString userId() const;
+ void setResource( SloxBase *res ) { mRes = res; }
+
+ void log( const TQString & );
+
+ static TQDomElement addElement( TQDomDocument &, TQDomNode &,
+ const TQString &tag );
+ static TQDomElement addDavElement( TQDomDocument &, TQDomNode &,
+ const TQString &tag );
+ static TQDomElement addSloxElement( SloxBase *res,
+ TQDomDocument &, TQDomNode &,
+ const TQString &tag,
+ const TQString &text = TQString() );
+
+ static TQDateTime sloxToTQDateTime( const TQString &str );
+ static TQDateTime sloxToTQDateTime( const TQString &str,
+ const TQString &timeZoneId );
+ static TQString qDateTimeToSlox( const TQDateTime &dt );
+ static TQString qDateTimeToSlox( const TQDateTime &dt,
+ const TQString &timeZoneId );
+
+ static TQValueList<SloxItem> getSloxItems( SloxBase *res, const TQDomDocument &doc );
+
+ void clearSloxAttributeStatus();
+ void parseSloxAttribute( const TQDomElement & );
+ void setSloxAttributes( KCal::Incidence * );
+ void setSloxAttributes( KABC::Addressee & );
+
+ private:
+ TQString mLogFile;
+ int mLogCount;
+ SloxBase *mRes;
+
+ TQString mUserId;
+
+ bool mWritable;
+};
+
+#endif