summaryrefslogtreecommitdiffstats
path: root/tderesources/egroupware
diff options
context:
space:
mode:
Diffstat (limited to 'tderesources/egroupware')
-rw-r--r--tderesources/egroupware/CMakeLists.txt109
-rw-r--r--tderesources/egroupware/Makefile.am73
-rw-r--r--tderesources/egroupware/access.h31
-rw-r--r--tderesources/egroupware/debugdialog.cpp126
-rw-r--r--tderesources/egroupware/debugdialog.h79
-rw-r--r--tderesources/egroupware/kabc_egroupwareprefs.kcfgc11
-rw-r--r--tderesources/egroupware/kabc_resourcexmlrpc.cpp774
-rw-r--r--tderesources/egroupware/kabc_resourcexmlrpc.h115
-rw-r--r--tderesources/egroupware/kabc_resourcexmlrpcconfig.cpp97
-rw-r--r--tderesources/egroupware/kabc_resourcexmlrpcconfig.h53
-rw-r--r--tderesources/egroupware/kabc_resourcexmlrpcplugin.cpp40
-rw-r--r--tderesources/egroupware/kabc_xmlrpc.desktop50
-rw-r--r--tderesources/egroupware/kcal_egroupwareprefs.kcfgc11
-rw-r--r--tderesources/egroupware/kcal_resourcexmlrpc.cpp1206
-rw-r--r--tderesources/egroupware/kcal_resourcexmlrpc.h237
-rw-r--r--tderesources/egroupware/kcal_resourcexmlrpcconfig.cpp98
-rw-r--r--tderesources/egroupware/kcal_resourcexmlrpcconfig.h54
-rw-r--r--tderesources/egroupware/kcal_resourcexmlrpcplugin.cpp40
-rw-r--r--tderesources/egroupware/kcal_xmlrpc.desktop50
-rw-r--r--tderesources/egroupware/knotes_egroupwareprefs.kcfgc11
-rw-r--r--tderesources/egroupware/knotes_resourcexmlrpc.cpp336
-rw-r--r--tderesources/egroupware/knotes_resourcexmlrpc.h104
-rw-r--r--tderesources/egroupware/knotes_resourcexmlrpcconfig.cpp98
-rw-r--r--tderesources/egroupware/knotes_resourcexmlrpcconfig.h54
-rw-r--r--tderesources/egroupware/knotes_resourcexmlrpcplugin.cpp40
-rw-r--r--tderesources/egroupware/knotes_xmlrpc.desktop50
-rw-r--r--tderesources/egroupware/synchronizer.cpp50
-rw-r--r--tderesources/egroupware/synchronizer.h72
-rw-r--r--tderesources/egroupware/tderesources_kabc_egroupware.kcfg24
-rw-r--r--tderesources/egroupware/tderesources_kcal_egroupware.kcfg24
-rw-r--r--tderesources/egroupware/tderesources_knotes_egroupware.kcfg24
-rw-r--r--tderesources/egroupware/todostatemapper.cpp167
-rw-r--r--tderesources/egroupware/todostatemapper.h75
-rw-r--r--tderesources/egroupware/xmlrpciface.cpp464
-rw-r--r--tderesources/egroupware/xmlrpciface.h167
35 files changed, 5014 insertions, 0 deletions
diff --git a/tderesources/egroupware/CMakeLists.txt b/tderesources/egroupware/CMakeLists.txt
new file mode 100644
index 000000000..ac6182f1f
--- /dev/null
+++ b/tderesources/egroupware/CMakeLists.txt
@@ -0,0 +1,109 @@
+#################################################
+#
+# (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}/kaddressbook/common
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/kaddressbook/common
+ ${CMAKE_SOURCE_DIR}/libtdepim
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### headers ###################################
+
+install( FILES
+ kabc_resourcexmlrpc.h kcal_resourcexmlrpc.h
+ DESTINATION ${INCLUDE_INSTALL_DIR}/kabc )
+
+
+##### other data ################################
+
+install( FILES kabc_xmlrpc.desktop DESTINATION ${SERVICES_INSTALL_DIR}/tderesources/kabc )
+install( FILES kcal_xmlrpc.desktop DESTINATION ${SERVICES_INSTALL_DIR}/tderesources/kcal )
+install( FILES knotes_xmlrpc.desktop DESTINATION ${SERVICES_INSTALL_DIR}/tderesources/knotes )
+
+
+##### egwcommon (static) ########################
+
+tde_add_library( egwcommon STATIC_PIC AUTOMOC
+ SOURCES
+ xmlrpciface.cpp synchronizer.cpp debugdialog.cpp
+)
+
+
+##### kabc_xmlrpc (shared) ######################
+
+tde_add_library( kabc_xmlrpc SHARED AUTOMOC
+ SOURCES
+ kabc_resourcexmlrpc.cpp kabc_resourcexmlrpcconfig.cpp
+ kabc_egroupwareprefs.kcfgc
+ VERSION 1.0.0
+ LINK egwcommon-static kabcommon-static tdepim-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+)
+
+
+##### kcal_xmlrpc (shared) ######################
+
+tde_add_library( kcal_xmlrpc SHARED AUTOMOC
+ SOURCES
+ kcal_resourcexmlrpc.cpp kcal_resourcexmlrpcconfig.cpp todostatemapper.cpp
+ kcal_egroupwareprefs.kcfgc
+ VERSION 1.0.0
+ LINK egwcommon-static tdepim-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+)
+
+
+##### knotes_xmlrpc (shared) ####################
+
+tde_add_library( knotes_xmlrpc SHARED AUTOMOC
+ SOURCES
+ knotes_resourcexmlrpc.cpp knotes_resourcexmlrpcconfig.cpp
+ knotes_egroupwareprefs.kcfgc
+ VERSION 1.0.0
+ LINK egwcommon-static knotes-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+)
+
+
+##### kabc_xmlrpc (module) ######################
+
+tde_add_kpart( kabc_xmlrpc AUTOMOC
+ SOURCES kabc_resourcexmlrpcplugin.cpp
+ LINK kabc_xmlrpc-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
+
+
+##### kcal_xmlrpc (module) ######################
+
+tde_add_kpart( kcal_xmlrpc AUTOMOC
+ SOURCES kcal_resourcexmlrpcplugin.cpp
+ LINK kcal_xmlrpc-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
+
+
+##### knotes_xmlrpc (module) ####################
+
+tde_add_kpart( knotes_xmlrpc AUTOMOC
+ SOURCES knotes_resourcexmlrpcplugin.cpp
+ LINK knotes_xmlrpc-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/tderesources/egroupware/Makefile.am b/tderesources/egroupware/Makefile.am
new file mode 100644
index 000000000..31a6702bf
--- /dev/null
+++ b/tderesources/egroupware/Makefile.am
@@ -0,0 +1,73 @@
+INCLUDES = -I$(top_srcdir)/libical/src/libical \
+ -I$(top_srcdir)/libical/src/libicalss \
+ -I$(top_builddir)/libical/src/libical \
+ -I$(top_builddir)/libical/src/libicalss \
+ -I$(srcdir)/versit -I$(top_srcdir)/ \
+ -I$(top_srcdir)/knotes \
+ -I$(top_builddir)/kaddressbook \
+ -I$(top_builddir)/kaddressbook/common \
+ -I$(top_srcdir)/kaddressbook/common \
+ -I$(top_builddir)/tderesources/egroupware \
+ $(all_includes)
+
+noinst_HEADERS = kabc_resourcexmlrpcconfig.h kcal_resourcexmlrpcconfig.h \
+ knotes_resourcexmlrpcconfig.h
+
+noinst_LTLIBRARIES = libegwcommon.la
+libegwcommon_la_SOURCES = xmlrpciface.cpp synchronizer.cpp debugdialog.cpp
+
+lib_LTLIBRARIES = libkabc_xmlrpc.la libkcal_xmlrpc.la libknotes_xmlrpc.la
+libkabc_xmlrpc_la_SOURCES = kabc_resourcexmlrpc.cpp kabc_resourcexmlrpcconfig.cpp \
+ kabc_egroupwareprefs.kcfgc
+libkabc_xmlrpc_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined
+libkabc_xmlrpc_la_LIBADD = $(LIB_KIO) -lkabc $(top_builddir)/libtdepim/libtdepim.la \
+ $(top_builddir)/kaddressbook/common/libkabcommon.la \
+ libegwcommon.la
+
+libkcal_xmlrpc_la_SOURCES = kcal_resourcexmlrpc.cpp kcal_resourcexmlrpcconfig.cpp \
+ todostatemapper.cpp kcal_egroupwareprefs.kcfgc
+libkcal_xmlrpc_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined
+libkcal_xmlrpc_la_LIBADD = $(top_builddir)/libkcal/libkcal.la \
+ $(top_builddir)/libtdepim/libtdepim.la \
+ libegwcommon.la
+
+libknotes_xmlrpc_la_SOURCES = knotes_resourcexmlrpc.cpp knotes_resourcexmlrpcconfig.cpp \
+ knotes_egroupwareprefs.kcfgc
+libknotes_xmlrpc_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined
+libknotes_xmlrpc_la_LIBADD = $(top_builddir)/libkcal/libkcal.la -ltdeprint \
+ $(top_builddir)/knotes/libknotesresources.la \
+ $(top_builddir)/libtdepim/libtdepim.la \
+ libegwcommon.la
+
+kabcincludedir = $(includedir)/kabc
+kabcinclude_HEADERS = kabc_resourcexmlrpc.h kcal_resourcexmlrpc.h
+
+kde_module_LTLIBRARIES = kabc_xmlrpc.la kcal_xmlrpc.la knotes_xmlrpc.la
+
+kabc_xmlrpc_la_SOURCES = kabc_resourcexmlrpcplugin.cpp
+kabc_xmlrpc_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kabc_xmlrpc_la_LIBADD = libkabc_xmlrpc.la
+
+kcal_xmlrpc_la_SOURCES = kcal_resourcexmlrpcplugin.cpp
+kcal_xmlrpc_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kcal_xmlrpc_la_LIBADD = libkcal_xmlrpc.la
+
+knotes_xmlrpc_la_SOURCES = knotes_resourcexmlrpcplugin.cpp
+knotes_xmlrpc_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+knotes_xmlrpc_la_LIBADD = libknotes_xmlrpc.la
+
+kabc_servicedir = $(kde_servicesdir)/tderesources/kabc
+kabc_service_DATA = kabc_xmlrpc.desktop
+
+kcal_servicedir = $(kde_servicesdir)/tderesources/kcal
+kcal_service_DATA = kcal_xmlrpc.desktop
+
+knotes_servicedir = $(kde_servicesdir)/tderesources/knotes
+knotes_service_DATA = knotes_xmlrpc.desktop
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kres_xmlrpc.pot
+
+kabc_resourcexmlrpc.lo: ../../kaddressbook/common/kabprefs_base.h
diff --git a/tderesources/egroupware/access.h b/tderesources/egroupware/access.h
new file mode 100644
index 000000000..aab787796
--- /dev/null
+++ b/tderesources/egroupware/access.h
@@ -0,0 +1,31 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ACCESS_H
+#define ACCESS_H
+
+#define EGW_ACCESS_READ 1
+#define EGW_ACCESS_ADD 2
+#define EGW_ACCESS_EDIT 4
+#define EGW_ACCESS_DELETE 8
+#define EGW_ACCESS_PRIVATE 9
+#define EGW_ACCESS_ALL 15
+
+#endif
diff --git a/tderesources/egroupware/debugdialog.cpp b/tderesources/egroupware/debugdialog.cpp
new file mode 100644
index 000000000..54fe07234
--- /dev/null
+++ b/tderesources/egroupware/debugdialog.cpp
@@ -0,0 +1,126 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <tqfile.h>
+#include <tqfiledialog.h>
+#include <tqlayout.h>
+
+#include <ktextbrowser.h>
+#include <kstaticdeleter.h>
+
+#include <stdlib.h>
+#include <klocale.h>
+#include "debugdialog.h"
+
+DebugDialog* DebugDialog::mSelf = 0;
+static KStaticDeleter<DebugDialog> debugDialogDeleter;
+
+DebugDialog::DebugDialog()
+ : KDialogBase( Plain, WStyle_DialogBorder | WStyle_StaysOnTop, 0,
+ "Debug Dialog", false, i18n("Debug Dialog"),
+ User1 | User2 | Ok, Ok, true )
+{
+ TQWidget *page = plainPage();
+ TQVBoxLayout *layout = new TQVBoxLayout( page, marginHint(), spacingHint() );
+
+ mView = new KTextBrowser( page );
+ layout->addWidget( mView );
+
+ setButtonText( User1, "Save As..." );
+ setButtonText( User2, "Clear" );
+
+ clear();
+}
+
+void DebugDialog::init()
+{
+ if ( !mSelf ) {
+ if ( getenv( "EGROUPWARE_DEBUG" ) != 0 ) {
+ debugDialogDeleter.setObject( mSelf, new DebugDialog );
+ }
+ }
+
+ if ( mSelf ) {
+ mSelf->show();
+ mSelf->raise();
+ }
+}
+
+DebugDialog::~DebugDialog()
+{
+ mSelf = 0;
+}
+
+void DebugDialog::addMessage( const TQString &msg, Type type )
+{
+ if ( mSelf )
+ mSelf->addText( msg, type );
+}
+
+void DebugDialog::clear()
+{
+ mView->clear();
+ mMessages.clear();
+}
+
+void DebugDialog::save()
+{
+ TQString fileName = TQFileDialog::getSaveFileName();
+ if ( fileName.isEmpty() )
+ return;
+
+ TQFile file( fileName );
+ if ( !file.open( IO_WriteOnly ) ) {
+ tqWarning( "Couldn't open file %s", file.name().latin1() );
+ return;
+ }
+
+ file.writeBlock( mMessages.join( "\n\n" ).utf8() );
+ file.close();
+}
+
+void DebugDialog::slotUser1()
+{
+ save();
+}
+
+void DebugDialog::slotUser2()
+{
+ clear();
+}
+
+void DebugDialog::addText( const TQString &text, Type type )
+{
+ TQString htmlCode( text );
+ htmlCode.replace( "<", "&lt;" );
+ htmlCode.replace( ">", "&gt;" );
+ htmlCode.replace( "\n", "<br>" );
+
+ mMessages.append( text );
+ if ( type == Input )
+ mHTMLMessages.append( "<font color=\"green\">" + htmlCode + "</font>" );
+ else
+ mHTMLMessages.append( "<font color=\"blue\">" + htmlCode + "</font>" );
+
+ mView->clear();
+ mView->setText( mHTMLMessages.join( "<br>" ) );
+}
+
+#include "debugdialog.moc"
diff --git a/tderesources/egroupware/debugdialog.h b/tderesources/egroupware/debugdialog.h
new file mode 100644
index 000000000..bde179885
--- /dev/null
+++ b/tderesources/egroupware/debugdialog.h
@@ -0,0 +1,79 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef DEBUGDIALOG_H
+#define DEBUGDIALOG_H
+
+#include <kdialogbase.h>
+
+class KTextBrowser;
+
+/**
+ A dialog that parses chunks of XML documents and
+ displays them in a treeview.
+ */
+class DebugDialog : public KDialogBase
+{
+ Q_OBJECT
+
+
+ public:
+ /**
+ The type of the message.
+ */
+ enum Type { Input, Output };
+
+ /**
+ Starts the debug dialog depending on the presence
+ of the environment variable EGROUPWARE_DEBUG.
+ */
+ static void init();
+
+ /**
+ Destructor.
+ */
+ ~DebugDialog();
+
+ /**
+ Adds a message, which will be shown by the dialog.
+ */
+ static void addMessage( const TQString &msg, Type type );
+
+ private slots:
+ void clear();
+ void save();
+
+ protected slots:
+ virtual void slotUser1();
+ virtual void slotUser2();
+
+ private:
+ DebugDialog();
+ static DebugDialog *mSelf;
+
+ void addText( const TQString&, Type );
+
+ TQStringList mMessages;
+ TQStringList mHTMLMessages;
+
+ KTextBrowser *mView;
+};
+
+#endif
diff --git a/tderesources/egroupware/kabc_egroupwareprefs.kcfgc b/tderesources/egroupware/kabc_egroupwareprefs.kcfgc
new file mode 100644
index 000000000..599001bbd
--- /dev/null
+++ b/tderesources/egroupware/kabc_egroupwareprefs.kcfgc
@@ -0,0 +1,11 @@
+# Code generation options for kconfig_compiler
+File=tderesources_kabc_egroupware.kcfg
+ClassName=EGroupwarePrefs
+NameSpace=KABC
+Singleton=false
+Mutators=true
+Inherits=KResourcePrefs
+IncludeFiles=libtdepim/kresourceprefs.h
+GlobalEnums=true
+#ItemAccessors=true
+#SetUserTexts=true
diff --git a/tderesources/egroupware/kabc_resourcexmlrpc.cpp b/tderesources/egroupware/kabc_resourcexmlrpc.cpp
new file mode 100644
index 000000000..84e783827
--- /dev/null
+++ b/tderesources/egroupware/kabc_resourcexmlrpc.cpp
@@ -0,0 +1,774 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <tqapplication.h>
+
+#include <kabc/addressee.h>
+#include <kabprefs.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmdcodec.h>
+#include <kstandarddirs.h>
+#include <kstringhandler.h>
+#include <libkcal/freebusyurlstore.h>
+#include <libtdepim/kpimprefs.h>
+
+#include "kabc_egroupwareprefs.h"
+#include "kabc_resourcexmlrpc.h"
+#include "kabc_resourcexmlrpcconfig.h"
+
+#include "access.h"
+#include "synchronizer.h"
+#include "xmlrpciface.h"
+
+using namespace KABC;
+
+static const TQString SearchContactsCommand = "addressbook.boaddressbook.search";
+static const TQString AddContactCommand = "addressbook.boaddressbook.write";
+static const TQString DeleteContactCommand = "addressbook.boaddressbook.delete";
+static const TQString LoadCategoriesCommand = "addressbook.boaddressbook.categories";
+static const TQString LoadCustomFieldsCommand = "addressbook.boaddressbook.customfields";
+
+static void setRights( KABC::Addressee &addr, int rights )
+{
+ addr.insertCustom( "EGWRESOURCE", "RIGHTS", TQString::number( rights ) );
+}
+
+static int rights( const KABC::Addressee &addr )
+{
+ return addr.custom( "EGWRESOURCE", "RIGHTS" ).toInt();
+}
+
+ResourceXMLRPC::ResourceXMLRPC( const TDEConfig *config )
+ : ResourceCached( config ), mServer( 0 )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ if ( config ) {
+ mPrefs->readConfig();
+ } else {
+ setResourceName( i18n( "eGroupware Server" ) );
+ }
+
+ initEGroupware();
+}
+
+ResourceXMLRPC::ResourceXMLRPC( const TQString &url, const TQString &domain,
+ const TQString &user, const TQString &password )
+ : ResourceCached( 0 ), mServer( 0 )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ mPrefs->setUrl( url );
+ mPrefs->setDomain( domain );
+ mPrefs->setUser( user );
+ mPrefs->setPassword( password );
+
+ initEGroupware();
+}
+
+void ResourceXMLRPC::init()
+{
+ setType( "xmlrpc" );
+
+ mSynchronizer = new Synchronizer;
+
+ mPrefs = new EGroupwarePrefs;
+}
+
+void ResourceXMLRPC::initEGroupware()
+{
+ KURL url( mPrefs->url() );
+
+ mAddrTypes.insert( "dom", Address::Dom );
+ mAddrTypes.insert( "intl", Address::Intl );
+ mAddrTypes.insert( "parcel", Address::Parcel );
+ mAddrTypes.insert( "postal", Address::Postal );
+}
+
+ResourceXMLRPC::~ResourceXMLRPC()
+{
+ saveCache();
+
+ delete mServer;
+ mServer = 0;
+
+ delete mPrefs;
+ mPrefs = 0;
+
+ delete mSynchronizer;
+ mSynchronizer = 0;
+}
+
+void ResourceXMLRPC::writeConfig( TDEConfig *config )
+{
+ Resource::writeConfig( config );
+
+ mPrefs->writeConfig();
+}
+
+Ticket *ResourceXMLRPC::requestSaveTicket()
+{
+ if ( !addressBook() ) {
+ kdDebug(5700) << "no addressbook" << endl;
+ return 0;
+ }
+
+ return createTicket( this );
+}
+
+void ResourceXMLRPC::releaseSaveTicket( Ticket *ticket )
+{
+ delete ticket;
+}
+
+bool ResourceXMLRPC::doOpen()
+{
+ if ( mServer )
+ delete mServer;
+
+ mServer = new KXMLRPC::Server( KURL(), this );
+ mServer->setUrl( KURL( mPrefs->url() ) );
+ mServer->setUserAgent( "KDE-AddressBook" );
+
+ TQMap<TQString, TQVariant> args;
+ args.insert( "domain", mPrefs->domain() );
+ args.insert( "username", mPrefs->user() );
+ args.insert( "password", mPrefs->password() );
+
+ mServer->call( "system.login", TQVariant( args ),
+ this, TQT_SLOT( loginFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mSynchronizer->start();
+
+ return true;
+}
+
+void ResourceXMLRPC::doClose()
+{
+ TQMap<TQString, TQVariant> args;
+ args.insert( "sessionid", mSessionID );
+ args.insert( "kp3", mKp3 );
+
+ mServer->call( "system.logout", TQVariant( args ),
+ this, TQT_SLOT( logoutFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mSynchronizer->start();
+}
+
+bool ResourceXMLRPC::load()
+{
+ mAddrMap.clear();
+
+ return true;
+}
+
+bool ResourceXMLRPC::asyncLoad()
+{
+ if ( !mServer )
+ return false;
+
+ mAddrMap.clear();
+
+ loadCache();
+
+ TQMap<TQString, TQVariant> args;
+ args.insert( "start", "0" );
+ args.insert( "query", "" );
+ args.insert( "filter", "" );
+ args.insert( "sort", "" );
+ args.insert( "order", "" );
+ args.insert( "include_users", "calendar" );
+
+ mServer->call( SearchContactsCommand, args,
+ this, TQT_SLOT( listContactsFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mServer->call( LoadCategoriesCommand, TQVariant( false, 0 ),
+ this, TQT_SLOT( loadCategoriesFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mServer->call( LoadCustomFieldsCommand, TQVariant( TQValueList<TQVariant>() ),
+ this, TQT_SLOT( loadCustomFieldsFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ return true;
+}
+
+
+bool ResourceXMLRPC::save( Ticket *ticket )
+{
+ return asyncSave( ticket );
+}
+
+bool ResourceXMLRPC::asyncSave( Ticket* )
+{
+ KABC::Addressee::List::ConstIterator it;
+
+ const KABC::Addressee::List addedList = addedAddressees();
+ for ( it = addedList.begin(); it != addedList.end(); ++it ) {
+ addContact( *it );
+ }
+
+ const KABC::Addressee::List changedList = changedAddressees();
+ for ( it = changedList.begin(); it != changedList.end(); ++it ) {
+ updateContact( *it );
+ }
+
+ const KABC::Addressee::List deletedList = deletedAddressees();
+ for ( it = deletedList.begin(); it != deletedList.end(); ++it ) {
+ deleteContact( *it );
+ }
+
+ return true;
+}
+
+void ResourceXMLRPC::addContact( const Addressee& addr )
+{
+ TQMap<TQString, TQVariant> args;
+ writeContact( addr, args );
+
+ mServer->call( AddContactCommand, args,
+ this, TQT_SLOT( addContactFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( addContactFault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( addr.uid() ) );
+}
+
+void ResourceXMLRPC::updateContact( const Addressee& addr )
+{
+ if ( !(rights( addr ) & EGW_ACCESS_DELETE) && (rights( addr ) != -1) ) {
+ clearChange( addr.uid() );
+ return;
+ }
+
+ TQMap<TQString, TQVariant> args;
+ writeContact( addr, args );
+
+ args.insert( "id", idMapper().remoteId( addr.uid() ) );
+ mServer->call( AddContactCommand, args,
+ this, TQT_SLOT( updateContactFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( updateContactFault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( addr.uid() ) );
+}
+
+void ResourceXMLRPC::deleteContact( const Addressee& addr )
+{
+ if ( !(rights( addr ) & EGW_ACCESS_DELETE) && rights( addr ) != -1 ) {
+ clearChange( addr.uid() );
+ idMapper().removeRemoteId( idMapper().remoteId( addr.uid() ) );
+ return;
+ }
+
+ mServer->call( DeleteContactCommand, idMapper().remoteId( addr.uid() ),
+ this, TQT_SLOT( deleteContactFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( deleteContactFault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( addr.uid() ) );
+}
+
+void ResourceXMLRPC::loginFinished( const TQValueList<TQVariant> &variant,
+ const TQVariant& )
+{
+ TQMap<TQString, TQVariant> map = variant[0].toMap();
+
+ KURL url( mPrefs->url() );
+ if ( map[ "GOAWAY" ].toString() == "XOXO" ) { // failed
+ mSessionID = mKp3 = "";
+ addressBook()->error( i18n( "Login failed, please check your username and password." ) );
+ } else {
+ mSessionID = map[ "sessionid" ].toString();
+ mKp3 = map[ "kp3" ].toString();
+ }
+
+ url.setUser( mSessionID );
+ url.setPass( mKp3 );
+ mServer->setUrl( url );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::logoutFinished( const TQValueList<TQVariant> &variant,
+ const TQVariant& )
+{
+ TQMap<TQString, TQVariant> map = variant[0].toMap();
+
+ if ( map[ "GOODBYE" ].toString() != "XOXO" )
+ addressBook()->error( i18n( "Logout failed, please check your username and password." ) );
+
+ KURL url( mPrefs->url() );
+ mSessionID = mKp3 = "";
+ url.setUser( mSessionID );
+ url.setPass( mKp3 );
+ mServer->setUrl( url );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::listContactsFinished( const TQValueList<TQVariant> &mapList,
+ const TQVariant& )
+{
+ const TQValueList<TQVariant> contactList = mapList[ 0 ].toList();
+ TQValueList<TQVariant>::ConstIterator contactIt;
+
+ KABC::Addressee::List serverContacts;
+ for ( contactIt = contactList.begin(); contactIt != contactList.end(); ++contactIt ) {
+ const TQMap<TQString, TQVariant> map = (*contactIt).toMap();
+
+ Addressee addr;
+ TQString uid;
+
+ readContact( map, addr, uid );
+
+ if ( !addr.isEmpty() ) {
+ addr.setResource( this );
+ addr.setChanged( false );
+
+ TQString local = idMapper().localId( uid );
+ if ( local.isEmpty() ) { // new entry
+ idMapper().setRemoteId( addr.uid(), uid );
+ } else {
+ addr.setUid( local );
+ }
+
+ mAddrMap.insert( addr.uid(), addr );
+ serverContacts.append( addr );
+ }
+ }
+
+ cleanUpCache( serverContacts );
+ saveCache();
+
+ emit loadingFinished( this );
+}
+
+void ResourceXMLRPC::addContactFinished( const TQValueList<TQVariant> &list,
+ const TQVariant &id )
+{
+ clearChange( id.toString() );
+ idMapper().setRemoteId( id.toString(), list[ 0 ].toString() );
+
+ saveCache();
+}
+
+void ResourceXMLRPC::updateContactFinished( const TQValueList<TQVariant>&,
+ const TQVariant &id )
+{
+ clearChange( id.toString() );
+
+ saveCache();
+}
+
+void ResourceXMLRPC::deleteContactFinished( const TQValueList<TQVariant>&,
+ const TQVariant &id )
+{
+ clearChange( id.toString() );
+ idMapper().removeRemoteId( idMapper().remoteId( id.toString() ) );
+
+ saveCache();
+}
+
+void ResourceXMLRPC::fault( int error, const TQString &errorMsg,
+ const TQVariant& )
+{
+ TQString msg = i18n( "<qt>Server sent error %1: <b>%2</b></qt>" ).arg( error ).arg( errorMsg );
+ if ( addressBook() )
+ addressBook()->error( msg );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::addContactFault( int, const TQString &errorMsg,
+ const TQVariant &id )
+{
+ KABC::Addressee addr = mAddrMap[ id.toString() ];
+
+ mAddrMap.remove( addr.uid() );
+
+ TQString msg = i18n( "Unable to add contact %1 to server. (%2)" );
+ addressBook()->error( msg.arg( addr.formattedName(), errorMsg ) );
+}
+
+void ResourceXMLRPC::updateContactFault( int, const TQString &errorMsg,
+ const TQVariant &id )
+{
+ KABC::Addressee addr = mAddrMap[ id.toString() ];
+
+ TQString msg = i18n( "Unable to update contact %1 on server. (%2)" );
+ addressBook()->error( msg.arg( addr.formattedName(), errorMsg ) );
+}
+
+void ResourceXMLRPC::deleteContactFault( int, const TQString &errorMsg,
+ const TQVariant &id )
+{
+ KABC::Addressee addr;
+
+ const KABC::Addressee::List deletedList = deletedAddressees();
+ KABC::Addressee::List::ConstIterator it;
+ for ( it = deletedList.begin(); it != deletedList.end(); ++it ) {
+ if ( (*it).uid() == id.toString() ) {
+ addr = *it;
+ break;
+ }
+ }
+
+ mAddrMap.insert( addr.uid(), addr );
+
+ TQString msg = i18n( "Unable to delete contact %1 from server. (%2)" );
+ addressBook()->error( msg.arg( addr.formattedName(), errorMsg ) );
+}
+
+TQString ResourceXMLRPC::addrTypesToTypeStr( int typeMask )
+{
+ TQStringList types;
+ TQMap<TQString, int>::ConstIterator it;
+ for ( it = mAddrTypes.begin(); it != mAddrTypes.end(); ++it )
+ if ( it.data() & typeMask )
+ types.append( it.key() );
+
+ return types.join( ";" );
+}
+
+void ResourceXMLRPC::writeContact( const Addressee &addr, TQMap<TQString, TQVariant> &args )
+{
+ args.insert( "access", ( addr.secrecy().type() == Secrecy::Private ? "private" : "public" ) );
+ args.insert( "fn", addr.formattedName() );
+ args.insert( "n_given", addr.givenName() );
+ args.insert( "n_family", addr.familyName() );
+ args.insert( "n_middle", addr.additionalName() );
+ args.insert( "n_prefix", addr.prefix() );
+ args.insert( "n_suffix", addr.suffix() );
+// args.insert( "sound", "sound" );
+ args.insert( "bday", addr.birthday() );
+ args.insert( "note", addr.note() );
+ int hours = addr.timeZone().offset() / 60;
+ args.insert( "tz", hours );
+// args.insert( "geo", "geo" );
+ args.insert( "url", addr.url().url() );
+// args.insert( "pubkey", "pubkey" );
+ args.insert( "org_name", addr.organization() );
+// args.insert( "org_unit", "org_unit" );
+ args.insert( "title", addr.title() );
+
+ // CATEGORIES
+ TQStringList::ConstIterator catIt;
+ const TQStringList categories = addr.categories();
+
+ TQMap<TQString, TQVariant> catMap;
+ int counter = 0;
+ for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
+ TQMap<TQString, int>::ConstIterator it = mCategoryMap.find( *catIt );
+ if ( it == mCategoryMap.end() ) // new category
+ catMap.insert( TQString::number( counter-- ), *catIt );
+ else
+ catMap.insert( TQString::number( it.data() ), *catIt );
+ }
+ args.insert( "cat_id", catMap );
+
+ Address workAddr = addr.address( Address::Work );
+ if ( !workAddr.isEmpty() ) {
+ args.insert( "adr_one_street", workAddr.street() );
+ args.insert( "adr_one_locality", workAddr.locality() );
+ args.insert( "adr_one_region", workAddr.region() );
+ args.insert( "adr_one_postalcode", workAddr.postalCode() );
+ args.insert( "adr_one_countryname", workAddr.country() );
+
+ args.insert( "adr_one_type", addrTypesToTypeStr( workAddr.type() ) );
+ args.insert( "label", workAddr.label() );
+ }
+
+ Address homeAddr = addr.address( Address::Home );
+ if ( !homeAddr.isEmpty() ) {
+ args.insert( "adr_two_street", homeAddr.street() );
+ args.insert( "adr_two_locality", homeAddr.locality() );
+ args.insert( "adr_two_region", homeAddr.region() );
+ args.insert( "adr_two_postalcode", homeAddr.postalCode() );
+ args.insert( "adr_two_countryname", homeAddr.country() );
+ args.insert( "adr_two_type", addrTypesToTypeStr( homeAddr.type() ) );
+ }
+
+ PhoneNumber phone = addr.phoneNumber( PhoneNumber::Work );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_work", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Home );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_home", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Voice );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_voice", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Fax );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_fax", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Msg );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_msg", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Cell );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_cell", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Pager );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_pager", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Bbs );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_bbs", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Modem );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_modem", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Car );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_car", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Isdn );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_isdn", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Video );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_video", phone.number() );
+
+ phone = addr.phoneNumber( PhoneNumber::Pref );
+ if ( !phone.number().isEmpty() )
+ args.insert( "tel_prefer", phone.number() );
+
+ if ( !addr.preferredEmail().isEmpty() ) {
+ args.insert( "email", addr.preferredEmail() );
+ args.insert( "email_type", "INTERNET" );
+ }
+
+ if ( addr.emails().count() > 1 ) {
+ args.insert( "email_home", addr.emails()[ 1 ] );
+ args.insert( "email_home_type", "INTERNET" );
+ }
+
+
+ const TQStringList customFields = addr.customs();
+ TQStringList::ConstIterator it;
+ for ( it = customFields.begin(); it != customFields.end(); ++it ) {
+ int colon = (*it).find( ":" );
+ TQString identifier = (*it).left( colon );
+ int dash = identifier.find( "-" );
+ TQString app = identifier.left( dash );
+ TQString name = identifier.mid( dash + 1 );
+ TQString value = (*it).mid( colon + 1 );
+ if ( value.isEmpty() )
+ continue;
+
+ if ( app == "XMLRPCResource" )
+ args.insert( name, value );
+ }
+
+ TQString url = KCal::FreeBusyUrlStore::self()->readUrl( addr.preferredEmail() );
+ if ( !url.isEmpty() )
+ args.insert( "freebusy_url", url );
+}
+
+void ResourceXMLRPC::readContact( const TQMap<TQString, TQVariant> &args, Addressee &addr, TQString &uid )
+{
+ Address addrOne, addrTwo;
+
+ TQMap<TQString, TQVariant>::ConstIterator it;
+ for ( it = args.begin(); it != args.end(); ++it ) {
+ if ( it.key() == "id" ) {
+ uid = it.data().toString();
+ } else if ( it.key() == "access" ) {
+ Secrecy secrecy;
+ if ( it.data().toString() == "private" )
+ secrecy.setType( Secrecy::Private );
+ else
+ secrecy.setType( Secrecy::Public );
+
+ addr.setSecrecy( secrecy );
+ } else if ( it.key() == "fn" ) {
+ addr.setFormattedName( it.data().toString() );
+ } else if ( it.key() == "n_given" ) {
+ addr.setGivenName( it.data().toString() );
+ } else if ( it.key() == "n_family" ) {
+ addr.setFamilyName( it.data().toString() );
+ } else if ( it.key() == "n_middle" ) {
+ addr.setAdditionalName( it.data().toString() );
+ } else if ( it.key() == "n_prefix" ) {
+ addr.setPrefix( it.data().toString() );
+ } else if ( it.key() == "n_suffix" ) {
+ addr.setSuffix( it.data().toString() );
+ } else if ( it.key() == "sound" ) {
+ } else if ( it.key() == "bday" ) {
+ addr.setBirthday( it.data().toDateTime() );
+ } else if ( it.key() == "note" ) {
+ addr.setNote( it.data().toString() );
+ } else if ( it.key() == "tz" ) {
+ int hour = it.data().toInt();
+ TimeZone timeZone( hour * 60 );
+ addr.setTimeZone( timeZone );
+ } else if ( it.key() == "geo" ) {
+ } else if ( it.key() == "url" ) {
+ addr.setUrl( KURL( it.data().toString() ) );
+ } else if ( it.key() == "pubkey" ) {
+ } else if ( it.key() == "org_name" ) {
+ addr.setOrganization( it.data().toString() );
+ } else if ( it.key() == "org_unit" ) {
+ } else if ( it.key() == "title" ) {
+ addr.setTitle( it.data().toString() );
+ } else if ( it.key() == "adr_one_street" ) {
+ addrOne.setStreet( it.data().toString() );
+ } else if ( it.key() == "adr_one_locality" ) {
+ addrOne.setLocality( it.data().toString() );
+ } else if ( it.key() == "adr_one_region" ) {
+ addrOne.setRegion( it.data().toString() );
+ } else if ( it.key() == "adr_one_postalcode" ) {
+ addrOne.setPostalCode( it.data().toString() );
+ } else if ( it.key() == "adr_one_countryname" ) {
+ addrOne.setCountry( it.data().toString() );
+ } else if ( it.key() == "adr_one_type" ) {
+ TQStringList types = TQStringList::split( ';', it.data().toString() );
+
+ int type = Address::Work;
+ for ( uint i = 0; i < types.count(); ++i )
+ type += mAddrTypes[ types[ i ] ];
+
+ addrOne.setType( type );
+ } else if ( it.key() == "label" ) {
+ addrOne.setLabel( it.data().toString() );
+ } else if ( it.key() == "adr_two_street" ) {
+ addrTwo.setStreet( it.data().toString() );
+ } else if ( it.key() == "adr_two_locality" ) {
+ addrTwo.setLocality( it.data().toString() );
+ } else if ( it.key() == "adr_two_region" ) {
+ addrTwo.setRegion( it.data().toString() );
+ } else if ( it.key() == "adr_two_postalcode" ) {
+ addrTwo.setPostalCode( it.data().toString() );
+ } else if ( it.key() == "adr_two_countryname" ) {
+ addrTwo.setCountry( it.data().toString() );
+ } else if ( it.key() == "adr_two_type" ) {
+ TQStringList types = TQStringList::split( ';', it.data().toString() );
+
+ int type = Address::Home;
+ for ( uint i = 0; i < types.count(); ++i )
+ type += mAddrTypes[ types[ i ] ];
+
+ addrTwo.setType( type );
+ } else if ( it.key() == "tel_work" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Work ) );
+ } else if ( it.key() == "tel_home" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Home ) );
+ } else if ( it.key() == "tel_voice" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Voice ) );
+ } else if ( it.key() == "tel_fax" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Fax ) );
+ } else if ( it.key() == "tel_msg" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Msg ) );
+ } else if ( it.key() == "tel_cell" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Cell ) );
+ } else if ( it.key() == "tel_pager" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Pager ) );
+ } else if ( it.key() == "tel_bbs" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Bbs ) );
+ } else if ( it.key() == "tel_modem" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Modem ) );
+ } else if ( it.key() == "tel_car" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Car ) );
+ } else if ( it.key() == "tel_isdn" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Isdn ) );
+ } else if ( it.key() == "tel_video" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Video ) );
+ } else if ( it.key() == "tel_prefer" ) {
+ addr.insertPhoneNumber( PhoneNumber( it.data().toString(), PhoneNumber::Pref ) );
+ } else if ( it.key() == "email" ) {
+ addr.insertEmail( it.data().toString(), true );
+ } else if ( it.key() == "email_type" ) {
+ } else if ( it.key() == "email_home" ) {
+ addr.insertEmail( it.data().toString(), false );
+ } else if ( it.key() == "email_home_type" ) {
+ } else if ( it.key() == "cat_id" ) {
+ const TQMap<TQString, TQVariant> categories = it.data().toMap();
+ TQMap<TQString, TQVariant>::ConstIterator it;
+
+ for ( it = categories.begin(); it != categories.end(); ++it )
+ addr.insertCategory( it.data().toString() );
+ } else if ( it.key() == "rights" ) {
+ setRights( addr, it.data().toInt() );
+ }
+ }
+
+ TQMap<TQString, TQString>::ConstIterator cfIt;
+ for ( cfIt = mCustomFieldsMap.begin(); cfIt != mCustomFieldsMap.end(); ++cfIt ) {
+ if ( args[ cfIt.key() ].toString().isEmpty() )
+ continue;
+
+ if ( cfIt.key() == "freebusy_url" ) {
+ KCal::FreeBusyUrlStore::self()->writeUrl( addr.preferredEmail(),
+ args[ cfIt.key() ].toString() );
+ KCal::FreeBusyUrlStore::self()->sync();
+ } else
+ addr.insertCustom( "XMLRPCResource", cfIt.key(), cfIt.data() );
+ }
+
+ if ( !addrOne.isEmpty() )
+ addr.insertAddress( addrOne );
+ if ( !addrTwo.isEmpty() )
+ addr.insertAddress( addrTwo );
+}
+
+void ResourceXMLRPC::loadCategoriesFinished( const TQValueList<TQVariant> &mapList,
+ const TQVariant& )
+{
+ mCategoryMap.clear();
+
+ const TQMap<TQString, TQVariant> map = mapList[ 0 ].toMap();
+ TQMap<TQString, TQVariant>::ConstIterator it;
+
+ KABPrefs *prefs = KABPrefs::instance();
+ for ( it = map.begin(); it != map.end(); ++it ) {
+ mCategoryMap.insert( it.data().toString(), it.key().toInt() );
+
+ TQStringList categories = prefs->customCategories();
+ if ( categories.find( it.data().toString() ) == categories.end() )
+ categories.append( it.data().toString() );
+
+ prefs->mCustomCategories = categories;
+ }
+}
+
+void ResourceXMLRPC::loadCustomFieldsFinished( const TQValueList<TQVariant> &mapList,
+ const TQVariant& )
+{
+ mCustomFieldsMap.clear();
+
+ const TQMap<TQString, TQVariant> map = mapList[ 0 ].toMap();
+ TQMap<TQString, TQVariant>::ConstIterator it;
+
+ for ( it = map.begin(); it != map.end(); ++it )
+ mCustomFieldsMap.insert( it.key(), it.data().toString() );
+}
+
+#include "kabc_resourcexmlrpc.moc"
diff --git a/tderesources/egroupware/kabc_resourcexmlrpc.h b/tderesources/egroupware/kabc_resourcexmlrpc.h
new file mode 100644
index 000000000..d9b745aa3
--- /dev/null
+++ b/tderesources/egroupware/kabc_resourcexmlrpc.h
@@ -0,0 +1,115 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_RESOURCEXMLRPC_H
+#define KABC_RESOURCEXMLRPC_H
+
+#include <tqmap.h>
+#include <tdepimmacros.h>
+
+#include "libtdepim/kabcresourcecached.h"
+
+class TDEConfig;
+class Synchronizer;
+
+namespace KXMLRPC {
+class Server;
+}
+
+namespace KABC {
+
+class EGroupwarePrefs;
+
+class KDE_EXPORT ResourceXMLRPC : public ResourceCached
+{
+ Q_OBJECT
+
+
+ public:
+ ResourceXMLRPC( const TDEConfig* );
+ ResourceXMLRPC( const TQString &url, const TQString &domain,
+ const TQString &user, const TQString &password );
+ ~ResourceXMLRPC();
+
+ virtual void writeConfig( TDEConfig* );
+
+ EGroupwarePrefs *prefs() const { return mPrefs; }
+
+ virtual bool doOpen();
+ virtual void doClose();
+
+ virtual Ticket *requestSaveTicket();
+ virtual void releaseSaveTicket( Ticket* );
+
+ virtual bool load();
+ virtual bool asyncLoad();
+ virtual bool save( Ticket * );
+ virtual bool asyncSave( Ticket * );
+
+ protected:
+ void init();
+
+ protected slots:
+ void loginFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void logoutFinished( const TQValueList<TQVariant>&, const TQVariant& );
+
+ void listContactsFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void addContactFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void updateContactFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void deleteContactFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void loadCategoriesFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void loadCustomFieldsFinished( const TQValueList<TQVariant>&, const TQVariant& );
+
+ void fault( int, const TQString&, const TQVariant& );
+ void addContactFault( int, const TQString&, const TQVariant& );
+ void updateContactFault( int, const TQString&, const TQVariant& );
+ void deleteContactFault( int, const TQString&, const TQVariant& );
+
+ void addContact( const KABC::Addressee& );
+ void updateContact( const KABC::Addressee& );
+ void deleteContact( const KABC::Addressee& );
+
+ private:
+ void initEGroupware();
+
+ TQString addrTypesToTypeStr( int );
+
+ void writeContact( const Addressee&, TQMap<TQString, TQVariant>& );
+ void readContact( const TQMap<TQString, TQVariant>&, Addressee &addr, TQString& );
+
+ EGroupwarePrefs *mPrefs;
+
+ TQString mSessionID;
+ TQString mKp3;
+
+ TQMap<TQString, int> mCategoryMap;
+ TQMap<TQString, int> mAddrTypes;
+ TQMap<TQString, TQString> mCustomFieldsMap;
+
+ KXMLRPC::Server *mServer;
+ Synchronizer *mSynchronizer;
+
+ class ResourceXMLRPCPrivate;
+ ResourceXMLRPCPrivate *d;
+};
+
+}
+
+#endif
diff --git a/tderesources/egroupware/kabc_resourcexmlrpcconfig.cpp b/tderesources/egroupware/kabc_resourcexmlrpcconfig.cpp
new file mode 100644
index 000000000..ddafbd1f2
--- /dev/null
+++ b/tderesources/egroupware/kabc_resourcexmlrpcconfig.cpp
@@ -0,0 +1,97 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2002 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <tqlabel.h>
+#include <tqlayout.h>
+
+#include <kdebug.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <klineedit.h>
+#include <kurlrequester.h>
+
+#include "kabc_egroupwareprefs.h"
+#include "kabc_resourcexmlrpc.h"
+#include "kabc_resourcexmlrpcconfig.h"
+
+using namespace KABC;
+
+ResourceXMLRPCConfig::ResourceXMLRPCConfig( TQWidget* parent, const char* name )
+ : KRES::ConfigWidget( parent, name )
+{
+ TQGridLayout *mainLayout = new TQGridLayout( this, 4, 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( "Domain:" ), this );
+ mDomain = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mDomain, 1, 1 );
+
+ label = new TQLabel( i18n( "User:" ), this );
+ mUser = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 2, 0 );
+ mainLayout->addWidget( mUser, 2, 1 );
+
+ label = new TQLabel( i18n( "Password:" ), this );
+ mPassword = new KLineEdit( this );
+ mPassword->setEchoMode( TQLineEdit::Password );
+
+ mainLayout->addWidget( label, 3, 0 );
+ mainLayout->addWidget( mPassword, 3, 1 );
+}
+
+void ResourceXMLRPCConfig::loadSettings( KRES::Resource *res )
+{
+ ResourceXMLRPC *resource = dynamic_cast<ResourceXMLRPC*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceXMLRPCConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ mURL->setURL( resource->prefs()->url() );
+ mDomain->setText( resource->prefs()->domain() );
+ mUser->setText( resource->prefs()->user() );
+ mPassword->setText( resource->prefs()->password() );
+}
+
+void ResourceXMLRPCConfig::saveSettings( KRES::Resource *res )
+{
+ ResourceXMLRPC *resource = dynamic_cast<ResourceXMLRPC*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceXMLRPCConfig::saveSettings(): cast failed" << endl;
+ return;
+ }
+
+ resource->prefs()->setUrl( mURL->url() );
+ resource->prefs()->setDomain( mDomain->text() );
+ resource->prefs()->setUser( mUser->text() );
+ resource->prefs()->setPassword( mPassword->text() );
+}
+
+#include "kabc_resourcexmlrpcconfig.moc"
diff --git a/tderesources/egroupware/kabc_resourcexmlrpcconfig.h b/tderesources/egroupware/kabc_resourcexmlrpcconfig.h
new file mode 100644
index 000000000..0a9dc9f06
--- /dev/null
+++ b/tderesources/egroupware/kabc_resourcexmlrpcconfig.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2002 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCEXMLRPCCONFIG_H
+#define RESOURCEXMLRPCCONFIG_H
+
+#include <tderesources/configwidget.h>
+#include <tdepimmacros.h>
+
+class KLineEdit;
+class KURLRequester;
+
+namespace KABC {
+
+class KDE_EXPORT ResourceXMLRPCConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+
+ public:
+ ResourceXMLRPCConfig( TQWidget* parent = 0, const char* name = 0 );
+
+ public slots:
+ void loadSettings( KRES::Resource* );
+ void saveSettings( KRES::Resource* );
+
+ private:
+ KURLRequester *mURL;
+ KLineEdit *mDomain;
+ KLineEdit *mUser;
+ KLineEdit *mPassword;
+};
+
+}
+
+#endif
diff --git a/tderesources/egroupware/kabc_resourcexmlrpcplugin.cpp b/tderesources/egroupware/kabc_resourcexmlrpcplugin.cpp
new file mode 100644
index 000000000..c4c0cc6c0
--- /dev/null
+++ b/tderesources/egroupware/kabc_resourcexmlrpcplugin.cpp
@@ -0,0 +1,40 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kabc_resourcexmlrpc.h"
+#include "kabc_resourcexmlrpcconfig.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+
+using namespace KABC;
+
+typedef KRES::PluginFactory< ResourceXMLRPC, ResourceXMLRPCConfig > XMLRPCFactory;
+
+// FIXME: Use K_EXPORT_COMPONENT_FACTORY( kabc_xmlrpc, XMLRPCFactory ); here
+// Problem: How to insert the catalogue!
+extern "C"
+{
+ void *init_kabc_xmlrpc()
+ {
+ TDEGlobal::locale()->insertCatalogue( "kres_xmlrpc" );
+ return new XMLRPCFactory;
+ }
+}
diff --git a/tderesources/egroupware/kabc_xmlrpc.desktop b/tderesources/egroupware/kabc_xmlrpc.desktop
new file mode 100644
index 000000000..6eeb94f33
--- /dev/null
+++ b/tderesources/egroupware/kabc_xmlrpc.desktop
@@ -0,0 +1,50 @@
+[Desktop Entry]
+Name=eGroupware Server (via XML-RPC)
+Name[af]=eGroupware Bediener (via XML-RPC)
+Name[bg]=Сървър eGroupware (чрез XML-RPC)
+Name[br]=Servijer eGroupware (gant XML-RPC)
+Name[ca]=Servidor eGroupware (via XML-RPC)
+Name[cs]=eGroupware Server (přes XML-RPC)
+Name[da]=eGroupware server (via XML-RPC)
+Name[el]=Εξυπηρετητής eGroupware (μέσω XML-RPC)
+Name[es]=Servidor de eGroupware (por medio de XML-RPC)
+Name[et]=eGroupware server (XML-RPC vahendusel)
+Name[eu]=eGroupware zerbitzaria (XML-RPC bidez)
+Name[fa]=کارساز eGroupware (از طریق XML-RPC)
+Name[fi]=eGroupware-palvelin (XML-RPC kautta)
+Name[fr]=Serveur eGroupware (via XML-RPC)
+Name[fy]=eGroupware-tsjinner (fia XML-RPC)
+Name[ga]=Freastalaí eGroupware (via XML-RPC)
+Name[gl]=Servidor eGroupware (mediante XML-RPC)
+Name[hu]=eGroupware-kiszolgáló (XML-RPC-n keresztül)
+Name[is]=eGroupware þjónn (gegnum XML-RPC)
+Name[it]=Server eGroupware (via XML-RPC)
+Name[ja]=eGroupware サーバ (XML-RPC 経由)
+Name[kk]=eGroupware сервері (XML-RPC арқылы)
+Name[km]=ម៉ាស៊ីន​បម្រើ eGroupware (តាម​រយៈ XML-RPC)
+Name[lt]=eGroupware serveris (per XML-RPC)
+Name[ms]=Pelayan eGroupware (melalui XML-RPC)
+Name[nb]=eGroupware-tjener (via XML-RPPC)
+Name[nds]=eGroupware-Server (över XML-RPC)
+Name[ne]=(XML-RPC मार्फत) eGroupware सर्भर
+Name[nl]=eGroupware-server (via XML-RPC)
+Name[nn]=eGroupware-tenar (via XML-RPC)
+Name[pl]=Serwer eGroupware (poprzez XML-RPC)
+Name[pt]=Servidor eGroupware (via XML-RPC)
+Name[pt_BR]=Servidor eGroupware (via XML-RPC)
+Name[ru]=Сервер eGroupware (через XML-RPC)
+Name[sk]=eGroupware Server (cez XML-RPC)
+Name[sl]=Strežnik eGroupware (preko XML-RPC)
+Name[sr]=eGroupware сервер (преко XML-RPC)
+Name[sr@Latn]=eGroupware server (preko XML-RPC)
+Name[sv]=eGroupware-server (via XML-RPC)
+Name[ta]=eGroupware சேவகன் (via XML-RPC)
+Name[tr]=eGroupware Sunucusu (XML-RPC ile)
+Name[uk]=Сервер eGroupware (через XML-RPC)
+Name[zh_CN]=eGroupware 服务器(通过 XML-RPC)
+Name[zh_TW]=eGroupware 伺服器(透過 XML-RPC)
+X-TDE-Library=kabc_xmlrpc
+Type=Service
+ServiceTypes=KResources/Plugin
+X-TDE-ResourceFamily=contact
+X-TDE-ResourceType=xmlrpc
diff --git a/tderesources/egroupware/kcal_egroupwareprefs.kcfgc b/tderesources/egroupware/kcal_egroupwareprefs.kcfgc
new file mode 100644
index 000000000..6c9f6d4d3
--- /dev/null
+++ b/tderesources/egroupware/kcal_egroupwareprefs.kcfgc
@@ -0,0 +1,11 @@
+# Code generation options for kconfig_compiler
+File=tderesources_kcal_egroupware.kcfg
+ClassName=EGroupwarePrefs
+NameSpace=KCal
+Singleton=false
+Mutators=true
+Inherits=KResourcePrefs
+IncludeFiles=libtdepim/kresourceprefs.h
+GlobalEnums=true
+#ItemAccessors=true
+#SetUserTexts=true
diff --git a/tderesources/egroupware/kcal_resourcexmlrpc.cpp b/tderesources/egroupware/kcal_resourcexmlrpc.cpp
new file mode 100644
index 000000000..c703fa2b9
--- /dev/null
+++ b/tderesources/egroupware/kcal_resourcexmlrpc.cpp
@@ -0,0 +1,1206 @@
+/*
+ This file is part of tdepim.
+
+ Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <stdlib.h>
+#include <typeinfo>
+
+#include <tqapplication.h>
+#include <tqdatetime.h>
+#include <tqptrlist.h>
+#include <tqstringlist.h>
+#include <tqtimer.h>
+
+#include <kabc/locknull.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <tderesources/configwidget.h>
+#include <kstandarddirs.h>
+#include <kstringhandler.h>
+#include <kurl.h>
+#include <libtdepim/kpimprefs.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/alarm.h"
+
+#include "kcal_egroupwareprefs.h"
+#include "kcal_resourcexmlrpcconfig.h"
+#include "kcal_resourcexmlrpc.h"
+
+#include "access.h"
+#include "synchronizer.h"
+#include "xmlrpciface.h"
+
+#define CAL_PRIO_LOW 1
+#define CAL_PRIO_NORMAL 2
+#define CAL_PRIO_HIGH 3
+
+#define CAL_RECUR_NONE 0
+#define CAL_RECUR_DAILY 1
+#define CAL_RECUR_WEEKLY 2
+#define CAL_RECUR_MONTHLY_MDAY 3
+#define CAL_RECUR_MONTHLY_WDAY 4
+#define CAL_RECUR_YEARLY 5
+#define CAL_SUNDAY 1
+#define CAL_MONDAY 2
+#define CAL_TUESDAY 4
+#define CAL_WEDNESDAY 8
+#define CAL_THURSDAY 16
+#define CAL_FRIDAY 32
+#define CAL_SATURDAY 64
+#define CAL_WEEKDAYS 62
+#define CAL_WEEKEND 65
+#define CAL_ALLDAYS 127
+
+using namespace KCal;
+
+typedef KRES::PluginFactory<ResourceXMLRPC, ResourceXMLRPCConfig> XMLRPCFactory;
+K_EXPORT_COMPONENT_FACTORY( kcal_xmlrpc, XMLRPCFactory )
+
+
+static const TQString SearchEventsCommand = "calendar.bocalendar.search";
+static const TQString AddEventCommand = "calendar.bocalendar.write";
+static const TQString DeleteEventCommand = "calendar.bocalendar.delete";
+static const TQString LoadEventCategoriesCommand = "calendar.bocalendar.categories";
+
+static const TQString SearchTodosCommand = "infolog.boinfolog.search";
+static const TQString AddTodoCommand = "infolog.boinfolog.write";
+static const TQString DeleteTodoCommand = "infolog.boinfolog.delete";
+static const TQString LoadTodoCategoriesCommand = "infolog.boinfolog.categories";
+
+static void setRights( Incidence *incidence, int rights )
+{
+ incidence->setCustomProperty( "EGWRESOURCE", "RIGHTS", TQString::number( rights ) );
+}
+
+static int rights( Incidence *incidence )
+{
+ return incidence->customProperty( "EGWRESOURCE", "RIGHTS" ).toInt();
+}
+
+ResourceXMLRPC::ResourceXMLRPC( const TDEConfig* config )
+ : ResourceCached( config ), mServer( 0 ), mLock( 0 )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ if ( config ) {
+ readConfig( config );
+ } else {
+ setResourceName( i18n( "eGroupware Server" ) );
+ }
+
+ initEGroupware();
+}
+
+ResourceXMLRPC::ResourceXMLRPC( )
+ : ResourceCached( 0 ), mServer( 0 ), mLock( 0 )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ initEGroupware();
+}
+
+ResourceXMLRPC::~ResourceXMLRPC()
+{
+ disableChangeNotification();
+
+ delete mServer;
+ mServer = 0;
+
+ delete mLock;
+ mLock = 0;
+
+ delete mPrefs;
+ mPrefs = 0;
+
+ delete mSynchronizer;
+ mSynchronizer = 0;
+}
+
+void ResourceXMLRPC::init()
+{
+ setType( "xmlrpc" );
+
+ mTodoStateMapper.setPath( "kcal/todostatemap/" );
+
+ mPrefs = new EGroupwarePrefs;
+ mLoaded = 0;
+
+ mLock = new KABC::LockNull( true );
+ mSynchronizer = new Synchronizer();
+}
+
+void ResourceXMLRPC::initEGroupware()
+{
+ KURL url( mPrefs->url() );
+}
+
+void ResourceXMLRPC::readConfig( const TDEConfig* config )
+{
+ mPrefs->readConfig();
+
+ ResourceCached::readConfig( config );
+}
+
+void ResourceXMLRPC::writeConfig( TDEConfig* config )
+{
+ ResourceCalendar::writeConfig( config );
+
+ mPrefs->writeConfig();
+
+ ResourceCached::writeConfig( config );
+}
+
+bool ResourceXMLRPC::doOpen()
+{
+ kdDebug(5800) << "ResourceXMLRPC::doOpen()" << endl;
+
+ if ( mServer )
+ delete mServer;
+
+ mServer = new KXMLRPC::Server( KURL(), this );
+ mServer->setUrl( KURL( mPrefs->url() ) );
+ mServer->setUserAgent( "KDE-Calendar" );
+
+ TQMap<TQString, TQVariant> args;
+ args.insert( "domain", mPrefs->domain() );
+ args.insert( "username", mPrefs->user() );
+ args.insert( "password", mPrefs->password() );
+
+ mServer->call( "system.login", TQVariant( args ),
+ this, TQT_SLOT( loginFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mSynchronizer->start();
+
+ return true;
+}
+
+void ResourceXMLRPC::doClose()
+{
+ kdDebug(5800) << "ResourceXMLRPC::doClose()" << endl;
+
+ TQMap<TQString, TQVariant> args;
+ args.insert( "sessionid", mSessionID );
+ args.insert( "kp3", mKp3 );
+
+ mServer->call( "system.logout", TQVariant( args ),
+ this, TQT_SLOT( logoutFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mSynchronizer->start();
+}
+
+bool ResourceXMLRPC::doLoad()
+{
+ kdDebug() << "ResourceXMLRPC::load()" << endl;
+
+ mCalendar.close();
+
+ disableChangeNotification();
+ loadCache();
+ enableChangeNotification();
+
+ emit resourceChanged( this );
+
+ clearChanges();
+
+ loadCache();
+ mTodoStateMapper.setIdentifier( type() + "_" + identifier() );
+ mTodoStateMapper.load();
+
+ TQMap<TQString, TQVariant> args, columns;
+ args.insert( "start", TQDateTime( TQDate::currentDate().addDays( -12 ) ) );
+ args.insert( "end", TQDateTime( TQDate::currentDate().addDays( 2000 ) ) );
+
+ mServer->call( SearchEventsCommand, args,
+ this, TQT_SLOT( listEventsFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+ args.clear();
+
+ columns.insert( "type", "task" );
+ args.insert( "filter", "none" );
+ args.insert( "col_filter", columns );
+ args.insert( "order", "id_parent" );
+
+ mServer->call( SearchTodosCommand, args,
+ this, TQT_SLOT( listTodosFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mServer->call( LoadEventCategoriesCommand, TQVariant( TQMap<TQString, TQVariant>() ),
+ this, TQT_SLOT( loadEventCategoriesFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mServer->call( LoadTodoCategoriesCommand, TQVariant( false, 0 ),
+ this, TQT_SLOT( loadTodoCategoriesFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+ return true;
+}
+
+bool ResourceXMLRPC::doSave()
+{
+ if ( readOnly() || !hasChanges() ) {
+ emit resourceSaved( this );
+ return true;
+ }
+
+ saveCache();
+
+ const Event::List events = mCalendar.rawEvents();
+ Event::List::ConstIterator evIt;
+
+ uint counter = 0;
+ for ( evIt = events.begin(); evIt != events.end(); ++evIt ) {
+ if ( !(*evIt)->isReadOnly() ) {
+ TQMap<TQString, TQVariant> args;
+ writeEvent( (*evIt), args );
+
+ args.insert( "id", idMapper().remoteId( (*evIt)->uid() ).toInt() );
+ mServer->call( AddEventCommand, TQVariant( args ),
+ this, TQT_SLOT( updateEventFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+ counter++;
+ }
+ }
+
+ const Todo::List todos = mCalendar.rawTodos();
+ Todo::List::ConstIterator todoIt;
+
+ for ( todoIt = todos.begin(); todoIt != todos.end(); ++todoIt ) {
+ if ( !(*todoIt)->isReadOnly() ) {
+ TQMap<TQString, TQVariant> args;
+ writeTodo( (*todoIt), args );
+
+ args.insert( "id", idMapper().remoteId( (*todoIt)->uid() ).toInt() );
+ mServer->call( AddTodoCommand, TQVariant( args ),
+ this, TQT_SLOT( updateTodoFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+ counter++;
+ }
+ }
+
+ if ( counter != 0 )
+ mSynchronizer->start();
+
+ mTodoStateMapper.save();
+
+ return true;
+}
+
+bool ResourceXMLRPC::isSaving()
+{
+ return false;
+}
+
+KABC::Lock *ResourceXMLRPC::lock()
+{
+ return mLock;
+}
+
+
+bool ResourceXMLRPC::addEvent( Event* ev )
+{
+ TQMap<TQString, TQVariant> args;
+
+ disableChangeNotification();
+
+ setRights( ev, EGW_ACCESS_ALL );
+ Event *oldEvent = mCalendar.event( ev->uid() );
+ if ( oldEvent ) { // already exists
+ if ( !oldEvent->isReadOnly() ) {
+ writeEvent( ev, args );
+ args.insert( "id", idMapper().remoteId( ev->uid() ).toInt() );
+ mServer->call( AddEventCommand, TQVariant( args ),
+ this, TQT_SLOT( updateEventFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mCalendar.deleteIncidence( oldEvent );
+ mCalendar.addIncidence( ev );
+ saveCache();
+ }
+ } else { // new event
+ writeEvent( ev, args );
+ mServer->call( AddEventCommand, TQVariant( args ),
+ this, TQT_SLOT( addEventFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( ev->uid() ) );
+
+ mCalendar.addEvent( ev );
+ saveCache();
+ }
+
+ enableChangeNotification();
+
+ return true;
+}
+
+bool ResourceXMLRPC::deleteEvent( Event* ev )
+{
+ if ( !(rights( ev ) & EGW_ACCESS_DELETE) && rights( ev ) != -1 )
+ return false;
+
+ mServer->call( DeleteEventCommand, idMapper().remoteId( ev->uid() ).toInt(),
+ this, TQT_SLOT( deleteEventFinished( const TQValueList<TQVariant>&,
+ const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( ev->uid() ) );
+ return true;
+}
+
+
+Event *ResourceXMLRPC::event( const TQString& uid )
+{
+ return mCalendar.event( uid );
+}
+
+Event::List ResourceXMLRPC::rawEventsForDate( const TQDate& qd,
+ EventSortField sortField,
+ SortDirection sortDirection )
+{
+ return mCalendar.rawEventsForDate( qd, sortField, sortDirection );
+}
+
+
+Event::List ResourceXMLRPC::rawEvents( const TQDate& start, const TQDate& end,
+ bool inclusive )
+{
+ return mCalendar.rawEvents( start, end, inclusive );
+}
+
+Event::List ResourceXMLRPC::rawEventsForDate( const TQDateTime& qdt )
+{
+ return mCalendar.rawEventsForDate( qdt.date() );
+}
+
+Event::List ResourceXMLRPC::rawEvents()
+{
+ return mCalendar.rawEvents();
+}
+
+
+bool ResourceXMLRPC::addTodo( Todo *todo )
+{
+ TQMap<TQString, TQVariant> args;
+
+ disableChangeNotification();
+
+ setRights( todo, EGW_ACCESS_ALL );
+ Todo *oldTodo = mCalendar.todo( todo->uid() );
+ if ( oldTodo ) { // already exists
+ if ( !oldTodo->isReadOnly() ) {
+ writeTodo( todo, args );
+ args.insert( "id", idMapper().remoteId( todo->uid() ).toInt() );
+ mServer->call( AddTodoCommand, TQVariant( args ),
+ this, TQT_SLOT( updateTodoFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mCalendar.deleteIncidence( oldTodo );
+ mCalendar.addIncidence( todo );
+ saveCache();
+ }
+ } else { // new todo
+ writeTodo( todo, args );
+ mServer->call( AddTodoCommand, TQVariant( args ),
+ this, TQT_SLOT( addTodoFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( todo->uid() ) );
+
+ mCalendar.addTodo( todo );
+ saveCache();
+ }
+
+ enableChangeNotification();
+
+ return true;
+}
+
+bool ResourceXMLRPC::deleteTodo( Todo *todo )
+{
+ if ( !(rights( todo ) & EGW_ACCESS_DELETE) && rights( todo ) != -1 )
+ return false;
+
+ mServer->call( DeleteTodoCommand, idMapper().remoteId( todo->uid() ).toInt(),
+ this, TQT_SLOT( deleteTodoFinished( const TQValueList<TQVariant>&,
+ const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( todo->uid() ) );
+ return true;
+}
+
+Todo::List ResourceXMLRPC::rawTodos()
+{
+ return mCalendar.rawTodos();
+}
+
+Todo *ResourceXMLRPC::todo( const TQString& uid )
+{
+ return mCalendar.todo( uid );
+}
+
+Todo::List ResourceXMLRPC::rawTodosForDate( const TQDate& date )
+{
+ return mCalendar.rawTodosForDate( date );
+}
+
+bool ResourceXMLRPC::addJournal( Journal* journal )
+{
+ return mCalendar.addJournal( journal );
+}
+
+bool ResourceXMLRPC::deleteJournal( Journal* journal )
+{
+ return mCalendar.deleteJournal( journal );
+}
+
+Journal::List ResourceXMLRPC::journals( const TQDate& date )
+{
+ return mCalendar.journals( date );
+}
+
+Journal *ResourceXMLRPC::journal( const TQString& uid )
+{
+ return mCalendar.journal( uid );
+}
+
+
+Alarm::List ResourceXMLRPC::alarmsTo( const TQDateTime& to )
+{
+ return mCalendar.alarmsTo( to );
+}
+
+Alarm::List ResourceXMLRPC::alarms( const TQDateTime& from, const TQDateTime& to )
+{
+ return mCalendar.alarms( from, to );
+}
+
+void ResourceXMLRPC::dump() const
+{
+ ResourceCalendar::dump();
+}
+
+void ResourceXMLRPC::reload()
+{
+ load();
+}
+
+
+void ResourceXMLRPC::loginFinished( const TQValueList<TQVariant>& variant,
+ const TQVariant& )
+{
+ TQMap<TQString, TQVariant> map = variant[ 0 ].toMap();
+
+ KURL url = KURL( mPrefs->url() );
+ if ( map[ "GOAWAY" ].toString() == "XOXO" ) { // failed
+ mSessionID = mKp3 = "";
+ } else {
+ mSessionID = map[ "sessionid" ].toString();
+ mKp3 = map[ "kp3" ].toString();
+ }
+
+ url.setUser( mSessionID );
+ url.setPass( mKp3 );
+ mServer->setUrl( url );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::logoutFinished( const TQValueList<TQVariant>& variant,
+ const TQVariant& )
+{
+ TQMap<TQString, TQVariant> map = variant[ 0 ].toMap();
+
+ if ( map[ "GOODBYE" ].toString() != "XOXO" )
+ kdError() << "logout failed" << endl;
+
+ KURL url = KURL( mPrefs->url() );
+ mSessionID = mKp3 = "";
+ url.setUser( mSessionID );
+ url.setPass( mKp3 );
+ mServer->setUrl( url );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::listEventsFinished( const TQValueList<TQVariant>& list,
+ const TQVariant& )
+{
+ const TQValueList<TQVariant> eventList = list[ 0 ].toList();
+ TQValueList<TQVariant>::ConstIterator eventIt;
+
+ disableChangeNotification();
+
+ Event::List retrievedEvents;
+
+ bool changed = false;
+ for ( eventIt = eventList.begin(); eventIt != eventList.end(); ++eventIt ) {
+ TQMap<TQString, TQVariant> map = (*eventIt).toMap();
+
+ Event *event = new Event;
+ event->setFloats( false );
+
+ TQString uid;
+ readEvent( map, event, uid );
+
+ // do we already have this event?
+ Event *oldEvent = 0;
+ TQString localUid = idMapper().localId( uid );
+ if ( !localUid.isEmpty() )
+ oldEvent = mCalendar.event( localUid );
+
+ if ( oldEvent ) {
+ event->setUid( oldEvent->uid() );
+ event->setCreated( oldEvent->created() );
+
+ if ( !(*oldEvent == *event) ) {
+ mCalendar.deleteEvent( oldEvent );
+ mCalendar.addEvent( event );
+ retrievedEvents.append( event );
+ changed = true;
+ } else
+ delete event;
+ } else {
+ if ( !localUid.isEmpty() )
+ event->setUid( localUid );
+ idMapper().setRemoteId( event->uid(), uid );
+ mCalendar.addEvent( event );
+ retrievedEvents.append( event );
+ changed = true;
+ }
+ }
+
+ enableChangeNotification();
+
+ clearChanges();
+
+
+ if ( changed ) {
+ cleanUpEventCache( retrievedEvents );
+ saveCache();
+ emit resourceChanged( this );
+ }
+
+ checkLoadingFinished();
+}
+
+void ResourceXMLRPC::deleteEventFinished( const TQValueList<TQVariant>&,
+ const TQVariant& id )
+{
+ idMapper().removeRemoteId( idMapper().remoteId( id.toString() ) );
+
+ Event *ev = mCalendar.event( id.toString() );
+
+ disableChangeNotification();
+ mCalendar.deleteEvent( ev );
+ saveCache();
+ enableChangeNotification();
+
+ emit resourceChanged( this );
+}
+
+void ResourceXMLRPC::updateEventFinished( const TQValueList<TQVariant>&,
+ const TQVariant& )
+{
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::addEventFinished( const TQValueList<TQVariant>& list,
+ const TQVariant& id )
+{
+ idMapper().setRemoteId( id.toString(), list[ 0 ].toString() );
+
+ emit resourceChanged( this );
+}
+
+void ResourceXMLRPC::loadEventCategoriesFinished( const TQValueList<TQVariant> &mapList, const TQVariant& )
+{
+ mEventCategoryMap.clear();
+
+ const TQMap<TQString, TQVariant> map = mapList[ 0 ].toMap();
+ TQMap<TQString, TQVariant>::ConstIterator it;
+
+ KPimPrefs prefs( "korganizerrc" );
+ for ( it = map.begin(); it != map.end(); ++it ) {
+ mEventCategoryMap.insert( it.data().toString(), it.key().toInt() );
+
+ if ( prefs.mCustomCategories.find( it.data().toString() ) == prefs.mCustomCategories.end() )
+ prefs.mCustomCategories.append( it.data().toString() );
+ }
+
+ prefs.usrWriteConfig();
+ prefs.config()->sync();
+
+ checkLoadingFinished();
+}
+
+void ResourceXMLRPC::listTodosFinished( const TQValueList<TQVariant>& list,
+ const TQVariant& )
+{
+ const TQValueList<TQVariant> todoList = list[ 0 ].toList();
+ TQValueList<TQVariant>::ConstIterator todoIt;
+
+ disableChangeNotification();
+
+ Todo::List retrievedTodos;
+
+ bool changed = false;
+ for ( todoIt = todoList.begin(); todoIt != todoList.end(); ++todoIt ) {
+ TQMap<TQString, TQVariant> map = (*todoIt).toMap();
+
+ Todo *todo = new Todo;
+
+ TQString uid;
+ readTodo( map, todo, uid );
+
+ // do we already have this todo?
+ Todo *oldTodo = 0;
+ TQString localUid = idMapper().localId( uid );
+ if ( !localUid.isEmpty() )
+ oldTodo = mCalendar.todo( localUid );
+
+ if ( oldTodo ) {
+ todo->setUid( oldTodo->uid() );
+ todo->setCreated( oldTodo->created() );
+
+ if ( !(*oldTodo == *todo) ) {
+ mCalendar.deleteTodo( oldTodo );
+ mCalendar.addTodo( todo );
+ retrievedTodos.append( todo );
+ changed = true;
+ } else
+ delete todo;
+ } else {
+ idMapper().setRemoteId( todo->uid(), uid );
+ mCalendar.addTodo( todo );
+ retrievedTodos.append( todo );
+ changed = true;
+ }
+ }
+
+ enableChangeNotification();
+
+ if ( changed ) {
+ cleanUpTodoCache( retrievedTodos );
+ saveCache();
+ emit resourceChanged( this );
+ }
+
+ checkLoadingFinished();
+}
+
+void ResourceXMLRPC::deleteTodoFinished( const TQValueList<TQVariant>&,
+ const TQVariant& id )
+{
+ idMapper().removeRemoteId( idMapper().remoteId( id.toString() ) );
+ mTodoStateMapper.remove( idMapper().remoteId( id.toString() ) );
+
+ Todo *todo = mCalendar.todo( id.toString() );
+ disableChangeNotification();
+ mCalendar.deleteTodo( todo );
+ saveCache();
+ enableChangeNotification();
+
+ emit resourceChanged( this );
+}
+
+void ResourceXMLRPC::addTodoFinished( const TQValueList<TQVariant>& list,
+ const TQVariant& id )
+{
+ idMapper().setRemoteId( id.toString(), list[ 0 ].toString() );
+
+ emit resourceChanged( this );
+}
+
+void ResourceXMLRPC::updateTodoFinished( const TQValueList<TQVariant>&,
+ const TQVariant& )
+{
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::loadTodoCategoriesFinished( const TQValueList<TQVariant> &mapList, const TQVariant& )
+{
+ mTodoCategoryMap.clear();
+
+ const TQMap<TQString, TQVariant> map = mapList[ 0 ].toMap();
+ TQMap<TQString, TQVariant>::ConstIterator it;
+
+ KPimPrefs prefs( "korganizerrc" );
+ for ( it = map.begin(); it != map.end(); ++it ) {
+ mTodoCategoryMap.insert( it.data().toString(), it.key().toInt() );
+
+ if ( prefs.mCustomCategories.find( it.data().toString() ) == prefs.mCustomCategories.end() )
+ prefs.mCustomCategories.append( it.data().toString() );
+ }
+
+ prefs.usrWriteConfig();
+ prefs.config()->sync();
+
+ checkLoadingFinished();
+}
+
+void ResourceXMLRPC::fault( int error, const TQString& errorMsg,
+ const TQVariant& )
+{
+ kdError() << "Server send error " << error << ": " << errorMsg << endl;
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::readEvent( const TQMap<TQString, TQVariant> &args, Event *event,
+ TQString &uid )
+{
+ // for recurrence
+ int rType = CAL_RECUR_NONE;
+ int rInterval = 1;
+ int rData = 0;
+ int rights = 0;
+ TQDateTime rEndDate;
+ TQValueList<TQDateTime> rExceptions;
+
+ TQMap<TQString, TQVariant>::ConstIterator it;
+ for ( it = args.begin(); it != args.end(); ++it ) {
+ if ( it.key() == "id" ) {
+ uid = it.data().toString();
+ } else if ( it.key() == "rights" ) {
+ rights = it.data().toInt();
+ } else if ( it.key() == "start" ) {
+ event->setDtStart( it.data().toDateTime() );
+ } else if ( it.key() == "end" ) {
+ TQDateTime start = args[ "start" ].toDateTime();
+ TQDateTime end = it.data().toDateTime();
+ if ( start.time() == end.time() &&
+ start.time().hour() == 0 && start.time().minute() == 0 &&
+ start.time().second() == 0 ) {
+ event->setDtEnd( end.addDays( -1 ) );
+ event->setFloats( true );
+ } else {
+ event->setDtEnd( end );
+ event->setHasEndDate( true );
+ }
+ } else if ( it.key() == "modtime" ) {
+ event->setLastModified( it.data().toDateTime() );
+ } else if ( it.key() == "title" ) {
+ event->setSummary( it.data().toString() );
+ } else if ( it.key() == "description" ) {
+ event->setDescription( it.data().toString() );
+ } else if ( it.key() == "location" ) {
+ event->setLocation( it.data().toString() );
+ } else if ( it.key() == "access" ) {
+ event->setSecrecy( (it.data().toString() == "public" ?
+ Incidence::SecrecyPublic : Incidence::SecrecyPrivate) );
+ } else if ( it.key() == "category" ) {
+ const TQMap<TQString, TQVariant> categories = it.data().toMap();
+ TQMap<TQString, TQVariant>::ConstIterator catIt;
+
+ TQStringList eventCategories;
+ for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
+ mEventCategoryMap.insert( catIt.data().toString(), catIt.key().toInt() );
+ eventCategories.append( catIt.data().toString() );
+ }
+
+ event->setCategories( eventCategories );
+ } else if ( it.key() == "priority" ) {
+ int priority = 0;
+
+ switch( it.data().toInt() ) {
+ case CAL_PRIO_LOW:
+ priority = 10;
+ break;
+ case CAL_PRIO_NORMAL:
+ priority = 5;
+ break;
+ case CAL_PRIO_HIGH:
+ priority = 1;
+ }
+
+ event->setPriority( priority );
+ } else if ( it.key() == "recur_type" ) {
+ rType = it.data().toInt();
+ } else if ( it.key() == "recur_interval" ) {
+ rInterval = it.data().toInt();
+ } else if ( it.key() == "recur_enddate" ) {
+ rEndDate = it.data().toDateTime();
+ } else if ( it.key() == "recur_data" ) {
+ rData = it.data().toInt();
+ } else if ( it.key() == "recur_exception" ) {
+ const TQMap<TQString, TQVariant> dateList = it.data().toMap();
+ TQMap<TQString, TQVariant>::ConstIterator dateIt;
+
+ for ( dateIt = dateList.begin(); dateIt != dateList.end(); ++dateIt )
+ rExceptions.append( (*dateIt).toDateTime() );
+ } else if ( it.key() == "participants" ) {
+ const TQMap<TQString, TQVariant> persons = it.data().toMap();
+ TQMap<TQString, TQVariant>::ConstIterator personsIt;
+
+ for ( personsIt = persons.begin(); personsIt != persons.end(); ++personsIt ) {
+ TQMap<TQString, TQVariant> person = (*personsIt).toMap();
+ Attendee::PartStat status = Attendee::InProcess;
+ if ( person[ "status" ] == "A" )
+ status = Attendee::Accepted;
+ else if ( person[ "status" ] == "R" )
+ status = Attendee::Declined;
+ else if ( person[ "status" ] == "T" )
+ status = Attendee::Tentative;
+ else if ( person[ "status" ] == "N" )
+ status = Attendee::InProcess;
+
+ Attendee *attendee = new Attendee( person[ "name" ].toString(),
+ person[ "email" ].toString(),
+ false, status );
+ attendee->setUid( personsIt.key() );
+ event->addAttendee( attendee );
+ }
+ } else if ( it.key() == "alarm" ) {
+ const TQMap<TQString, TQVariant> alarmList = it.data().toMap();
+ TQMap<TQString, TQVariant>::ConstIterator alarmIt;
+
+ for ( alarmIt = alarmList.begin(); alarmIt != alarmList.end(); ++alarmIt ) {
+ TQMap<TQString, TQVariant> alarm = (*alarmIt).toMap();
+
+ Alarm *vAlarm = event->newAlarm();
+ vAlarm->setText( event->summary() );
+ vAlarm->setTime( alarm[ "time" ].toDateTime() );
+ vAlarm->setStartOffset( alarm[ "offset" ].toInt() );
+ vAlarm->setEnabled( alarm[ "enabled" ].toBool() );
+ }
+ }
+ }
+
+ if ( rType != CAL_RECUR_NONE && rInterval > 0 ) {
+ Recurrence *re = event->recurrence();
+// re->setRecurStart( event->dtStart() );
+
+
+ if ( rInterval == 0 ) // libkcal crashes with rInterval == 0
+ rInterval = 1;
+
+ switch ( rType ) {
+ case CAL_RECUR_DAILY:
+ re->setDaily( rInterval );
+ break;
+ case CAL_RECUR_WEEKLY: {
+ TQBitArray weekMask( 7 );
+ weekMask.setBit( 0, rData & CAL_MONDAY );
+ weekMask.setBit( 1, rData & CAL_TUESDAY );
+ weekMask.setBit( 2, rData & CAL_WEDNESDAY );
+ weekMask.setBit( 3, rData & CAL_THURSDAY );
+ weekMask.setBit( 4, rData & CAL_FRIDAY );
+ weekMask.setBit( 5, rData & CAL_SATURDAY );
+ weekMask.setBit( 6, rData & CAL_SUNDAY );
+
+ re->setWeekly( rInterval, weekMask );
+ break; }
+ case CAL_RECUR_MONTHLY_MDAY:
+ re->setMonthly( rInterval );
+ break;
+ case CAL_RECUR_MONTHLY_WDAY:
+ re->setMonthly( rInterval );
+ // TODO: Set the correct monthly pos
+ break;
+ case CAL_RECUR_YEARLY:
+ re->setYearly( rInterval );
+ break;
+ }
+ if ( rEndDate.date().isValid() )
+ re->setEndDate( rEndDate.date() );
+
+ TQValueList<TQDateTime>::ConstIterator exIt;
+ for ( exIt = rExceptions.begin(); exIt != rExceptions.end(); ++exIt )
+ re->addExDateTime( *exIt );
+ }
+
+ event->setReadOnly( !(rights & EGW_ACCESS_EDIT) );
+ setRights( event, rights );
+}
+
+void ResourceXMLRPC::writeEvent( Event *event, TQMap<TQString, TQVariant> &args )
+{
+ args.insert( "start", event->dtStart() );
+
+ // handle all day events
+ if ( event->doesFloat() )
+ args.insert( "end", TQDateTime(event->dtEnd().addDays( 1 )) );
+ else
+ args.insert( "end", event->dtEnd() );
+
+ args.insert( "modtime", event->lastModified() );
+ args.insert( "title", event->summary() );
+ args.insert( "description", event->description() );
+ args.insert( "location", event->location() );
+
+ // SECRECY
+ args.insert( "access", (event->secrecy() == Incidence::SecrecyPublic ? "public" : "private") );
+
+ // CATEGORY
+ const TQStringList categories = event->categories();
+ TQStringList::ConstIterator catIt;
+ TQMap<TQString, TQVariant> catMap;
+ int counter = 0;
+ for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
+ TQMap<TQString, int>::Iterator it = mEventCategoryMap.find( *catIt );
+ if ( it == mEventCategoryMap.end() ) // new category
+ catMap.insert( TQString::number( counter-- ), *catIt );
+ else
+ catMap.insert( TQString::number( it.data() ), *catIt );
+ }
+ args.insert( "category", catMap );
+
+ // PRIORITY
+ int priority = 0;
+ if ( event->priority() == 1 )
+ priority = CAL_PRIO_HIGH;
+ else if ( event->priority() > 1 && event->priority() <= 5 )
+ priority = CAL_PRIO_NORMAL;
+ else
+ priority = CAL_PRIO_LOW;
+
+ args.insert( "priority", priority );
+
+ // RECURRENCE
+ Recurrence *rec = event->recurrence();
+ if ( !rec->doesRecur() ) {
+ args.insert( "recur_type", int( 0 ) );
+ args.insert( "recur_interval", int( 0 ) );
+ args.insert( "recur_enddate", TQDateTime() );
+ args.insert( "recur_data", int( 0 ) );
+ args.insert( "recur_exception", TQMap<TQString, TQVariant>() );
+ } else {
+ switch ( rec->recurrenceType() ) {
+ case Recurrence::rDaily:
+ args.insert( "recur_type", int( CAL_RECUR_DAILY ) );
+ break;
+ case Recurrence::rWeekly: {
+ int weekMask = 0;
+ if ( rec->days().testBit( 0 ) )
+ weekMask += CAL_MONDAY;
+ if ( rec->days().testBit( 1 ) )
+ weekMask += CAL_TUESDAY;
+ if ( rec->days().testBit( 2 ) )
+ weekMask += CAL_WEDNESDAY;
+ if ( rec->days().testBit( 3 ) )
+ weekMask += CAL_THURSDAY;
+ if ( rec->days().testBit( 4 ) )
+ weekMask += CAL_FRIDAY;
+ if ( rec->days().testBit( 5 ) )
+ weekMask += CAL_SATURDAY;
+ if ( rec->days().testBit( 6 ) )
+ weekMask += CAL_SUNDAY;
+
+ args.insert( "recur_data", weekMask );
+ args.insert( "recur_type", int( CAL_RECUR_WEEKLY ) );
+ }
+ break;
+ case Recurrence::rMonthlyPos:
+ args.insert( "recur_type", int( CAL_RECUR_MONTHLY_MDAY ) );
+ break;
+ case Recurrence::rMonthlyDay:
+ args.insert( "recur_type", int( CAL_RECUR_MONTHLY_WDAY ) );
+ break;
+ case Recurrence::rYearlyDay:
+ args.insert( "recur_type", int( CAL_RECUR_YEARLY ) );
+ break;
+ default:
+ break;
+ }
+
+ args.insert( "recur_interval", rec->frequency() );
+ args.insert( "recur_enddate", rec->endDateTime() );
+
+ // TODO: Also use exception dates!
+ const TQValueList<TQDateTime> dates = event->recurrence()->exDateTimes();
+ TQValueList<TQDateTime>::ConstIterator dateIt;
+ TQMap<TQString, TQVariant> exMap;
+ int counter = 0;
+ for ( dateIt = dates.begin(); dateIt != dates.end(); ++dateIt, ++counter )
+ exMap.insert( TQString::number( counter ), *dateIt );
+
+ args.insert( "recur_exception", exMap );
+ }
+
+ // PARTICIPANTS
+ const Attendee::List attendees = event->attendees();
+ Attendee::List::ConstIterator attIt;
+ TQMap<TQString, TQVariant> persons;
+ for ( attIt = attendees.begin(); attIt != attendees.end(); ++attIt ) {
+ TQMap<TQString, TQVariant> person;
+ TQString status;
+
+ if ( (*attIt)->status() == Attendee::Accepted )
+ status = "A";
+ else if ( (*attIt)->status() == Attendee::Declined )
+ status = "R";
+ else if ( (*attIt)->status() == Attendee::Tentative )
+ status = "T";
+ else
+ status = "N";
+
+ person.insert( "status", status );
+ person.insert( "name", (*attIt)->name() );
+ person.insert( "email", (*attIt)->email() );
+
+ persons.insert( (*attIt)->uid(), person );
+ }
+ args.insert( "participants", persons );
+
+ // ALARMS
+ const Alarm::List alarms = event->alarms();
+ Alarm::List::ConstIterator alarmIt;
+ TQMap<TQString, TQVariant> alarmMap;
+ for ( alarmIt = alarms.begin(); alarmIt != alarms.end(); ++alarmIt ) {
+ TQMap<TQString, TQVariant> alarm;
+ alarm.insert( "time", (*alarmIt)->time() );
+ alarm.insert( "offset", (*alarmIt)->startOffset().asSeconds() );
+ alarm.insert( "enabled", ( (*alarmIt)->enabled() ? int( 1 ) : int( 0 ) ) );
+
+ alarmMap.insert( "id", alarm ); // that sucks...
+ }
+
+ args.insert( "alarm", alarmMap );
+}
+
+void ResourceXMLRPC::writeTodo( Todo* todo, TQMap<TQString, TQVariant>& args )
+{
+ args.insert( "subject", todo->summary() );
+ args.insert( "des", todo->description() );
+ args.insert( "access",
+ (todo->secrecy() == Todo::SecrecyPublic ? "public" : "private" ) );
+
+ // CATEGORIES
+ TQMap<TQString, TQVariant> catMap;
+
+ const TQStringList categories = todo->categories();
+ TQStringList::ConstIterator catIt;
+ int counter = 0;
+ for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
+ TQMap<TQString, int>::Iterator it = mTodoCategoryMap.find( *catIt );
+ if ( it == mTodoCategoryMap.end() )
+ catMap.insert( TQString::number( counter-- ), *catIt );
+ else
+ catMap.insert( TQString::number( it.data() ), *catIt );
+ }
+ args.insert( "category", catMap );
+
+ args.insert( "datemodified", todo->lastModified() );
+ args.insert( "startdate", todo->dtStart() );
+ args.insert( "enddate", todo->dtDue() );
+
+ // SUBTODO
+ Incidence *inc = todo->relatedTo();
+ if ( inc ) {
+ TQString parentUid = idMapper().remoteId( inc->uid() );
+ args.insert( "id_parent", parentUid );
+ }
+
+ // STATE
+ TQString remoteId = idMapper().remoteId( todo->uid() );
+ TQString status = mTodoStateMapper.remoteState( remoteId, todo->percentComplete() );
+ args.insert( "status", status );
+}
+
+void ResourceXMLRPC::readTodo( const TQMap<TQString, TQVariant>& args, Todo *todo, TQString &uid )
+{
+ uid = args[ "id" ].toString();
+
+/*
+ info_from
+ info_addr
+ info_owner
+ info_responsible
+ info_modifier
+*/
+
+ todo->setSummary( args[ "subject" ].toString() );
+ todo->setDescription( args[ "des" ].toString() );
+ todo->setSecrecy( args[ "access" ].toString() == "public" ? Todo::SecrecyPublic : Todo::SecrecyPrivate );
+
+ // CATEGORIES
+ const TQMap<TQString, TQVariant> categories = args[ "category" ].toMap();
+ TQMap<TQString, TQVariant>::ConstIterator it;
+
+ TQStringList todoCategories;
+ for ( it = categories.begin(); it != categories.end(); ++it ) {
+ mTodoCategoryMap.insert( it.data().toString(), it.key().toInt() );
+ todoCategories.append( it.data().toString() );
+ }
+
+ todo->setCategories( todoCategories );
+
+ todo->setLastModified( args[ "datemodified" ].toDateTime() );
+
+ todo->setFloats( true );
+ TQDateTime dateTime = args[ "startdate" ].toDateTime();
+ if ( dateTime.isValid() ) {
+ todo->setDtStart( dateTime );
+ todo->setHasStartDate( true );
+ if ( !dateTime.time().isNull() )
+ todo->setFloats( false );
+ }
+
+ dateTime = args[ "enddate" ].toDateTime();
+ if ( dateTime.isValid() ) {
+ todo->setDtDue( dateTime );
+ todo->setHasDueDate( true );
+ if ( !dateTime.time().isNull() )
+ todo->setFloats( false );
+ }
+
+ // SUBTODO
+ TQString parentId = args[ "id_parent" ].toString();
+ if ( parentId != "0" ) { // we are a sub todo
+ TQString localParentUid = idMapper().localId( parentId );
+ if ( !localParentUid.isEmpty() ) { // found parent todo
+ Todo *parent = mCalendar.todo( localParentUid );
+ if ( parent )
+ todo->setRelatedTo( parent );
+ }
+ }
+
+ // STATE
+ TQString status = args[ "status" ].toString();
+ int state = TodoStateMapper::toLocal( status );
+
+ mTodoStateMapper.addTodoState( uid, state, status );
+ todo->setPercentComplete( state );
+
+ int rights = args[ "rights" ].toInt();
+ todo->setReadOnly( !(rights & EGW_ACCESS_EDIT) );
+ setRights( todo, rights );
+}
+
+void ResourceXMLRPC::checkLoadingFinished()
+{
+ mLoaded++;
+ if ( mLoaded == 4 ) {
+ mLoaded = 0;
+ emit resourceLoaded( this );
+ }
+}
+
+#include "kcal_resourcexmlrpc.moc"
diff --git a/tderesources/egroupware/kcal_resourcexmlrpc.h b/tderesources/egroupware/kcal_resourcexmlrpc.h
new file mode 100644
index 000000000..5253babaa
--- /dev/null
+++ b/tderesources/egroupware/kcal_resourcexmlrpc.h
@@ -0,0 +1,237 @@
+ /*
+ This file is part of tdepim.
+
+ Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KCAL_RESOURCEXMLRPC_H
+#define KCAL_RESOURCEXMLRPC_H
+
+#include <tqdatetime.h>
+#include <tqptrlist.h>
+#include <tqstring.h>
+
+#include <kconfig.h>
+#include <kurl.h>
+
+#include <tdepimmacros.h>
+
+#include "libkcal/calendarlocal.h"
+#include "libkcal/incidence.h"
+#include "libkcal/resourcecached.h"
+#include "todostatemapper.h"
+
+namespace KXMLRPC {
+class Server;
+}
+
+class Synchronizer;
+class TQTimer;
+
+namespace KCal {
+
+class EGroupwarePrefs;
+
+/**
+ This class provides access to php/eGroupware calendar via XML-RPC.
+*/
+class KDE_EXPORT ResourceXMLRPC : public ResourceCached
+{
+ Q_OBJECT
+
+
+ public:
+ ResourceXMLRPC( const TDEConfig* );
+ ResourceXMLRPC();
+ virtual ~ResourceXMLRPC();
+
+ void readConfig( const TDEConfig* config );
+ void writeConfig( TDEConfig* config );
+
+ EGroupwarePrefs *prefs() const { return mPrefs; }
+
+ bool isSaving();
+
+ KABC::Lock *lock();
+
+ /**
+ Add Event to calendar.
+ */
+ bool addEvent( Event* event );
+
+ /**
+ Deletes an event from this calendar.
+ */
+ bool deleteEvent( Event* );
+
+ /**
+ Retrieves an event on the basis of the unique string ID.
+ */
+ Event *event( const TQString& uid );
+
+ /**
+ Return unfiltered list of all events in calendar.
+ */
+ Event::List rawEvents();
+
+ /**
+ Builds and then returns a list of all events that match for the
+ date specified. useful for dayView, etc. etc.
+ */
+ Event::List rawEventsForDate(
+ const TQDate& date,
+ EventSortField sortField=EventSortUnsorted,
+ SortDirection sortDirection=SortDirectionAscending );
+
+ /**
+ Get unfiltered events for date \a qdt.
+ */
+ Event::List rawEventsForDate( const TQDateTime& qdt );
+
+ /**
+ Get unfiltered events in a range of dates. If inclusive is set to true,
+ only events are returned, which are completely included in the range.
+ */
+ Event::List rawEvents( const TQDate& start, const TQDate& end,
+ bool inclusive = false );
+
+
+ /**
+ Add a todo to the todolist.
+ */
+ bool addTodo( Todo* todo );
+
+ /**
+ Remove a todo from the todolist.
+ */
+ bool deleteTodo( Todo* todo );
+
+ /**
+ Searches todolist for an event with this unique string identifier,
+ returns a pointer or null.
+ */
+ Todo *todo( const TQString& uid );
+
+ /**
+ Return list of all todos.
+ */
+ Todo::List rawTodos();
+
+ /**
+ Returns list of todos due on the specified date.
+ */
+ Todo::List rawTodosForDate( const TQDate& date );
+
+ /**
+ Add a Journal entry to calendar
+ */
+ virtual bool addJournal( Journal* journal );
+
+ /**
+ Remove journal from the calendar.
+ */
+ bool deleteJournal( Journal* journal );
+
+ /**
+ Return Journals for given date
+ */
+ virtual Journal::List journals( const TQDate& );
+
+ /**
+ Return Journal with given UID
+ */
+ virtual Journal *journal( const TQString& uid );
+
+ /**
+ Return all alarms, which ocur in the given time interval.
+ */
+ Alarm::List alarms( const TQDateTime& from, const TQDateTime& to );
+
+ /**
+ Return all alarms, which ocur before given date.
+ */
+ Alarm::List alarmsTo( const TQDateTime& to );
+
+ /**
+ Public because needed in MultiCalendar::load()
+ */
+ bool doOpen();
+ void doClose();
+
+ void dump() const;
+
+ void setTimeZoneId( const TQString& ) {}
+
+ protected slots:
+ void loginFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void logoutFinished( const TQValueList<TQVariant>&, const TQVariant& );
+
+ void listEventsFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void addEventFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void updateEventFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void deleteEventFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void loadEventCategoriesFinished( const TQValueList<TQVariant>&, const TQVariant& );
+
+ void listTodosFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void addTodoFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void updateTodoFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void deleteTodoFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void loadTodoCategoriesFinished( const TQValueList<TQVariant>&, const TQVariant& );
+
+ void fault( int, const TQString&, const TQVariant& );
+
+ protected:
+ bool doLoad();
+ bool doSave();
+
+ private slots:
+ void reload();
+
+ private:
+ void init();
+ void initEGroupware();
+
+ void writeEvent( Event*, TQMap<TQString, TQVariant>& );
+ void readEvent( const TQMap<TQString, TQVariant>&, Event*, TQString& );
+
+ void writeTodo( Todo*, TQMap<TQString, TQVariant>& );
+ void readTodo( const TQMap<TQString, TQVariant>&, Todo*, TQString& );
+
+ void checkLoadingFinished();
+
+ KXMLRPC::Server *mServer;
+
+ EGroupwarePrefs *mPrefs;
+
+ TQString mSessionID;
+ TQString mKp3;
+
+ TQMap<TQString, int> mEventCategoryMap;
+ TQMap<TQString, int> mTodoCategoryMap;
+
+ TodoStateMapper mTodoStateMapper;
+
+ Synchronizer *mSynchronizer;
+
+ KABC::Lock *mLock;
+ int mLoaded;
+};
+
+}
+
+#endif
diff --git a/tderesources/egroupware/kcal_resourcexmlrpcconfig.cpp b/tderesources/egroupware/kcal_resourcexmlrpcconfig.cpp
new file mode 100644
index 000000000..213da26e3
--- /dev/null
+++ b/tderesources/egroupware/kcal_resourcexmlrpcconfig.cpp
@@ -0,0 +1,98 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <tqlabel.h>
+#include <tqlayout.h>
+
+#include <kdebug.h>
+#include <kdialog.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <knuminput.h>
+#include <kurlrequester.h>
+
+#include "kcal_egroupwareprefs.h"
+#include "kcal_resourcexmlrpc.h"
+#include "kcal_resourcexmlrpcconfig.h"
+
+using namespace KCal;
+
+ResourceXMLRPCConfig::ResourceXMLRPCConfig( TQWidget* parent, const char* name )
+ : KRES::ConfigWidget( parent, name )
+{
+ TQGridLayout *mainLayout = new TQGridLayout( this, 4, 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( "Domain:" ), this );
+ mDomain = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mDomain, 1, 1 );
+
+ label = new TQLabel( i18n( "User:" ), this );
+ mUser = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 2, 0 );
+ mainLayout->addWidget( mUser, 2, 1 );
+
+ label = new TQLabel( i18n( "Password:" ), this );
+ mPassword = new KLineEdit( this );
+ mPassword->setEchoMode( TQLineEdit::Password );
+
+ mainLayout->addWidget( label, 3, 0 );
+ mainLayout->addWidget( mPassword, 3, 1 );
+}
+
+void ResourceXMLRPCConfig::loadSettings( KRES::Resource *res )
+{
+ ResourceXMLRPC *resource = dynamic_cast<ResourceXMLRPC*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceXMLRPCConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ mURL->setURL( resource->prefs()->url() );
+ mDomain->setText( resource->prefs()->domain() );
+ mUser->setText( resource->prefs()->user() );
+ mPassword->setText( resource->prefs()->password() );
+}
+
+void ResourceXMLRPCConfig::saveSettings( KRES::Resource *res )
+{
+ ResourceXMLRPC *resource = dynamic_cast<ResourceXMLRPC*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceXMLRPCConfig::saveSettings(): cast failed" << endl;
+ return;
+ }
+
+ resource->prefs()->setUrl( mURL->url() );
+ resource->prefs()->setDomain( mDomain->text() );
+ resource->prefs()->setUser( mUser->text() );
+ resource->prefs()->setPassword( mPassword->text() );
+}
+
+#include "kcal_resourcexmlrpcconfig.moc"
diff --git a/tderesources/egroupware/kcal_resourcexmlrpcconfig.h b/tderesources/egroupware/kcal_resourcexmlrpcconfig.h
new file mode 100644
index 000000000..2790717fb
--- /dev/null
+++ b/tderesources/egroupware/kcal_resourcexmlrpcconfig.h
@@ -0,0 +1,54 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCEXMLRPCCONFIG_H
+#define RESOURCEXMLRPCCONFIG_H
+
+#include <tderesources/configwidget.h>
+#include <tdepimmacros.h>
+
+class KIntSpinBox;
+class KLineEdit;
+class KURLRequester;
+
+namespace KCal {
+
+class KDE_EXPORT ResourceXMLRPCConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+
+ public:
+ ResourceXMLRPCConfig( TQWidget* parent = 0, const char* name = 0 );
+
+ public slots:
+ void loadSettings( KRES::Resource* );
+ void saveSettings( KRES::Resource* );
+
+ private:
+ KURLRequester *mURL;
+ KLineEdit *mDomain;
+ KLineEdit *mUser;
+ KLineEdit *mPassword;
+};
+
+}
+
+#endif
diff --git a/tderesources/egroupware/kcal_resourcexmlrpcplugin.cpp b/tderesources/egroupware/kcal_resourcexmlrpcplugin.cpp
new file mode 100644
index 000000000..021389b61
--- /dev/null
+++ b/tderesources/egroupware/kcal_resourcexmlrpcplugin.cpp
@@ -0,0 +1,40 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kcal_resourcexmlrpc.h"
+#include "kcal_resourcexmlrpcconfig.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+
+using namespace KCal;
+
+typedef KRES::PluginFactory<ResourceXMLRPC, ResourceXMLRPCConfig> XMLRPCFactory;
+
+// FIXME: Use K_EXPORT_COMPONENT_FACTORY( kcal_xmlrpc, XMLRPCFactory ); here
+// Problem: How to insert the catalogue!
+extern "C"
+{
+ void *init_kcal_xmlrpc()
+ {
+ TDEGlobal::locale()->insertCatalogue( "kres_xmlrpc" );
+ return new XMLRPCFactory;
+ }
+}
diff --git a/tderesources/egroupware/kcal_xmlrpc.desktop b/tderesources/egroupware/kcal_xmlrpc.desktop
new file mode 100644
index 000000000..4a6134e5d
--- /dev/null
+++ b/tderesources/egroupware/kcal_xmlrpc.desktop
@@ -0,0 +1,50 @@
+[Desktop Entry]
+Name=eGroupware Server (via XML-RPC)
+Name[af]=eGroupware Bediener (via XML-RPC)
+Name[bg]=Сървър eGroupware (чрез XML-RPC)
+Name[br]=Servijer eGroupware (gant XML-RPC)
+Name[ca]=Servidor eGroupware (via XML-RPC)
+Name[cs]=eGroupware Server (přes XML-RPC)
+Name[da]=eGroupware server (via XML-RPC)
+Name[el]=Εξυπηρετητής eGroupware (μέσω XML-RPC)
+Name[es]=Servidor de eGroupware (por medio de XML-RPC)
+Name[et]=eGroupware server (XML-RPC vahendusel)
+Name[eu]=eGroupware zerbitzaria (XML-RPC bidez)
+Name[fa]=کارساز eGroupware (از طریق XML-RPC)
+Name[fi]=eGroupware-palvelin (XML-RPC kautta)
+Name[fr]=Serveur eGroupware (via XML-RPC)
+Name[fy]=eGroupware-tsjinner (fia XML-RPC)
+Name[ga]=Freastalaí eGroupware (via XML-RPC)
+Name[gl]=Servidor eGroupware (mediante XML-RPC)
+Name[hu]=eGroupware-kiszolgáló (XML-RPC-n keresztül)
+Name[is]=eGroupware þjónn (gegnum XML-RPC)
+Name[it]=Server eGroupware (via XML-RPC)
+Name[ja]=eGroupware サーバ (XML-RPC 経由)
+Name[kk]=eGroupware сервері (XML-RPC арқылы)
+Name[km]=ម៉ាស៊ីន​បម្រើ eGroupware (តាម​រយៈ XML-RPC)
+Name[lt]=eGroupware serveris (per XML-RPC)
+Name[ms]=Pelayan eGroupware (melalui XML-RPC)
+Name[nb]=eGroupware-tjener (via XML-RPPC)
+Name[nds]=eGroupware-Server (över XML-RPC)
+Name[ne]=(XML-RPC मार्फत) eGroupware सर्भर
+Name[nl]=eGroupware-server (via XML-RPC)
+Name[nn]=eGroupware-tenar (via XML-RPC)
+Name[pl]=Serwer eGroupware (poprzez XML-RPC)
+Name[pt]=Servidor eGroupware (via XML-RPC)
+Name[pt_BR]=Servidor eGroupware (via XML-RPC)
+Name[ru]=Сервер eGroupware (через XML-RPC)
+Name[sk]=eGroupware Server (cez XML-RPC)
+Name[sl]=Strežnik eGroupware (preko XML-RPC)
+Name[sr]=eGroupware сервер (преко XML-RPC)
+Name[sr@Latn]=eGroupware server (preko XML-RPC)
+Name[sv]=eGroupware-server (via XML-RPC)
+Name[ta]=eGroupware சேவகன் (via XML-RPC)
+Name[tr]=eGroupware Sunucusu (XML-RPC ile)
+Name[uk]=Сервер eGroupware (через XML-RPC)
+Name[zh_CN]=eGroupware 服务器(通过 XML-RPC)
+Name[zh_TW]=eGroupware 伺服器(透過 XML-RPC)
+X-TDE-Library=kcal_xmlrpc
+Type=Service
+ServiceTypes=KResources/Plugin
+X-TDE-ResourceFamily=calendar
+X-TDE-ResourceType=xmlrpc
diff --git a/tderesources/egroupware/knotes_egroupwareprefs.kcfgc b/tderesources/egroupware/knotes_egroupwareprefs.kcfgc
new file mode 100644
index 000000000..6c3fbdffe
--- /dev/null
+++ b/tderesources/egroupware/knotes_egroupwareprefs.kcfgc
@@ -0,0 +1,11 @@
+# Code generation options for kconfig_compiler
+File=tderesources_knotes_egroupware.kcfg
+ClassName=EGroupwarePrefs
+NameSpace=KNotes
+Singleton=false
+Mutators=true
+Inherits=KResourcePrefs
+IncludeFiles=libtdepim/kresourceprefs.h
+GlobalEnums=true
+#ItemAccessors=true
+#SetUserTexts=true
diff --git a/tderesources/egroupware/knotes_resourcexmlrpc.cpp b/tderesources/egroupware/knotes_resourcexmlrpc.cpp
new file mode 100644
index 000000000..1b19831bc
--- /dev/null
+++ b/tderesources/egroupware/knotes_resourcexmlrpc.cpp
@@ -0,0 +1,336 @@
+/*
+ This file is part of tdepim.
+
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <tqapplication.h>
+#include <tqstringlist.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kstringhandler.h>
+#include <kurl.h>
+
+#include "libkcal/journal.h"
+
+#include "knotes/resourcemanager.h"
+
+#include "knotes_egroupwareprefs.h"
+#include "knotes_resourcexmlrpc.h"
+#include "knotes_resourcexmlrpcconfig.h"
+
+#include "synchronizer.h"
+#include "xmlrpciface.h"
+
+using namespace KNotes;
+
+typedef KRES::PluginFactory< ResourceXMLRPC, ResourceXMLRPCConfig> XMLRPCFactory;
+K_EXPORT_COMPONENT_FACTORY( knotes_xmlrpc, XMLRPCFactory )
+
+static const TQString SearchNotesCommand = "infolog.boinfolog.search";
+static const TQString AddNoteCommand = "infolog.boinfolog.write";
+static const TQString DeleteNoteCommand = "infolog.boinfolog.delete";
+static const TQString LoadNoteCategoriesCommand = "infolog.boinfolog.categories";
+
+ResourceXMLRPC::ResourceXMLRPC( const TDEConfig* config )
+ : ResourceNotes( config ), mCalendar( TQString::fromLatin1("UTC") ),
+ mServer( 0 )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+
+ if ( config ) {
+ readConfig( config );
+ } else {
+ setResourceName( i18n( "eGroupware Server" ) );
+ }
+}
+
+ResourceXMLRPC::ResourceXMLRPC( )
+ : ResourceNotes( 0 ), mCalendar( TQString::fromLatin1("UTC") ),
+ mServer( 0 )
+{
+ init();
+
+ mPrefs->addGroupPrefix( identifier() );
+}
+
+ResourceXMLRPC::~ResourceXMLRPC()
+{
+ delete mServer;
+ mServer = 0;
+
+ delete mPrefs;
+ mPrefs = 0;
+
+ delete mSynchronizer;
+ mSynchronizer = 0;
+}
+
+void ResourceXMLRPC::init()
+{
+ setType( "xmlrpc" );
+
+ mPrefs = new EGroupwarePrefs;
+
+ mSynchronizer = new Synchronizer;
+}
+
+void ResourceXMLRPC::readConfig( const TDEConfig* )
+{
+ mPrefs->readConfig();
+}
+
+void ResourceXMLRPC::writeConfig( TDEConfig* config )
+{
+ ResourceNotes::writeConfig( config );
+
+ mPrefs->writeConfig();
+}
+
+bool ResourceXMLRPC::load()
+{
+ mCalendar.close();
+
+ if ( mServer )
+ delete mServer;
+
+ mServer = new KXMLRPC::Server( KURL(), this );
+ mServer->setUrl( KURL( mPrefs->url() ) );
+ mServer->setUserAgent( "KDE-Notes" );
+
+ TQMap<TQString, TQVariant> args, columns;
+ args.insert( "domain", mPrefs->domain() );
+ args.insert( "username", mPrefs->user() );
+ args.insert( "password", mPrefs->password() );
+
+ mServer->call( "system.login", TQVariant( args ),
+ this, TQT_SLOT( loginFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mSynchronizer->start();
+
+ columns.insert( "type", "note" );
+ args.clear();
+ args.insert( "filter", "none" );
+ args.insert( "col_filter", columns );
+ args.insert( "order", "id_parent" );
+
+ mServer->call( SearchNotesCommand, args,
+ this, TQT_SLOT( listNotesFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+
+ mSynchronizer->start();
+
+ return true;
+}
+
+bool ResourceXMLRPC::save()
+{
+ mCalendar.close();
+
+ return true;
+}
+
+bool ResourceXMLRPC::addNote( KCal::Journal *journal )
+{
+ TQMap<TQString, TQVariant> args;
+ writeNote( journal, args );
+
+ KCal::Journal *oldJournal = mCalendar.journal( journal->uid() );
+
+ bool added = false;
+ if ( oldJournal ) {
+ if ( !oldJournal->isReadOnly() ) {
+ writeNote( journal, args );
+ args.insert( "id", mUidMap[ journal->uid() ].toInt() );
+ mServer->call( AddNoteCommand, TQVariant( args ),
+ this, TQT_SLOT( updateNoteFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ) );
+ mCalendar.addJournal( journal );
+ added = true;
+ }
+ } else {
+ mServer->call( AddNoteCommand, TQVariant( args ),
+ this, TQT_SLOT( addNoteFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( journal->uid() ) );
+
+ mCalendar.addJournal( journal );
+ added = true;
+ }
+
+ if ( added )
+ mSynchronizer->start();
+
+ return true;
+}
+
+bool ResourceXMLRPC::deleteNote( KCal::Journal *journal )
+{
+ int id = mUidMap[ journal->uid() ].toInt();
+
+ mServer->call( DeleteNoteCommand, id,
+ this, TQT_SLOT( deleteNoteFinished( const TQValueList<TQVariant>&, const TQVariant& ) ),
+ this, TQT_SLOT( fault( int, const TQString&, const TQVariant& ) ),
+ TQVariant( journal->uid() ) );
+ mSynchronizer->start();
+
+ return true;
+}
+
+KCal::Alarm::List ResourceXMLRPC::alarms( const TQDateTime& from, const TQDateTime& to )
+{
+ KCal::Alarm::List alarms;
+ KCal::Journal::List notes = mCalendar.journals();
+ KCal::Journal::List::ConstIterator note;
+ for ( note = notes.begin(); note != notes.end(); ++note )
+ {
+ TQDateTime preTime = from.addSecs( -1 );
+ KCal::Alarm::List::ConstIterator it;
+ for( it = (*note)->alarms().begin(); it != (*note)->alarms().end(); ++it )
+ {
+ if ( (*it)->enabled() )
+ {
+ TQDateTime dt = (*it)->nextRepetition( preTime );
+ if ( dt.isValid() && dt <= to )
+ alarms.append( *it );
+ }
+ }
+ }
+
+ return alarms;
+}
+
+void ResourceXMLRPC::loginFinished( const TQValueList<TQVariant>& variant,
+ const TQVariant& )
+{
+ TQMap<TQString, TQVariant> map = variant[ 0 ].toMap();
+
+ KURL url = KURL( mPrefs->url() );
+ if ( map[ "GOAWAY" ].toString() == "XOXO" ) { // failed
+ mSessionID = mKp3 = "";
+ } else {
+ mSessionID = map[ "sessionid" ].toString();
+ mKp3 = map[ "kp3" ].toString();
+ }
+
+ url.setUser( mSessionID );
+ url.setPass( mKp3 );
+ mServer->setUrl( url );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::logoutFinished( const TQValueList<TQVariant>& variant,
+ const TQVariant& )
+{
+ TQMap<TQString, TQVariant> map = variant[ 0 ].toMap();
+
+ if ( map[ "GOODBYE" ].toString() != "XOXO" )
+ kdError() << "logout failed" << endl;
+
+ KURL url = KURL( mPrefs->url() );
+ mSessionID = mKp3 = "";
+ url.setUser( mSessionID );
+ url.setPass( mKp3 );
+ mServer->setUrl( url );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::listNotesFinished( const TQValueList<TQVariant> &list, const TQVariant& )
+{
+ TQMap<TQString, TQString>::Iterator uidIt;
+ for ( uidIt = mUidMap.begin(); uidIt != mUidMap.end(); ++uidIt ) {
+ KCal::Journal *journal = mCalendar.journal( uidIt.key() );
+ mCalendar.deleteJournal( journal );
+ }
+
+ mUidMap.clear();
+
+ TQValueList<TQVariant> noteList = list[ 0 ].toList();
+ TQValueList<TQVariant>::Iterator noteIt;
+
+ for ( noteIt = noteList.begin(); noteIt != noteList.end(); ++noteIt ) {
+ TQMap<TQString, TQVariant> map = (*noteIt).toMap();
+
+ KCal::Journal *journal = new KCal::Journal();
+
+ TQString uid;
+ readNote( map, journal, uid );
+ mUidMap.insert( journal->uid(), uid );
+
+ mCalendar.addJournal( journal );
+ manager()->registerNote( this, journal );
+ }
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::addNoteFinished( const TQValueList<TQVariant> &list, const TQVariant &id )
+{
+ int uid = list[ 0 ].toInt();
+ mUidMap.insert( id.toString(), TQString::number( uid ) );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::updateNoteFinished( const TQValueList<TQVariant>&, const TQVariant& )
+{
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::deleteNoteFinished( const TQValueList<TQVariant>&, const TQVariant &id )
+{
+ mUidMap.erase( id.toString() );
+
+ KCal::Journal *journal = mCalendar.journal( id.toString() );
+ mCalendar.deleteJournal( journal );
+
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::fault( int error, const TQString& errorMsg, const TQVariant& )
+{
+ kdError() << "Server send error " << error << ": " << errorMsg << endl;
+ mSynchronizer->stop();
+}
+
+void ResourceXMLRPC::writeNote( KCal::Journal* journal, TQMap<TQString, TQVariant>& args )
+{
+ args.insert( "subject", journal->summary() );
+ args.insert( "des", journal->description() );
+ args.insert( "access",
+ (journal->secrecy() == KCal::Journal::SecrecyPublic ? "public" : "private" ) );
+}
+
+void ResourceXMLRPC::readNote( const TQMap<TQString, TQVariant>& args, KCal::Journal *journal, TQString &uid )
+{
+ uid = args[ "id" ].toString();
+
+ journal->setSummary( args[ "subject" ].toString() );
+ journal->setDescription( args[ "des" ].toString() );
+ journal->setSecrecy( args[ "access" ].toString() == "public" ?
+ KCal::Journal::SecrecyPublic : KCal::Journal::SecrecyPrivate );
+}
+
+#include "knotes_resourcexmlrpc.moc"
diff --git a/tderesources/egroupware/knotes_resourcexmlrpc.h b/tderesources/egroupware/knotes_resourcexmlrpc.h
new file mode 100644
index 000000000..df8a4dd36
--- /dev/null
+++ b/tderesources/egroupware/knotes_resourcexmlrpc.h
@@ -0,0 +1,104 @@
+ /*
+ This file is part of tdepim.
+
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KNOTES_RESOURCEXMLRPC_H
+#define KNOTES_RESOURCEXMLRPC_H
+
+#include <tqptrlist.h>
+#include <tqstring.h>
+
+#include <kconfig.h>
+#include <kurl.h>
+#include <tdepimmacros.h>
+
+#include "libkcal/calendarlocal.h"
+#include "libkcal/journal.h"
+#include "knotes/resourcenotes.h"
+
+namespace KXMLRPC {
+class Server;
+}
+
+class Synchronizer;
+
+namespace KNotes {
+
+class EGroupwarePrefs;
+
+/**
+ This class provides access to eGroupware notes via XML-RPC.
+*/
+class KDE_EXPORT ResourceXMLRPC : public ResourceNotes
+{
+ Q_OBJECT
+
+
+ public:
+ ResourceXMLRPC( const TDEConfig* );
+ ResourceXMLRPC();
+ virtual ~ResourceXMLRPC();
+
+ void readConfig( const TDEConfig* config );
+ void writeConfig( TDEConfig* config );
+
+ EGroupwarePrefs *prefs() const { return mPrefs; }
+
+ bool load();
+ bool save();
+
+ bool addNote( KCal::Journal* );
+ bool deleteNote( KCal::Journal* );
+
+ KCal::Alarm::List alarms( const TQDateTime& from, const TQDateTime& to );
+
+ protected slots:
+ void loginFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void logoutFinished( const TQValueList<TQVariant>&, const TQVariant& );
+
+ void listNotesFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void addNoteFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void updateNoteFinished( const TQValueList<TQVariant>&, const TQVariant& );
+ void deleteNoteFinished( const TQValueList<TQVariant>&, const TQVariant& );
+
+ void fault( int, const TQString&, const TQVariant& );
+
+ private:
+ void init();
+ void initEGroupware();
+
+ void writeNote( KCal::Journal*, TQMap<TQString, TQVariant>& );
+ void readNote( const TQMap<TQString, TQVariant>&, KCal::Journal*, TQString& );
+
+ KCal::CalendarLocal mCalendar;
+ KXMLRPC::Server *mServer;
+
+ EGroupwarePrefs *mPrefs;
+
+ TQString mSessionID;
+ TQString mKp3;
+ TQMap<TQString, TQString> mUidMap;
+
+ Synchronizer *mSynchronizer;
+};
+
+}
+
+#endif
diff --git a/tderesources/egroupware/knotes_resourcexmlrpcconfig.cpp b/tderesources/egroupware/knotes_resourcexmlrpcconfig.cpp
new file mode 100644
index 000000000..8cf2a35c8
--- /dev/null
+++ b/tderesources/egroupware/knotes_resourcexmlrpcconfig.cpp
@@ -0,0 +1,98 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <tqlabel.h>
+#include <tqlayout.h>
+
+#include <kdebug.h>
+#include <kdialog.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <knuminput.h>
+#include <kurlrequester.h>
+
+#include "knotes_egroupwareprefs.h"
+#include "knotes_resourcexmlrpc.h"
+#include "knotes_resourcexmlrpcconfig.h"
+
+using namespace KNotes;
+
+ResourceXMLRPCConfig::ResourceXMLRPCConfig( TQWidget* parent, const char* name )
+ : KRES::ConfigWidget( parent, name )
+{
+ TQGridLayout *mainLayout = new TQGridLayout( this, 4, 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( "Domain:" ), this );
+ mDomain = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mDomain, 1, 1 );
+
+ label = new TQLabel( i18n( "User:" ), this );
+ mUser = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 2, 0 );
+ mainLayout->addWidget( mUser, 2, 1 );
+
+ label = new TQLabel( i18n( "Password:" ), this );
+ mPassword = new KLineEdit( this );
+ mPassword->setEchoMode( TQLineEdit::Password );
+
+ mainLayout->addWidget( label, 3, 0 );
+ mainLayout->addWidget( mPassword, 3, 1 );
+}
+
+void ResourceXMLRPCConfig::loadSettings( KRES::Resource *res )
+{
+ ResourceXMLRPC *resource = dynamic_cast<ResourceXMLRPC*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceXMLRPCConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ mURL->setURL( resource->prefs()->url() );
+ mDomain->setText( resource->prefs()->domain() );
+ mUser->setText( resource->prefs()->user() );
+ mPassword->setText( resource->prefs()->password() );
+}
+
+void ResourceXMLRPCConfig::saveSettings( KRES::Resource *res )
+{
+ ResourceXMLRPC *resource = dynamic_cast<ResourceXMLRPC*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceXMLRPCConfig::saveSettings(): cast failed" << endl;
+ return;
+ }
+
+ resource->prefs()->setUrl( mURL->url() );
+ resource->prefs()->setDomain( mDomain->text() );
+ resource->prefs()->setUser( mUser->text() );
+ resource->prefs()->setPassword( mPassword->text() );
+}
+
+#include "knotes_resourcexmlrpcconfig.moc"
diff --git a/tderesources/egroupware/knotes_resourcexmlrpcconfig.h b/tderesources/egroupware/knotes_resourcexmlrpcconfig.h
new file mode 100644
index 000000000..e087dbe2b
--- /dev/null
+++ b/tderesources/egroupware/knotes_resourcexmlrpcconfig.h
@@ -0,0 +1,54 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCEXMLRPCCONFIG_H
+#define RESOURCEXMLRPCCONFIG_H
+
+#include <tderesources/configwidget.h>
+#include <tdepimmacros.h>
+
+class KIntSpinBox;
+class KLineEdit;
+class KURLRequester;
+
+namespace KNotes {
+
+class KDE_EXPORT ResourceXMLRPCConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+
+ public:
+ ResourceXMLRPCConfig( TQWidget* parent = 0, const char* name = 0 );
+
+ public slots:
+ void loadSettings( KRES::Resource* );
+ void saveSettings( KRES::Resource* );
+
+ private:
+ KURLRequester *mURL;
+ KLineEdit *mDomain;
+ KLineEdit *mUser;
+ KLineEdit *mPassword;
+};
+
+}
+
+#endif
diff --git a/tderesources/egroupware/knotes_resourcexmlrpcplugin.cpp b/tderesources/egroupware/knotes_resourcexmlrpcplugin.cpp
new file mode 100644
index 000000000..276cb6b0f
--- /dev/null
+++ b/tderesources/egroupware/knotes_resourcexmlrpcplugin.cpp
@@ -0,0 +1,40 @@
+/*
+ This file is part of tdepim.
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "knotes_resourcexmlrpc.h"
+#include "knotes_resourcexmlrpcconfig.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+
+using namespace KNotes;
+
+typedef KRES::PluginFactory<ResourceXMLRPC, ResourceXMLRPCConfig> XMLRPCFactory;
+
+// FIXME: Use K_EXPORT_COMPONENT_FACTORY( knotes_xmlrpc, XMLRPCFactory ); here
+// Problem: How to insert the catalogue!
+extern "C"
+{
+ void *init_knotes_xmlrpc()
+ {
+ TDEGlobal::locale()->insertCatalogue( "kres_xmlrpc" );
+ return new XMLRPCFactory;
+ }
+}
diff --git a/tderesources/egroupware/knotes_xmlrpc.desktop b/tderesources/egroupware/knotes_xmlrpc.desktop
new file mode 100644
index 000000000..93d5e4713
--- /dev/null
+++ b/tderesources/egroupware/knotes_xmlrpc.desktop
@@ -0,0 +1,50 @@
+[Desktop Entry]
+Name=eGroupware Server (via XML-RPC)
+Name[af]=eGroupware Bediener (via XML-RPC)
+Name[bg]=Сървър eGroupware (чрез XML-RPC)
+Name[br]=Servijer eGroupware (gant XML-RPC)
+Name[ca]=Servidor eGroupware (via XML-RPC)
+Name[cs]=eGroupware Server (přes XML-RPC)
+Name[da]=eGroupware server (via XML-RPC)
+Name[el]=Εξυπηρετητής eGroupware (μέσω XML-RPC)
+Name[es]=Servidor de eGroupware (por medio de XML-RPC)
+Name[et]=eGroupware server (XML-RPC vahendusel)
+Name[eu]=eGroupware zerbitzaria (XML-RPC bidez)
+Name[fa]=کارساز eGroupware (از طریق XML-RPC)
+Name[fi]=eGroupware-palvelin (XML-RPC kautta)
+Name[fr]=Serveur eGroupware (via XML-RPC)
+Name[fy]=eGroupware-tsjinner (fia XML-RPC)
+Name[ga]=Freastalaí eGroupware (via XML-RPC)
+Name[gl]=Servidor eGroupware (mediante XML-RPC)
+Name[hu]=eGroupware-kiszolgáló (XML-RPC-n keresztül)
+Name[is]=eGroupware þjónn (gegnum XML-RPC)
+Name[it]=Server eGroupware (via XML-RPC)
+Name[ja]=eGroupware サーバ (XML-RPC 経由)
+Name[kk]=eGroupware сервері (XML-RPC арқылы)
+Name[km]=ម៉ាស៊ីន​បម្រើ eGroupware (តាម​រយៈ XML-RPC)
+Name[lt]=eGroupware serveris (per XML-RPC)
+Name[ms]=Pelayan eGroupware (melalui XML-RPC)
+Name[nb]=eGroupware-tjener (via XML-RPPC)
+Name[nds]=eGroupware-Server (över XML-RPC)
+Name[ne]=(XML-RPC मार्फत) eGroupware सर्भर
+Name[nl]=eGroupware-server (via XML-RPC)
+Name[nn]=eGroupware-tenar (via XML-RPC)
+Name[pl]=Serwer eGroupware (poprzez XML-RPC)
+Name[pt]=Servidor eGroupware (via XML-RPC)
+Name[pt_BR]=Servidor eGroupware (via XML-RPC)
+Name[ru]=Сервер eGroupware (через XML-RPC)
+Name[sk]=eGroupware Server (cez XML-RPC)
+Name[sl]=Strežnik eGroupware (preko XML-RPC)
+Name[sr]=eGroupware сервер (преко XML-RPC)
+Name[sr@Latn]=eGroupware server (preko XML-RPC)
+Name[sv]=eGroupware-server (via XML-RPC)
+Name[ta]=eGroupware சேவகன் (via XML-RPC)
+Name[tr]=eGroupware Sunucusu (XML-RPC ile)
+Name[uk]=Сервер eGroupware (через XML-RPC)
+Name[zh_CN]=eGroupware 服务器(通过 XML-RPC)
+Name[zh_TW]=eGroupware 伺服器(透過 XML-RPC)
+X-TDE-Library=knotes_xmlrpc
+Type=Service
+ServiceTypes=KResources/Plugin
+X-TDE-ResourceFamily=notes
+X-TDE-ResourceType=xmlrpc
diff --git a/tderesources/egroupware/synchronizer.cpp b/tderesources/egroupware/synchronizer.cpp
new file mode 100644
index 000000000..8152828cb
--- /dev/null
+++ b/tderesources/egroupware/synchronizer.cpp
@@ -0,0 +1,50 @@
+/*
+ This file is part of tdepim.
+
+ Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <kapplication.h>
+#include <tqeventloop.h>
+
+#include <unistd.h>
+
+#include "synchronizer.h"
+
+Synchronizer::Synchronizer()
+ : mBlocked( false )
+{
+}
+
+void Synchronizer::start()
+{
+ mBlocked = true;
+
+ while ( mBlocked ) {
+ TQApplication::eventLoop()->processEvents( TQEventLoop::ExcludeUserInput );
+
+ // use sleep here to reduce cpu usage
+ usleep( 100 );
+ }
+}
+
+void Synchronizer::stop()
+{
+ mBlocked = false;
+}
+
diff --git a/tderesources/egroupware/synchronizer.h b/tderesources/egroupware/synchronizer.h
new file mode 100644
index 000000000..e9183bd20
--- /dev/null
+++ b/tderesources/egroupware/synchronizer.h
@@ -0,0 +1,72 @@
+/*
+ This file is part of tdepim.
+
+ Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef SYNCHRONIZER_H
+#define SYNCHRONIZER_H
+
+#include <tqobject.h>
+
+/**
+ A small helper class which blocks an asynchronous operation (e.g. a KIO request)
+ so that it can be used in a synchronous environment.
+
+ Example:
+
+ ...
+
+ Synchronizer mSynchronizer;
+
+ ...
+
+ job = TDEIO::file_copy( url, file, -1, true );
+ connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ TQT_SLOT( slotResult( TDEIO::Job * ) ) );
+
+ mSynchronizer.start(); // will block here until the slot was called
+ ...
+
+
+ void slotResult( TDEIO::Job* )
+ {
+ mSynchronizer.stop();
+ }
+ */
+class Synchronizer
+{
+ public:
+ Synchronizer();
+
+ /**
+ Blocks the execution until @ref stop() is called.
+ */
+ void start();
+
+ /**
+ Unblocks the execution.
+ */
+ void stop();
+
+ private:
+ bool mBlocked;
+};
+
+#endif
+
diff --git a/tderesources/egroupware/tderesources_kabc_egroupware.kcfg b/tderesources/egroupware/tderesources_kabc_egroupware.kcfg
new file mode 100644
index 000000000..5ada19426
--- /dev/null
+++ b/tderesources/egroupware/tderesources_kabc_egroupware.kcfg
@@ -0,0 +1,24 @@
+<?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_egroupwarerc"/>
+
+ <group name="General">
+ <entry type="String" name="Url">
+ <label>URL</label>
+ </entry>
+ <entry type="String" name="Domain">
+ <label>Domain</label>
+ <default>default</default>
+ </entry>
+ <entry type="String" name="User">
+ <label>User Name</label>
+ </entry>
+ <entry type="Password" name="Password">
+ <label>Password</label>
+ </entry>
+ </group>
+
+</kcfg>
diff --git a/tderesources/egroupware/tderesources_kcal_egroupware.kcfg b/tderesources/egroupware/tderesources_kcal_egroupware.kcfg
new file mode 100644
index 000000000..1eb8c7731
--- /dev/null
+++ b/tderesources/egroupware/tderesources_kcal_egroupware.kcfg
@@ -0,0 +1,24 @@
+<?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_egroupwarerc"/>
+
+ <group name="General">
+ <entry type="String" name="Url">
+ <label>URL</label>
+ </entry>
+ <entry type="String" name="Domain">
+ <label>Domain</label>
+ <default>default</default>
+ </entry>
+ <entry type="String" name="User">
+ <label>User Name</label>
+ </entry>
+ <entry type="Password" name="Password">
+ <label>Password</label>
+ </entry>
+ </group>
+
+</kcfg>
diff --git a/tderesources/egroupware/tderesources_knotes_egroupware.kcfg b/tderesources/egroupware/tderesources_knotes_egroupware.kcfg
new file mode 100644
index 000000000..fd3cc7b81
--- /dev/null
+++ b/tderesources/egroupware/tderesources_knotes_egroupware.kcfg
@@ -0,0 +1,24 @@
+<?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_knotes_egroupwarerc"/>
+
+ <group name="General">
+ <entry type="String" name="Url">
+ <label>URL</label>
+ </entry>
+ <entry type="String" name="Domain">
+ <label>Domain</label>
+ <default>default</default>
+ </entry>
+ <entry type="String" name="User">
+ <label>User Name</label>
+ </entry>
+ <entry type="Password" name="Password">
+ <label>Password</label>
+ </entry>
+ </group>
+
+</kcfg>
diff --git a/tderesources/egroupware/todostatemapper.cpp b/tderesources/egroupware/todostatemapper.cpp
new file mode 100644
index 000000000..531b298f5
--- /dev/null
+++ b/tderesources/egroupware/todostatemapper.cpp
@@ -0,0 +1,167 @@
+/*
+ This file is part of tdepim.
+
+ Copyright (c) 2005 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <tqdatastream.h>
+#include <tqfile.h>
+
+#include <kdebug.h>
+#include <kstandarddirs.h>
+
+#include "todostatemapper.h"
+
+TQDataStream& operator<<( TQDataStream &stream, const TodoStateMapper::TodoStateMapEntry &entry )
+{
+ stream << entry.uid << entry.localState << entry.remoteState;
+
+ return stream;
+}
+
+TQDataStream& operator>>( TQDataStream &stream, TodoStateMapper::TodoStateMapEntry &entry )
+{
+ stream >> entry.uid >> entry.localState >> entry.remoteState;
+
+ return stream;
+}
+
+TodoStateMapper::TodoStateMapper()
+{
+}
+
+TodoStateMapper::~TodoStateMapper()
+{
+}
+
+void TodoStateMapper::setPath( const TQString &path )
+{
+ mPath = path;
+}
+
+void TodoStateMapper::setIdentifier( const TQString &identifier )
+{
+ mIdentifier = identifier;
+}
+
+bool TodoStateMapper::load()
+{
+ TQFile file( filename() );
+ if ( !file.open( IO_ReadOnly ) ) {
+ kdError() << "Can't read uid map file '" << filename() << "'" << endl;
+ return false;
+ }
+
+ clear();
+
+ TQDataStream stream;
+ stream.setVersion( 6 );
+ stream.setDevice( &file );
+ stream >> mTodoStateMap;
+
+ file.close();
+
+ return true;
+}
+
+bool TodoStateMapper::save()
+{
+ TQFile file( filename() );
+ if ( !file.open( IO_WriteOnly ) ) {
+ kdError() << "Can't write uid map file '" << filename() << "'" << endl;
+ return false;
+ }
+
+ TQDataStream stream;
+ stream.setVersion( 6 );
+ stream.setDevice( &file );
+ stream << mTodoStateMap;
+
+ file.close();
+
+ return true;
+}
+
+void TodoStateMapper::clear()
+{
+ mTodoStateMap.clear();
+}
+
+void TodoStateMapper::addTodoState( const TQString &uid, int localState, const TQString &remoteState )
+{
+ TodoStateMapEntry entry;
+ entry.uid = uid;
+ entry.localState = localState;
+ entry.remoteState = remoteState;
+
+ mTodoStateMap.insert( uid, entry );
+}
+
+TQString TodoStateMapper::remoteState( const TQString &uid, int localState )
+{
+ if ( mTodoStateMap.find( uid ) == mTodoStateMap.end() )
+ kdError() << "TodoStateMapper: no entry for " << uid << " found" << endl;
+
+ TodoStateMapEntry entry = mTodoStateMap[ uid ];
+ if ( entry.localState == localState )
+ return entry.remoteState;
+ else
+ return toRemote( localState );
+}
+
+void TodoStateMapper::remove( const TQString &uid )
+{
+ mTodoStateMap.remove( uid );
+}
+
+int TodoStateMapper::toLocal( const TQString &remoteState )
+{
+ if ( remoteState == "offer" )
+ return 0;
+ else if ( remoteState == "ongoing" )
+ return 50;
+ else if ( remoteState == "done" || remoteState == "billed" )
+ return 100;
+ else {
+ TQString number( remoteState );
+ number.replace( "%", "" );
+ return number.toInt();
+ }
+}
+
+TQString TodoStateMapper::toRemote( int localState )
+{
+ if ( localState == 0 )
+ return "offer";
+ else if ( localState == 50 )
+ return "ongoing";
+ else if ( localState == 100 )
+ return "done";
+ else
+ return TQString( "%1%" ).arg( localState );
+}
+
+TQString TodoStateMapper::filename()
+{
+ TQString file = mPath;
+ if ( !file.endsWith( "/" ) ) file += "/";
+ file += mIdentifier;
+
+ return locateLocal( "data", file );
+}
+
diff --git a/tderesources/egroupware/todostatemapper.h b/tderesources/egroupware/todostatemapper.h
new file mode 100644
index 000000000..fb82b4786
--- /dev/null
+++ b/tderesources/egroupware/todostatemapper.h
@@ -0,0 +1,75 @@
+/*
+ This file is part of tdepim.
+
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef TODOSTATEMAPPER_H
+#define TODOSTATEMAPPER_H
+
+#include <tqdatastream.h>
+#include <tqmap.h>
+
+class TodoStateMapper
+{
+ public:
+ /**
+ Create Id mapper. You have to set path and identifier before you can call
+ load() or save().
+ */
+ TodoStateMapper();
+ ~TodoStateMapper();
+
+ void setPath( const TQString &path );
+ void setIdentifier( const TQString &identifier );
+
+ bool load();
+ bool save();
+
+ void clear();
+
+ void addTodoState( const TQString &uid, int localState, const TQString &remoteState );
+
+ TQString remoteState( const TQString &uid, int localState );
+
+ void remove( const TQString &uid );
+
+ static int toLocal( const TQString &remoteState );
+ static TQString toRemote( int localState );
+
+ protected:
+ TQString filename();
+
+ private:
+ TQString mPath;
+ TQString mIdentifier;
+
+ typedef struct {
+ TQString uid;
+ int localState;
+ TQString remoteState;
+ } TodoStateMapEntry;
+
+ typedef TQMap<TQString, TodoStateMapEntry> TodoStateMap;
+ TodoStateMap mTodoStateMap;
+
+ friend TQDataStream &operator<<( TQDataStream&, const TodoStateMapEntry& );
+ friend TQDataStream &operator>>( TQDataStream&, TodoStateMapEntry& );
+};
+
+#endif
diff --git a/tderesources/egroupware/xmlrpciface.cpp b/tderesources/egroupware/xmlrpciface.cpp
new file mode 100644
index 000000000..d43613e65
--- /dev/null
+++ b/tderesources/egroupware/xmlrpciface.cpp
@@ -0,0 +1,464 @@
+/**************************************************************************
+* Copyright (C) 2003 - 2004 by Frerich Raabe <raabe@kde.org> *
+* Tobias Koenig <tokoe@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. *
+***************************************************************************/
+
+#include <tqfile.h>
+
+#include <kdebug.h>
+#include <kio/job.h>
+#include <klocale.h>
+#include <kmdcodec.h>
+
+#include "debugdialog.h"
+#include "xmlrpciface.h"
+
+using namespace KXMLRPC;
+
+namespace KXMLRPC
+{
+ class Result
+ {
+ friend class Query;
+ public:
+ Result()
+ { }
+
+ bool success() const
+ {
+ return m_success;
+ }
+ int errorCode() const
+ {
+ return m_errorCode;
+ }
+ TQString errorString() const
+ {
+ return m_errorString;
+ }
+ TQValueList<TQVariant> data() const
+ {
+ return m_data;
+ }
+
+ private:
+ bool m_success;
+ int m_errorCode;
+ TQString m_errorString;
+ TQValueList<TQVariant> m_data;
+ };
+}
+
+Query *Query::create( const TQVariant &id, TQObject *parent, const char *name )
+{
+ return new Query( id, parent, name );
+}
+
+void Query::call( const TQString &server, const TQString &method,
+ const TQValueList<TQVariant> &args, const TQString &userAgent )
+{
+ const TQString xmlMarkup = markupCall( method, args );
+ DebugDialog::addMessage( xmlMarkup, DebugDialog::Output );
+
+ TQByteArray postData;
+ TQDataStream stream( postData, IO_WriteOnly );
+ stream.writeRawBytes( xmlMarkup.utf8(), xmlMarkup.utf8().length() );
+
+ TDEIO::TransferJob *job = TDEIO::http_post( KURL( server ), postData, false );
+ if ( !job ) {
+ kdWarning() << "Unable to create KIO job for " << server << endl;
+ return;
+ }
+ job->addMetaData( "UserAgent", userAgent );
+ job->addMetaData( "content-type", "Content-Type: text/xml; charset=utf-8" );
+ job->addMetaData( "ConnectTimeout", "50" );
+
+ connect( job, TQT_SIGNAL( data( TDEIO::Job *, const TQByteArray & ) ),
+ this, TQT_SLOT( slotData( TDEIO::Job *, const TQByteArray & ) ) );
+ connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ),
+ this, TQT_SLOT( slotResult( TDEIO::Job * ) ) );
+
+ m_pendingJobs.append( job );
+}
+
+void Query::slotData( TDEIO::Job *, const TQByteArray &data )
+{
+ unsigned int oldSize = m_buffer.size();
+ m_buffer.resize( oldSize + data.size() );
+ memcpy( m_buffer.data() + oldSize, data.data(), data.size() );
+}
+
+void Query::slotResult( TDEIO::Job *job )
+{
+ m_pendingJobs.remove( job );
+
+ if ( job->error() != 0 )
+ {
+ emit fault( job->error(), job->errorString(), m_id );
+ emit finished( this );
+ return ;
+ }
+
+ TQString data = TQString::fromUtf8( m_buffer.data(), m_buffer.size() );
+ DebugDialog::addMessage( data, DebugDialog::Input );
+
+ TQDomDocument doc;
+ TQString errMsg;
+ int errLine, errCol;
+ if ( !doc.setContent( data, false, &errMsg, &errLine, &errCol ) )
+ {
+ emit fault( -1, i18n( "Received invalid XML markup: %1 at %2:%3" )
+ .arg( errMsg ).arg( errLine ).arg( errCol ), m_id );
+ emit finished( this );
+ return ;
+ }
+
+ m_buffer.truncate( 0 );
+
+ if ( isMessageResponse( doc ) )
+ emit message( parseMessageResponse( doc ).data(), m_id );
+ else if ( isFaultResponse( doc ) )
+ {
+ emit fault( parseFaultResponse( doc ).errorCode(), parseFaultResponse( doc ).errorString(), m_id );
+ }
+ else
+ {
+ emit fault( 1, i18n( "Unknown type of XML markup received" ), m_id );
+ }
+
+ emit finished( this );
+}
+
+bool Query::isMessageResponse( const TQDomDocument &doc ) const
+{
+ return doc.documentElement().firstChild().toElement().tagName().lower() == "params";
+}
+
+Result Query::parseMessageResponse( const TQDomDocument &doc ) const
+{
+ Result response;
+ response.m_success = true;
+
+ TQDomNode paramNode = doc.documentElement().firstChild().firstChild();
+ while ( !paramNode.isNull() )
+ {
+ response.m_data << demarshal( paramNode.firstChild().toElement() );
+ paramNode = paramNode.nextSibling();
+ }
+
+ return response;
+}
+
+bool Query::isFaultResponse( const TQDomDocument &doc ) const
+{
+ return doc.documentElement().firstChild().toElement().tagName().lower() == "fault";
+}
+
+Result Query::parseFaultResponse( const TQDomDocument &doc ) const
+{
+ Result response;
+ response.m_success = false;
+
+ TQDomNode errorNode = doc.documentElement().firstChild().firstChild();
+ const TQVariant errorVariant = demarshal( errorNode.toElement() );
+ response.m_errorCode = errorVariant.toMap() [ "faultCode" ].toInt();
+ response.m_errorString = errorVariant.toMap() [ "faultString" ].toString();
+
+ return response;
+}
+
+TQString Query::markupCall( const TQString &cmd,
+ const TQValueList<TQVariant> &args ) const
+{
+ TQString markup = "<?xml version=\"1.0\" ?>\r\n<methodCall>\r\n";
+
+ markup += "<methodName>" + cmd + "</methodName>\r\n";
+
+ if ( !args.isEmpty() )
+ {
+ markup += "<params>\r\n";
+ TQValueList<TQVariant>::ConstIterator it = args.begin();
+ TQValueList<TQVariant>::ConstIterator end = args.end();
+ for ( ; it != end; ++it )
+ markup += "<param>\r\n" + marshal( *it ) + "</param>\r\n";
+ markup += "</params>\r\n";
+ }
+
+ markup += "</methodCall>\r\n";
+
+ return markup;
+}
+
+TQString Query::marshal( const TQVariant &arg ) const
+{
+ switch ( arg.type() )
+ {
+ case TQVariant::String:
+ case TQVariant::CString:
+ {
+ TQString result = arg.toString();
+ result = result.replace( "&", "&amp;" );
+ result = result.replace( "\"", "&quot;" );
+ result = result.replace( "<", "&lt;" );
+ result = result.replace( ">", "&gt;" );
+ return "<value><string>" + result + "</string></value>\r\n";
+ }
+ case TQVariant::Int:
+ return "<value><int>" + TQString::number( arg.toInt() ) + "</int></value>\r\n";
+ case TQVariant::Double:
+ return "<value><double>" + TQString::number( arg.toDouble() ) + "</double></value>\r\n";
+ case TQVariant::Bool:
+ {
+ TQString markup = "<value><boolean>";
+ markup += arg.toBool() ? "1" : "0";
+ markup += "</boolean></value>\r\n";
+ return markup;
+ }
+ case TQVariant::ByteArray:
+ return "<value><base64>" + KCodecs::base64Encode( arg.toByteArray() ) + "</base64></value>\r\n";
+ case TQVariant::DateTime:
+ return "<value><datetime.iso8601>" + arg.toDateTime().toString( Qt::ISODate ) + "</datetime.iso8601></value>\r\n";
+ case TQVariant::List:
+ {
+ TQString markup = "<value><array><data>\r\n";
+ const TQValueList<TQVariant> args = arg.toList();
+ TQValueList<TQVariant>::ConstIterator it = args.begin();
+ TQValueList<TQVariant>::ConstIterator end = args.end();
+ for ( ; it != end; ++it )
+ markup += marshal( *it );
+ markup += "</data></array></value>\r\n";
+ return markup;
+ }
+ case TQVariant::Map:
+ {
+ TQString markup = "<value><struct>\r\n";
+ TQMap<TQString, TQVariant> map = arg.toMap();
+ TQMap<TQString, TQVariant>::ConstIterator it = map.begin();
+ TQMap<TQString, TQVariant>::ConstIterator end = map.end();
+ for ( ; it != end; ++it )
+ {
+ markup += "<member>\r\n";
+ markup += "<name>" + it.key() + "</name>\r\n";
+ markup += marshal( it.data() );
+ markup += "</member>\r\n";
+ }
+ markup += "</struct></value>\r\n";
+ return markup;
+ }
+ default:
+ kdWarning() << "Failed to marshal unknown variant type: " << arg.type() << endl;
+ };
+ return TQString();
+}
+
+TQVariant Query::demarshal( const TQDomElement &elem ) const
+{
+ Q_ASSERT( elem.tagName().lower() == "value" );
+
+ const TQDomElement typeElement = elem.firstChild().toElement();
+ const TQString typeName = typeElement.tagName().lower();
+
+ if ( typeName == "string" )
+ return TQVariant( typeElement.text() );
+ else if ( typeName == "i4" || typeName == "int" )
+ return TQVariant( typeElement.text().toInt() );
+ else if ( typeName == "double" )
+ return TQVariant( typeElement.text().toDouble() );
+ else if ( typeName == "boolean" )
+ {
+ if ( typeElement.text().lower() == "true" || typeElement.text() == "1" )
+ return TQVariant( true );
+ else
+ return TQVariant( false );
+ }
+ else if ( typeName == "base64" )
+ return TQVariant( KCodecs::base64Decode( TQCString(typeElement.text().latin1()) ) );
+ else if ( typeName == "datetime" || typeName == "datetime.iso8601" )
+ return TQVariant( TQDateTime::fromString( typeElement.text(), Qt::ISODate ) );
+ else if ( typeName == "array" )
+ {
+ TQValueList<TQVariant> values;
+ TQDomNode valueNode = typeElement.firstChild().firstChild();
+ while ( !valueNode.isNull() )
+ {
+ values << demarshal( valueNode.toElement() );
+ valueNode = valueNode.nextSibling();
+ }
+ return TQVariant( values );
+ }
+ else if ( typeName == "struct" )
+ {
+ TQMap<TQString, TQVariant> map;
+ TQDomNode memberNode = typeElement.firstChild();
+ while ( !memberNode.isNull() )
+ {
+ const TQString key = memberNode.toElement().elementsByTagName( "name" ).item( 0 ).toElement().text();
+ const TQVariant data = demarshal( memberNode.toElement().elementsByTagName( "value" ).item( 0 ).toElement() );
+ map[ key ] = data;
+ memberNode = memberNode.nextSibling();
+ }
+ return TQVariant( map );
+ }
+ else
+ kdWarning() << "Cannot demarshal unknown type " << typeName << endl;
+
+ return TQVariant();
+}
+
+Query::Query( const TQVariant &id, TQObject *parent, const char *name )
+ : TQObject( parent, name ), m_id( id )
+{}
+
+Query::~Query()
+{
+ TQValueList<TDEIO::Job*>::Iterator it;
+ for ( it = m_pendingJobs.begin(); it != m_pendingJobs.end(); ++it )
+ (*it)->kill();
+}
+
+Server::Server( const KURL &url, TQObject *parent, const char *name )
+ : TQObject( parent, name )
+{
+ if ( url.isValid() )
+ m_url = url;
+
+ m_userAgent = "KDE XMLRPC resources";
+
+ DebugDialog::init();
+}
+
+Server::~Server()
+{
+ TQValueList<Query*>::Iterator it;
+ for ( it = mPendingQueries.begin(); it !=mPendingQueries.end(); ++it )
+ (*it)->deleteLater();
+
+ mPendingQueries.clear();
+}
+
+void Server::queryFinished( Query *query )
+{
+ mPendingQueries.remove( query );
+ query->deleteLater();
+}
+
+void Server::setUrl( const KURL &url )
+{
+ m_url = url.isValid() ? url : KURL();
+}
+
+void Server::call( const TQString &method, const TQValueList<TQVariant> &args,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot, const TQVariant &id )
+{
+ if ( m_url.isEmpty() )
+ kdWarning() << "Cannot execute call to " << method << ": empty server URL" << endl;
+
+ Query *query = Query::create( id, this );
+ connect( query, TQT_SIGNAL( message( const TQValueList<TQVariant> &, const TQVariant& ) ), msgObj, messageSlot );
+ connect( query, TQT_SIGNAL( fault( int, const TQString&, const TQVariant& ) ), faultObj, faultSlot );
+ connect( query, TQT_SIGNAL( finished( Query* ) ), this, TQT_SLOT( queryFinished( Query* ) ) );
+ mPendingQueries.append( query );
+
+ query->call( m_url.url(), method, args, m_userAgent );
+}
+
+void Server::call( const TQString &method, const TQVariant &arg,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ args << arg ;
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Server::call( const TQString &method, int arg,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ args << TQVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Server::call( const TQString &method, bool arg,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ args << TQVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Server::call( const TQString &method, double arg ,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ args << TQVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Server::call( const TQString &method, const TQString &arg ,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ args << TQVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Server::call( const TQString &method, const TQCString &arg,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ args << TQVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Server::call( const TQString &method, const TQByteArray &arg ,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ args << TQVariant( arg );
+ call( method, args, faultObj, faultSlot, msgObj, messageSlot, id );
+}
+
+void Server::call( const TQString &method, const TQDateTime &arg,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ args << TQVariant( arg );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+void Server::call( const TQString &method, const TQStringList &arg,
+ TQObject* msgObj, const char* messageSlot,
+ TQObject* faultObj, const char* faultSlot,
+ const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+ TQStringList::ConstIterator it = arg.begin();
+ TQStringList::ConstIterator end = arg.end();
+ for ( ; it != end; ++it )
+ args << TQVariant( *it );
+ call( method, args, msgObj, messageSlot, faultObj, faultSlot, id );
+}
+
+#include "xmlrpciface.moc"
diff --git a/tderesources/egroupware/xmlrpciface.h b/tderesources/egroupware/xmlrpciface.h
new file mode 100644
index 000000000..df2f3a6da
--- /dev/null
+++ b/tderesources/egroupware/xmlrpciface.h
@@ -0,0 +1,167 @@
+/**************************************************************************
+* Copyright (C) 2003 - 2004 by Frerich Raabe <raabe@kde.org> *
+* Tobias Koenig <tokoe@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. *
+***************************************************************************/
+#ifndef KXMLRPCIFACE_H
+#define KXMLRPCIFACE_H
+
+#include <kurl.h>
+
+#include <tqbuffer.h>
+#include <tqdom.h>
+#include <tqobject.h>
+#include <tqvariant.h>
+#include <tqvaluelist.h>
+
+namespace TDEIO
+{
+ class Job;
+}
+
+namespace KXMLRPC
+{
+ class Query;
+ class QueryResult;
+ class Server;
+ class Result;
+
+ class Query : public TQObject
+ {
+ Q_OBJECT
+
+ public:
+
+
+ static Query *create( const TQVariant &id = TQVariant(),
+ TQObject *parent = 0, const char *name = 0 );
+
+ public slots:
+ void call( const TQString &server, const TQString &method,
+ const TQValueList<TQVariant> &args = TQValueList<TQVariant>(),
+ const TQString &userAgent = "KDE-XMLRPC" );
+
+ signals:
+ void message( const TQValueList<TQVariant> &result, const TQVariant &id );
+ void fault( int, const TQString&, const TQVariant &id );
+ void finished( Query* );
+
+ private slots:
+ void slotData( TDEIO::Job *job, const TQByteArray &data );
+ void slotResult( TDEIO::Job *job );
+
+ private:
+ bool isMessageResponse( const TQDomDocument &doc ) const;
+ bool isFaultResponse( const TQDomDocument &doc ) const;
+
+ Result parseMessageResponse( const TQDomDocument &doc ) const;
+ Result parseFaultResponse( const TQDomDocument &doc ) const;
+
+ TQString markupCall( const TQString &method,
+ const TQValueList<TQVariant> &args ) const;
+ TQString marshal( const TQVariant &v ) const;
+ TQVariant demarshal( const TQDomElement &e ) const;
+
+ Query( const TQVariant &id, TQObject *parent = 0, const char *name = 0 );
+ ~Query();
+
+ TQByteArray m_buffer;
+ TQVariant m_id;
+
+ TQValueList<TDEIO::Job*> m_pendingJobs;
+ };
+
+ class Server : public TQObject
+ {
+ Q_OBJECT
+
+ public:
+ Server( const KURL &url = KURL(),
+ TQObject *parent = 0, const char *name = 0 );
+ ~Server();
+
+ const KURL &url() const { return m_url; }
+ void setUrl( const KURL &url );
+
+ TQString userAgent() const { return m_userAgent; }
+ void setUserAgent( const TQString &userAgent ) { m_userAgent = userAgent; }
+
+ template <typename T>
+ void call( const TQString &method, const TQValueList<T> &arg,
+ TQObject* obj1, const char* faultSlot,
+ TQObject* obj2, const char* messageSlot, const TQVariant &id = TQVariant() );
+
+
+ public slots:
+ void call( const TQString &method, const TQValueList<TQVariant> &args,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, const TQVariant &arg,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, int arg ,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, bool arg,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, double arg,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, const TQString &arg,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, const TQCString &arg ,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, const TQByteArray &arg,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, const TQDateTime &arg,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+ void call( const TQString &method, const TQStringList &arg,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot,
+ const TQVariant &id = TQVariant() );
+
+ private slots:
+ void queryFinished( Query* );
+
+ private:
+ KURL m_url;
+ TQString m_userAgent;
+
+ TQValueList<Query*> mPendingQueries;
+ };
+}
+
+template <typename T>
+void KXMLRPC::Server::call( const TQString &method, const TQValueList<T> &arg,
+ TQObject* faultObj, const char* faultSlot,
+ TQObject* msgObj, const char* messageSlot, const TQVariant &id )
+{
+ TQValueList<TQVariant> args;
+
+ typename TQValueList<T>::ConstIterator it = arg.begin();
+ typename TQValueList<T>::ConstIterator end = arg.end();
+ for ( ; it != end; ++it )
+ args << TQVariant( *it );
+
+ return call( method, args, faultObj, faultSlot, msgObj, messageSlot, id );
+}
+
+#endif