summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeloptes <deloptes@gmail.com>2016-09-26 21:07:55 +0200
committerPatrick Ohly <patrick.ohly@intel.com>2016-09-26 21:07:55 +0200
commitcb34f4972bcbde44b8dc702fff3a7d791a317fc0 (patch)
tree14bcdf64034300e302e1e5797646dc9e86f91419
parent8fccc44cc5dc745c90577cc50b1a5936f1cdd8be (diff)
tde, tdepim: backend for the TDE desktop (FDO #97780)
This is the code for TDE < 14.1.
-rw-r--r--src/backends/tde/TDEPlatform.cpp198
-rw-r--r--src/backends/tde/TDEPlatform.h51
-rw-r--r--src/backends/tde/TDEPlatformRegister.cpp48
-rw-r--r--src/backends/tde/configure-sub.in60
-rw-r--r--src/backends/tde/tde.am23
-rw-r--r--src/backends/tdepim/KNotesIface_stub.cpp302
-rw-r--r--src/backends/tdepim/KNotesIface_stub.h45
-rw-r--r--src/backends/tdepim/README171
-rw-r--r--src/backends/tdepim/TDEPIMAddressBookSource.cpp389
-rw-r--r--src/backends/tdepim/TDEPIMAddressBookSource.h134
-rw-r--r--src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp76
-rw-r--r--src/backends/tdepim/TDEPIMCalendarSource.cpp393
-rw-r--r--src/backends/tdepim/TDEPIMCalendarSource.h108
-rw-r--r--src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp127
-rw-r--r--src/backends/tdepim/TDEPIMNotesSource.cpp266
-rw-r--r--src/backends/tdepim/TDEPIMNotesSource.h91
-rw-r--r--src/backends/tdepim/TDEPIMNotesSourceRegister.cpp83
-rw-r--r--src/backends/tdepim/TDEPIMSyncSource.cpp76
-rw-r--r--src/backends/tdepim/TDEPIMSyncSource.h56
-rw-r--r--src/backends/tdepim/configure-sub.in144
-rw-r--r--src/backends/tdepim/tdepim.am65
21 files changed, 2906 insertions, 0 deletions
diff --git a/src/backends/tde/TDEPlatform.cpp b/src/backends/tde/TDEPlatform.cpp
new file mode 100644
index 00000000..d262f57e
--- /dev/null
+++ b/src/backends/tde/TDEPlatform.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPlatform.cpp,v 1.5 2016/09/12 19:57:42 emanoil Exp $
+ *
+ */
+
+/*
+*
+* WARNING This code is untested! It is based on theory. Feedback is welcome!
+*
+*/
+
+#include <config.h>
+
+#ifdef ENABLE_TDEWALLET
+
+#include "TDEPlatform.h"
+
+#include <syncevo/Exception.h>
+#include <syncevo/UserInterface.h>
+#include <syncevo/SyncConfig.h>
+
+#include <tdeapplication.h>
+#include <tdeaboutdata.h>
+#include <tdecmdlineargs.h>
+
+#include <tdewallet.h>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+// TODO: this check should be global
+// static bool HaveDBus;
+
+void TDEInitMainSlot(const char *appname)
+{
+
+ int argc = 1;
+ static char *argv[] = { const_cast<char *>(appname), NULL };
+
+ TDEAboutData aboutData( "syncevotdewlt", // internal program name
+ "SyncEvolution-TDEPIM-plugin", // displayable program name.
+ "0.1", // version string
+ "SyncEvolution TDEPIM plugin", // short porgram description
+ TDEAboutData::License_GPL, // license type
+ "(c) 2016, emanoil.kotsev@fincom.at" // copyright statement
+ );
+
+ TDECmdLineArgs::init(argc, argv, &aboutData);
+
+ TDEApplication syncevotdewallet( "syncevolution-tdewallet" );
+ syncevotdewlt.dcopClient()->registerAs(syncevotdewallet.name());
+
+}
+
+static bool UseTDEWallet(const InitStateTri &keyring,
+ int slotCount)
+{
+ // Disabled by user?
+ if (keyring.getValue() == InitStateTri::VALUE_FALSE) {
+ return false;
+ }
+
+ // When both (presumably) GNOME keyring and TDE Wallet are available,
+ // check if the user really wanted TDE Wallet before using TDE Wallet
+ // instead of GNOME keyring. This default favors GNOME keyring
+ // over TDE Wallet because SyncEvolution traditionally used that.
+ if (keyring.getValue() == InitStateTri::VALUE_TRUE &&
+ slotCount > 1) {
+ return false;
+ }
+
+ // If explicitly selected, it must be us.
+ if (keyring.getValue() == InitStateTri::VALUE_STRING &&
+ !boost::iequals(keyring.get(), "TDE")) {
+ return false;
+ }
+
+ // Use KWallet.
+ return true;
+}
+
+/**
+ * Here we use server sync url without protocol prefix and
+ * user account name as the key in the keyring.
+ *
+ * Also since the KWallet's API supports only storing (key,password)
+ * or Map<TQString,TQString> , the former is used.
+ */
+bool TDEWalletLoadPasswordSlot(const InitStateTri &keyring,
+ const std::string &passwordName,
+ const std::string &descr,
+ const ConfigPasswordKey &key,
+ InitStateString &password)
+{
+ if (!UseTDEWallet(keyring,
+ GetLoadPasswordSignal().num_slots() - INTERNAL_LOAD_PASSWORD_SLOTS)) {
+ SE_LOG_DEBUG(NULL, "not using TDE Wallet");
+ return false;
+ }
+
+ TQString walletPassword;
+ TQString walletKey = TQString(key.user.c_str()) + ',' +
+ TQString(key.domain.c_str())+ ','+
+ TQString(key.server.c_str())+','+
+ TQString(key.object.c_str())+','+
+ TQString(key.protocol.c_str())+','+
+ TQString(key.authtype.c_str())+','+
+ TQString::number(key.port);
+
+ TQString wallet_name = TDEWallet::Wallet::NetworkWallet();
+
+ const TQString folder("Syncevolution");
+
+ bool found = false;
+ if (!TDEWallet::Wallet::keyDoesNotExist(wallet_name, folder, walletKey)) {
+ TDEWallet::Wallet *wallet = TDEWallet::Wallet::openWallet(wallet_name, -1, TDEWallet::Wallet::Synchronous);
+ if ( wallet &&
+ wallet->setFolder(folder) &&
+ wallet->readPassword(walletKey, walletPassword) == 0 ) {
+ std::string text1(walletPassword.utf8(),walletPassword.utf8().length());
+ password = text1;
+ found = true;
+ }
+ }
+ SE_LOG_DEBUG(NULL, "%s password in KWallet using %s",
+ found ? "found" : "no",
+ key.toString().c_str());
+
+ return true;
+}
+
+
+bool TDEWalletSavePasswordSlot(const InitStateTri &keyring,
+ const std::string &passwordName,
+ const std::string &password,
+ const ConfigPasswordKey &key)
+{
+ if (!UseTDEWallet(keyring,
+ GetSavePasswordSignal().num_slots() - INTERNAL_SAVE_PASSWORD_SLOTS)) {
+ SE_LOG_DEBUG(NULL, "not using TDE Wallet");
+ return false;
+ }
+
+ /*
+ * It is possible to let CmdlineSyncClient decide which
+ * fields in ConfigPasswordKey it would use
+ * but currently only use passed key instead
+ */
+
+ // write password to keyring
+ std::string s = key.user + ',' + key.domain + ',' + key.server + ',' + key.object + ',' + key.protocol + ',' + key.authtype + ',';
+ const TQString walletKey =TQString::fromUtf8(s.data(),s.size()) + TQString::number(key.port);
+ const TQString walletPassword = TQString::fromUtf8(password.data(),password.size());
+
+ bool write_success = false;
+ const TQString wallet_name = TDEWallet::Wallet::NetworkWallet();
+ const TQString folder ("Syncevolution");
+ TDEWallet::Wallet *wallet = TDEWallet::Wallet::openWallet(wallet_name, -1,
+ TDEWallet::Wallet::Synchronous);
+ if (wallet) {
+ if (!wallet->hasFolder(folder)) {
+ wallet->createFolder(folder);
+ }
+
+ if (wallet->setFolder(folder) &&
+ wallet->writePassword(walletKey, walletPassword) == 0) {
+ write_success = true;
+ }
+ }
+
+ if (!write_success) {
+ Exception::throwError(SE_HERE, "Saving " + passwordName + " in TDE Wallet failed.");
+ }
+ SE_LOG_DEBUG(NULL, "stored password in KWallet using %s", key.toString().c_str());
+ return write_success;
+}
+
+SE_END_CXX
+
+#endif // ENABLE_TDEWALLET
diff --git a/src/backends/tde/TDEPlatform.h b/src/backends/tde/TDEPlatform.h
new file mode 100644
index 00000000..cf072ec9
--- /dev/null
+++ b/src/backends/tde/TDEPlatform.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPlatform.h,v 1.3 2016/09/01 10:41:38 emanoil Exp $
+ *
+ */
+
+#ifndef INCL_TDEPLATFORM
+#define INCL_TDEPLATFORM
+
+#include <string>
+
+#include <syncevo/util.h>
+
+#include <syncevo/declarations.h>
+
+SE_BEGIN_CXX
+
+struct ConfigPasswordKey;
+
+void TDEInitMainSlot(const char *appname);
+
+bool TDEWalletLoadPasswordSlot(const InitStateTri &keyring,
+ const std::string &passwordName,
+ const std::string &descr,
+ const ConfigPasswordKey &key,
+ InitStateString &password);
+
+bool TDEWalletSavePasswordSlot(const InitStateTri &keyring,
+ const std::string &passwordName,
+ const std::string &password,
+ const ConfigPasswordKey &key);
+SE_END_CXX
+
+#endif // INCL_TDEPLATFORM
diff --git a/src/backends/tde/TDEPlatformRegister.cpp b/src/backends/tde/TDEPlatformRegister.cpp
new file mode 100644
index 00000000..c289aebc
--- /dev/null
+++ b/src/backends/tde/TDEPlatformRegister.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPlatformRegister.cpp,v 1.4 2016/09/01 10:41:38 emanoil Exp $
+ *
+ */
+
+#include <config.h>
+
+#ifdef ENABLE_TDEWALLET
+
+#include "TDEPlatform.h"
+#include <syncevo/SyncContext.h>
+#include <syncevo/UserInterface.h>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+static class TDEInit
+{
+public:
+ TDEInit()
+ {
+ GetLoadPasswordSignal().connect(0, TDEWalletLoadPasswordSlot);
+ GetSavePasswordSignal().connect(0, TDEWalletSavePasswordSlot);
+ SyncContext::GetInitMainSignal().connect(TDEInitMainSlot);
+ }
+} tdeinit;
+
+SE_END_CXX
+
+#endif // ENABLE_TDEWALLET
diff --git a/src/backends/tde/configure-sub.in b/src/backends/tde/configure-sub.in
new file mode 100644
index 00000000..3ab64e95
--- /dev/null
+++ b/src/backends/tde/configure-sub.in
@@ -0,0 +1,60 @@
+dnl -*- mode: Autoconf; -*-
+dnl Invoke autogen.sh to produce a configure script.
+
+TDEWALLETFOUND=no
+
+# first check for tqmake-qt3.
+AC_CHECK_PROGS([TQMAKE], [tqmake tqmake])
+PKG_CHECK_MODULES(TQT, tqt, TQTFOUND=yes, [TQTFOUND=no])
+
+# Check for TDE Wallet. There is no .pc file for it,
+# so fall back to normal header file and library checking.
+# libtdepim1-trinity-dev and tdelibs14-trinity-dev >= 14.0.2 provides the necessary files.
+# it could be backwords compat but we do not guarantee success
+
+if ! test "$TDEWALLET_CFLAGS"; then
+ TDEWALLET_CFLAGS="-I/opt/trinity/include"
+ if test "$TQMAKE"; then
+ TDEWALLET_CFLAGS="$TDEWALLET_CFLAGS $TQT_CFLAGS"
+ fi
+fi
+if ! test "$TDEWALLET_LIBS"; then
+ TDEWALLET_LIBS="-L/opt/trinity/lib"
+ if test "$TQMAKE"; then
+ TDEWALLET_LIBS="$TDEWALLET_LIBS $TQT_LIBS"
+ fi
+fi
+
+AC_LANG_PUSH(C++)
+old_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $TDEWALLET_CFLAGS"
+AC_CHECK_HEADERS(tdewallet.h, [TDEWALLETFOUND=yes], [TDEWALLETFOUND=no], [])
+CPPFLAGS="$old_CPPFLAGS"
+AC_LANG_POP(C++)
+
+# In contrast to the GNOME KEYRING, the TDE Wallet is
+# currently considered optional. "configure" will never enable
+# by default, because that is a change that might not be
+# expected by traditional users.
+AC_ARG_ENABLE(tdewallet,
+ AS_HELP_STRING([--enable-tdewallet], [enable access to TDE Wallet]),
+ [enable_tdewallet="$enableval"
+ test $TDEWALLETFOUND = "yes" || test "$enable_tdewallet" = "no" || AC_MSG_ERROR([--enable-tdewallet requires packages libtdepim1-trinity-dev, tdelibs14-trinity-dev, but they were not found])],
+ [enable_tdewallet="no"])
+
+if test "$enable_tdewallet" = "yes"; then
+ have_keyring=yes
+ # conditional compilation in preprocessor
+ AC_DEFINE(ENABLE_TDEWALLET, 1, [TDE Wallet available])
+ # link into static executables, similar to a SyncSource
+ SYNCSOURCES="$SYNCSOURCES src/backends/tde/platformtde.la"
+else
+ # avoid unneeded dependencies on TDE Wallet
+ TDEWALLET_CFLAGS=
+ TDEWALLET_LIBS=
+fi
+AC_SUBST(TDEWALLET_LIBS)
+AC_SUBST(TDEWALLET_CFLAGS)
+
+# conditional compilation in make
+AM_CONDITIONAL([ENABLE_TDEWALLET], [test "$enable_tdewallet" = "yes"])
diff --git a/src/backends/tde/tde.am b/src/backends/tde/tde.am
new file mode 100644
index 00000000..9953369f
--- /dev/null
+++ b/src/backends/tde/tde.am
@@ -0,0 +1,23 @@
+dist_noinst_DATA += src/backends/tde/configure-sub.in
+
+src_backends_tde_lib = src/backends/tde/platformtde.la
+MOSTLYCLEANFILES += $(src_backends_tde_lib)
+
+src_backends_tde_platformtde_la_SOURCES = \
+ src/backends/tde/TDEPlatform.h \
+ src/backends/tde/TDEPlatform.cpp
+
+if ENABLE_MODULES
+src_backends_tde_backenddir = $(BACKENDS_DIRECTORY)
+src_backends_tde_backend_LTLIBRARIES = $(src_backends_tde_lib)
+src_backends_tde_platformtde_la_SOURCES += \
+ src/backends/tde/TDEPlatformRegister.cpp
+else
+noinst_LTLIBRARIES += $(src_backends_tde_lib)
+endif
+
+src_backends_tde_platformtde_la_LIBADD = $(TDEWALLET_LIBS) $(SYNCEVOLUTION_LIBS)
+src_backends_tde_platformtde_la_LDFLAGS = -module -avoid-version
+src_backends_tde_platformtde_la_CXXFLAGS = $(TDEWALLET_CFLAGS) $(SYNCEVOLUTION_CFLAGS)
+src_backends_tde_platformtde_la_CPPFLAGS = -I$(top_srcdir)/test $(BACKEND_CPPFLAGS)
+src_backends_tde_platformtde_la_DEPENDENCIES = src/syncevo/libsyncevolution.la
diff --git a/src/backends/tdepim/KNotesIface_stub.cpp b/src/backends/tdepim/KNotesIface_stub.cpp
new file mode 100644
index 00000000..274179e9
--- /dev/null
+++ b/src/backends/tdepim/KNotesIface_stub.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** DCOP Stub Implementation created by dcopidl2cpp from KNotesIface.kidl
+**
+** WARNING! All changes made in this file will be lost!
+**
+** $Id: KNotesIface_stub.cpp,v 1.2 2016/09/01 10:40:05 emanoil Exp $
+**
+*****************************************************************************/
+
+#include "KNotesIface_stub.h"
+#include <dcopclient.h>
+
+#include <tqdatastream.h>
+
+
+KNotesIface_stub::KNotesIface_stub( const TQCString& app, const TQCString& obj )
+ : DCOPStub( app, obj )
+{
+}
+
+KNotesIface_stub::KNotesIface_stub( DCOPClient* client, const TQCString& app, const TQCString& obj )
+ : DCOPStub( client, app, obj )
+{
+}
+
+KNotesIface_stub::KNotesIface_stub( const DCOPRef& ref )
+ : DCOPStub( ref )
+{
+}
+
+TQString KNotesIface_stub::newNote( const TQString& arg0, const TQString& arg1 )
+{
+ TQString result;
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return result;
+ }
+ TQByteArray data, replyData;
+ TQCString replyType;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ arg << arg1;
+ if ( dcopClient()->call( app(), obj(), "newNote(TQString,TQString)", data, replyType, replyData ) ) {
+ if ( replyType == "TQString" ) {
+ TQDataStream _reply_stream( replyData, IO_ReadOnly );
+ _reply_stream >> result;
+ setStatus( CallSucceeded );
+ } else {
+ callFailed();
+ }
+ } else {
+ callFailed();
+ }
+ return result;
+}
+
+TQString KNotesIface_stub::newNoteFromClipboard( const TQString& arg0 )
+{
+ TQString result;
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return result;
+ }
+ TQByteArray data, replyData;
+ TQCString replyType;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ if ( dcopClient()->call( app(), obj(), "newNoteFromClipboard(TQString)", data, replyType, replyData ) ) {
+ if ( replyType == "TQString" ) {
+ TQDataStream _reply_stream( replyData, IO_ReadOnly );
+ _reply_stream >> result;
+ setStatus( CallSucceeded );
+ } else {
+ callFailed();
+ }
+ } else {
+ callFailed();
+ }
+ return result;
+}
+
+void KNotesIface_stub::showNote( const TQString& arg0 )
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ TQByteArray data;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ dcopClient()->send( app(), obj(), "showNote(TQString)", data );
+ setStatus( CallSucceeded );
+}
+
+void KNotesIface_stub::hideNote( const TQString& arg0 )
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ TQByteArray data;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ dcopClient()->send( app(), obj(), "hideNote(TQString)", data );
+ setStatus( CallSucceeded );
+}
+
+void KNotesIface_stub::killNote( const TQString& arg0 )
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ TQByteArray data;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ dcopClient()->send( app(), obj(), "killNote(TQString)", data );
+ setStatus( CallSucceeded );
+}
+
+void KNotesIface_stub::killNote( const TQString& arg0, bool arg1 )
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ TQByteArray data;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ arg << arg1;
+ dcopClient()->send( app(), obj(), "killNote(TQString,bool)", data );
+ setStatus( CallSucceeded );
+}
+
+TQMap<TQString,TQString> KNotesIface_stub::notes()
+{
+ TQMap<TQString,TQString> result;
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return result;
+ }
+ TQByteArray data, replyData;
+ TQCString replyType;
+ if ( dcopClient()->call( app(), obj(), "notes()", data, replyType, replyData ) ) {
+ if ( replyType == "TQMap<TQString,TQString>" ) {
+ TQDataStream _reply_stream( replyData, IO_ReadOnly );
+ _reply_stream >> result;
+ setStatus( CallSucceeded );
+ } else {
+ callFailed();
+ }
+ } else {
+ callFailed();
+ }
+ return result;
+}
+
+void KNotesIface_stub::setName( const TQString& arg0, const TQString& arg1 )
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ TQByteArray data;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ arg << arg1;
+ dcopClient()->send( app(), obj(), "setName(TQString,TQString)", data );
+ setStatus( CallSucceeded );
+}
+
+void KNotesIface_stub::setText( const TQString& arg0, const TQString& arg1 )
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ TQByteArray data;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ arg << arg1;
+ dcopClient()->send( app(), obj(), "setText(TQString,TQString)", data );
+ setStatus( CallSucceeded );
+}
+
+TQString KNotesIface_stub::name( const TQString& arg0 )
+{
+ TQString result;
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return result;
+ }
+ TQByteArray data, replyData;
+ TQCString replyType;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ if ( dcopClient()->call( app(), obj(), "name(TQString)", data, replyType, replyData ) ) {
+ if ( replyType == "TQString" ) {
+ TQDataStream _reply_stream( replyData, IO_ReadOnly );
+ _reply_stream >> result;
+ setStatus( CallSucceeded );
+ } else {
+ callFailed();
+ }
+ } else {
+ callFailed();
+ }
+ return result;
+}
+
+TQString KNotesIface_stub::text( const TQString& arg0 )
+{
+ TQString result;
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return result;
+ }
+ TQByteArray data, replyData;
+ TQCString replyType;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ if ( dcopClient()->call( app(), obj(), "text(TQString)", data, replyType, replyData ) ) {
+ if ( replyType == "TQString" ) {
+ TQDataStream _reply_stream( replyData, IO_ReadOnly );
+ _reply_stream >> result;
+ setStatus( CallSucceeded );
+ } else {
+ callFailed();
+ }
+ } else {
+ callFailed();
+ }
+ return result;
+}
+
+void KNotesIface_stub::sync( const TQString& arg0 )
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ TQByteArray data;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ dcopClient()->send( app(), obj(), "sync(TQString)", data );
+ setStatus( CallSucceeded );
+}
+
+bool KNotesIface_stub::isNew( const TQString& arg0, const TQString& arg1 )
+{
+ bool result = false;
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return result;
+ }
+ TQByteArray data, replyData;
+ TQCString replyType;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ arg << arg1;
+ if ( dcopClient()->call( app(), obj(), "isNew(TQString,TQString)", data, replyType, replyData ) ) {
+ if ( replyType == "bool" ) {
+ TQDataStream _reply_stream( replyData, IO_ReadOnly );
+ _reply_stream >> result;
+ setStatus( CallSucceeded );
+ } else {
+ callFailed();
+ }
+ } else {
+ callFailed();
+ }
+ return result;
+}
+
+bool KNotesIface_stub::isModified( const TQString& arg0, const TQString& arg1 )
+{
+ bool result = false;
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return result;
+ }
+ TQByteArray data, replyData;
+ TQCString replyType;
+ TQDataStream arg( data, IO_WriteOnly );
+ arg << arg0;
+ arg << arg1;
+ if ( dcopClient()->call( app(), obj(), "isModified(TQString,TQString)", data, replyType, replyData ) ) {
+ if ( replyType == "bool" ) {
+ TQDataStream _reply_stream( replyData, IO_ReadOnly );
+ _reply_stream >> result;
+ setStatus( CallSucceeded );
+ } else {
+ callFailed();
+ }
+ } else {
+ callFailed();
+ }
+ return result;
+}
+
+
diff --git a/src/backends/tdepim/KNotesIface_stub.h b/src/backends/tdepim/KNotesIface_stub.h
new file mode 100644
index 00000000..a21504b0
--- /dev/null
+++ b/src/backends/tdepim/KNotesIface_stub.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** DCOP Stub Definition created by dcopidl2cpp from KNotesIface.kidl
+**
+** WARNING! All changes made in this file will be lost!
+**
+** $Id: KNotesIface_stub.h,v 1.2 2016/09/01 10:40:05 emanoil Exp $
+**
+*****************************************************************************/
+
+#ifndef __KNOTESIFACE_STUB__
+#define __KNOTESIFACE_STUB__
+
+#include <dcopstub.h>
+#include <dcopobject.h>
+#include <tqmap.h>
+#include <tqstring.h>
+
+
+class KNotesIface_stub : virtual public DCOPStub
+{
+public:
+ KNotesIface_stub( const TQCString& app, const TQCString& id );
+ KNotesIface_stub( DCOPClient* client, const TQCString& app, const TQCString& id );
+ explicit KNotesIface_stub( const DCOPRef& ref );
+ virtual TQString newNote( const TQString& name, const TQString& text );
+ virtual TQString newNoteFromClipboard( const TQString& name );
+ virtual ASYNC showNote( const TQString& noteId );
+ virtual ASYNC hideNote( const TQString& noteId );
+ virtual ASYNC killNote( const TQString& noteId );
+ virtual ASYNC killNote( const TQString& noteId, bool force );
+ virtual TQMap<TQString,TQString> notes();
+ virtual ASYNC setName( const TQString& noteId, const TQString& newName );
+ virtual ASYNC setText( const TQString& noteId, const TQString& newText );
+ virtual TQString name( const TQString& noteId );
+ virtual TQString text( const TQString& noteId );
+ virtual ASYNC sync( const TQString& app );
+ virtual bool isNew( const TQString& app, const TQString& noteId );
+ virtual bool isModified( const TQString& app, const TQString& noteId );
+protected:
+ KNotesIface_stub() : DCOPStub( never_use ) {}
+};
+
+
+#endif
diff --git a/src/backends/tdepim/README b/src/backends/tdepim/README
new file mode 100644
index 00000000..e980dc02
--- /dev/null
+++ b/src/backends/tdepim/README
@@ -0,0 +1,171 @@
+Getting started with TDM on Debian jessie:
+1st install libtdepim1-trinity-dev and tdelibs14-trinity-dev
+2nd use this on your own risk - take backups!
+
+# Debugging in TDE:
+[x] 5300 libtdepim
+[x] 5300 knotes
+[x] 5800 libkcal
+
+# Configuring without Evolution, without Akonadi and with TDEPIM
+# This is good for testing (static libs)
+<path>/syncevolution/configure --with-synthesis-src=<path>/libsynthesis \
+ CFLAGS="-g -Wall -Werror -Wno-unknown-pragmas" \
+ CXXFLAGS="-g -Wall -Werror -Wno-unknown-pragmas" \
+ --disable-shared --enable-static \
+ --disable-akonadi \
+ --disable-ebook \
+ --disable-ecal \
+ --disable-goa \
+ --disable-kcalextended \
+ --disable-kwallet \
+ --enable-tdepimabc \
+ --enable-tdepimcal \
+ --enable-tdewallet
+
+# Configure to build
+ Important: You would most probably set --prefix
+======== configure script build-test-syncevo.sh start =======
+export PKG_CONFIG_PATH=/opt/trinity/lib/pkgconfig:$PKG_CONFIG_PATH
+
+if [[ $1 == "static" ]]; then
+LIBVAR="--disable-shared --enable-static"
+else
+LIBVAR="--enable-shared"
+fi
+
+./configure --prefix=/tmp/test \
+ $LIBVAR \
+ --enable-maintainer-mode \
+ --enable-shared \
+ --enable-gui \
+ --enable-gtk=3 \
+ --enable-core \
+ --enable-bluetooth \
+ --enable-tdepimabc \
+ --enable-tdepimcal \
+ --enable-tdepimnotes \
+ --disable-tdewallet \
+ --enable-sqlite \
+ --enable-file \
+ --enable-dav \
+ --without-gio-gdbus \
+ --disable-ssl-certificate-check \
+ --disable-akonadi \
+ --disable-ebook \
+ --disable-ecal \
+ --disable-goa \
+ --disable-kcalextended \
+ --disable-kwallet \
+ --disable-maemocal \
+ --disable-oauth2 \
+ --disable-qtcontacts \
+ --disable-gsso \
+ --disable-uoa \
+ --disable-sign
+
+
+======== configure script build-test-syncevo.sh end =======
+
+# Now build shared
+bash autogen.sh && bash ../build-test-syncevo.sh && make
+
+# or static
+bash autogen.sh && bash ../build-test-syncevo.sh static && make
+
+# Static creates src/syncevolution and src/client-test which can be
+# run under a debugger directly.
+
+# Install
+ make install
+
+# Set up environment for testing
+ export LD_LIBRARY_PATH=/tmp/test/lib/syncevolution/backends:/tmp/test/lib:$LD_LIBRARY_PATH
+ export LD_RUN_PATH=$LD_LIBRARY_PATH:$LD_RUN_PATH
+ export PATH=/tmp/test/bin:$PATH
+
+# Backup your contacts and calendar file (if you use the standard one)
+cp ~/.trinity/share/apps/tdeabc/std.vcf ~/$(date +%Y%m%d)_std.vcf
+cp ~/.trinity/share/apps/korganizer/std.ics ~/$(date +%Y%m%d)_std.ics
+
+# You could also make tar.gz of the above directories.
+# In this case it is better to clean up first
+
+# Clean up all lock and cache files
+rm -rf .cache/syncevolution/ \
+ .config/syncevolution/ \
+ ~/.trinity/share/apps/tdeabc/lock/*.trinity_share_apps_tdeabc_std.vcf* \
+ ~/.trinity/share/apps/tdeabc/std.vcf__*
+
+# Query databases:
+ syncevolution --print-databases
+
+# Configuring syncevolution for contacts with TDEPIM as backend:
+ syncevolution --configure --datastore-property sync=none \
+ --sync-property username=... \
+ --sync-property password=... \
+ scheduleworld
+ syncevolution --configure --datastore-property sync=two-way \
+ addressbook/backend=tdepim-contacts \
+ addressbook/database="kxXrRFzP9c" \
+ addressbook/databaseFormat="text/vcard" \
+ scheduleworld addressbook
+
+# Nokia phone 5530
+template=nokia
+# Nokia phone N9
+template=Nokia_N900
+deviceAddress="XX:XX:XX:XX:XX:XX"
+
+# configure local store
+syncevolution --configure \
+ addressbook/backend=tdepim-contacts \
+ addressbook/database="xnCaZWvsal" \
+ addressbook/databaseFormat="text/vcard" \
+ calendar/backend=tdepim-calendar \
+ calendar/database="kOBUWNvG42" \
+ calendar/databaseFormat="text/calendar" \
+ todo/backend=tdepim-tasks \
+ todo/database="kOBUWNvG42" \
+ todo/databaseFormat="text/calendar" \
+ memo/backend=tdepim-notes \
+ memo/database=tdenotes \
+ memo/databaseFormat="text/plain" \
+ @default addressbook calendar todo memo
+
+# add your phone
+# for N9 it is important to set uri to the calendar you want to sync with
+# this is equivalent to the database above
+syncevolution --configure \
+ --template ${template} \
+ peerIsClient=1 \
+ dumpData=0 \
+ printChanges=0 \
+ syncURL=obex-bt://${deviceAddress} \
+ calendar/uri="PC-SYNC" \
+ calendar/databaseFormat="text/x-vcalendar" \
+ todo/uri="PC-SYNC" \
+ todo/databaseFormat="text/x-vcalendar" \
+ memo/uri="notes" \
+ memo/databaseFormat="text/plain" \
+ nokia_N9
+
+
+# Initial run:
+ syncevolution --sync slow nokia_N9 addressbook
+ syncevolution --sync slow nokia_N9 calendar+todo
+ syncevolution --sync slow nokia_N9 memo
+
+# All following syncs run:
+ syncevolution nokia_N9 addressbook
+ syncevolution nokia_N9 calendar+todo
+ syncevolution nokia_N9 memo
+
+# Sync all configured
+ syncevolution nokia_N9 addressbook calendar+todo memo
+
+# Useful information
++ https://syncevolution.org/wiki/kde-akonadi
++ https://syncevolution.org/documentation/syncevolution-usage
++ https://syncevolution.org/documentation/getting-started
++ https://syncevolution.org/wiki/howto
diff --git a/src/backends/tdepim/TDEPIMAddressBookSource.cpp b/src/backends/tdepim/TDEPIMAddressBookSource.cpp
new file mode 100644
index 00000000..8ab90de7
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMAddressBookSource.cpp
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPIMAddressBookSource.cpp,v 1.9 2016/09/12 19:57:27 emanoil Exp $
+ *
+ */
+
+#include "TDEPIMAddressBookSource.h"
+
+#ifdef ENABLE_TDEPIMABC
+
+#include <syncevo/util.h>
+#include <syncevo/Exception.h>
+#include <syncevo/Logging.h>
+
+#include <tdeabc/resource.h>
+#include <tdeabc/vcardconverter.h>
+
+
+SE_BEGIN_CXX
+
+TDEPIMAddressBookSource::TDEPIMAddressBookSource( TDEPIMAddressBookSourceType type, const SyncSourceParams &params) :
+ TrackingSyncSource(params,1),
+ m_type(type),
+ addressbookPtr(0),
+ ticketPtr(0),
+ modified(false)
+{
+
+ switch (m_type) {
+ case TDEPIM_CONTACT_V21:
+ m_contentMimeType = "text/x-vcard";
+ m_typeName = "vcard21 addressbook";
+ break;
+ case TDEPIM_CONTACT_V30:
+ m_contentMimeType = "text/vcard";
+ m_typeName = "vcard30 addressbook";
+ break;
+ default:
+ Exception::throwError(SE_HERE, "internal init error, invalid addressbook type");
+ break;
+ }
+
+ app = new TDEPIMSyncSource("syncevo-tdepim-abc");
+
+ addressbookPtr = TDEABC::StdAddressBook::self(false); // load synchronously
+ TDEABC::StdAddressBook::setAutomaticSave(false); // save only when asked
+
+ if ( ! addressbookPtr )
+ Exception::throwError(SE_HERE, "internal error, can not open the default addressbook");
+
+ SyncSourceLogging::init(
+ InitList<std::string>("N_FIRST") + "N_MIDDLE" + "N_LAST",
+ " ",
+ m_operations);
+
+// SE_LOG_DEBUG(getDisplayName(), "TDE addressbook for %s (mime type: %s)",
+// m_typeName.latin1(), m_contentMimeType.latin1());
+}
+
+TDEPIMAddressBookSource::~TDEPIMAddressBookSource()
+{
+ if (ticketPtr) { // make sure we release the ticket
+ TDEABC::Resource *workbookPtr = ticketPtr->resource() ;
+ workbookPtr->releaseSaveTicket(ticketPtr);
+ ticketPtr = 0 ;
+ SE_LOG_DEBUG(getDisplayName(), "TDE addressbook release ticket on close" );
+ }
+ delete app;
+}
+
+TQString TDEPIMAddressBookSource::lastModifiedNormalized(TDEABC::Addressee &e)
+{
+ //Get the revision date of the KDE addressbook entry.
+ TQDateTime d = e.revision();
+ // if no modification date is available, always return the same 0-time stamp
+ // to avoid that 2 calls deliver different times which would be treated as changed entry
+ // this would result in 1.1.1970
+ if ( !d.isValid() ) {
+ d.setTime_t(0);
+ e.setRevision(d);
+ }
+
+// We pass UTC, because we open the calendar in UTC
+// return d.toString(TQt::ISODate);
+ return d.toString("yyyyMMddThhmmssZ");
+}
+
+// TODO if it makes sense to sync up only specific categories
+// bool TDEPIMAddressBookSource::hasCategory(const TQStringList &list) const
+// {
+// if ( m_categories.isEmpty() ) return true; // no filter defined -> match all
+//
+// for (TQStringList::const_iterator it = list.begin(); it != list.end(); ++it ) {
+// if ( m_categories.contains(*it) ) return true;
+// }
+// return false; // not found
+// }
+
+TDEPIMAddressBookSource::Databases TDEPIMAddressBookSource::getDatabases()
+{
+
+ bool first = true;
+ Databases result;
+
+ TQPtrList<TDEABC::Resource> lit = addressbookPtr->resources();
+ TQPtrListIterator<TDEABC::Resource> it( lit );
+ TDEABC::Resource *res;
+ while ( (res = it.current()) != 0 ) {
+ ++it;
+
+ std::string name_str(res->resourceName().utf8(),res->resourceName().utf8().length());
+ std::string path_str(res->identifier().utf8(),res->identifier().utf8().length());
+ SE_LOG_DEBUG(getDisplayName(), "SUB Name : %s , ID: %s", name_str.c_str(), path_str.c_str() );
+ /*
+ * we pull only active resources thus user has freedom to decide what wants to be visible for sync
+ */
+ if ( res->isActive() ) {
+ result.push_back (
+ Database (
+ name_str, // the name of the resource
+ path_str, // the path - (we use the resource uid)
+ first, // default or not
+ res->readOnly() // read only or not
+ )
+ );
+ first = false;
+ }
+ }
+ return result;
+}
+
+void TDEPIMAddressBookSource::open()
+{
+ std::string id = getDatabaseID();
+ SE_LOG_DEBUG(getDisplayName(), "TDE search for address book id: %s ", id.c_str() );
+
+ TQPtrList<TDEABC::Resource> lit = addressbookPtr->resources();
+ TQPtrListIterator<TDEABC::Resource> it( lit );
+ TDEABC::Resource *res;
+ while ( (res = it.current()) != 0 ) {
+ ++it;
+ std::string path_str(res->identifier().utf8(),res->identifier().utf8().length());
+ if ( id.compare(path_str) == 0 ) {
+ if ( ! res->isActive() )
+ Exception::throwError(SE_HERE, "internal error, configured resource is not active");
+ ticketPtr = res->requestSaveTicket();
+ SE_LOG_DEBUG(getDisplayName(), "TDE address book id: %s ", path_str.c_str() );
+ break;
+ }
+ }
+
+ if ( ! ticketPtr )
+ Exception::throwError(SE_HERE, "internal error, unable to set ticket on addressbook");
+}
+
+bool TDEPIMAddressBookSource::isEmpty()
+{
+ TDEABC::Resource *workbookPtr = ticketPtr->resource() ;
+ TDEABC::Resource::Iterator it = workbookPtr->begin();
+ TDEABC::Addressee a = ( *it ); // if the first addressee is empty, the address book is empty
+ return a.isEmpty();
+}
+
+void TDEPIMAddressBookSource::close()
+{
+ TDEABC::Resource *workbookPtr = ticketPtr->resource() ;
+
+ if ( modified ) {
+ if ( ! workbookPtr->save(ticketPtr) )
+ Exception::throwError(SE_HERE, "internal error,unable to use ticket on addressbook");
+ modified= false;
+ }
+ if (ticketPtr)
+ workbookPtr->releaseSaveTicket(ticketPtr);
+ ticketPtr = 0 ;
+}
+
+void TDEPIMAddressBookSource::listAllItems(RevisionMap_t &revisions)
+{
+ TDEABC::Resource *workbookPtr = ticketPtr->resource() ;
+
+ for (TDEABC::Resource::Iterator it=workbookPtr->begin(); it!=workbookPtr->end(); it++) {
+ TDEABC::Addressee ab = (*it);
+ TQString lm = lastModifiedNormalized(ab);
+ std::string uid_str(ab.uid().utf8(),ab.uid().utf8().length());
+ std::string lm_str(lm.utf8(),lm.utf8().length());
+ revisions[uid_str] = lm_str;
+// m_categories.append(a.categories()); // Set filter categories
+ SE_LOG_DEBUG(getDisplayName(), "Addressee UID: %s last changed(%s)",uid_str.c_str(),lm_str.c_str() );
+ }
+}
+
+TrackingSyncSource::InsertItemResult TDEPIMAddressBookSource::insertItem(const std::string &uid, const std::string &item, bool raw)
+{
+
+ TDEABC::VCardConverter converter;
+ InsertItemResultState state = ITEM_OKAY;
+ TQString uidOld = TQString::fromUtf8(uid.data(),uid.size());
+ TDEABC::Resource *workbookPtr = ticketPtr->resource() ;
+ if ( ! workbookPtr )
+ Exception::throwError(SE_HERE, "internal insertItem error, addressbook resource lost");
+
+ TDEABC::Addressee addressee = converter.parseVCard( TQString::fromUtf8(item.data(),item.size()) );
+
+// TODO: add category if present
+ // if we run with a configured category filter, but the received added vcard does
+ // not contain that category, add the filter-categories so that the address will be
+ // found again on the next sync
+// if ( ! hasCategory(addressee.categories()) ) {
+// for (TQStringList::const_iterator it = categories.begin(); it != categories.end(); ++it )
+// addressee.insertCategory(*it);
+// }
+
+ // ensure it has the correct UID
+ if ( uid.empty() )
+ uidOld = addressee.uid(); // item push
+ else
+ addressee.setUid(uidOld); // item replace
+
+// It is not ok to return ITEM_REPLACED
+// If we add the addressee to the calendar with the same UID
+// it will overwrite the old one -
+// TODO we need merge here
+// TDEABC::Addressee addresseeOld = workbookPtr->findByUid(uidOld);
+// if ( ! addresseeOld.isEmpty() ) {
+// std::string ret_uid(uidOld.utf8(), uidOld.utf8().length());
+// return InsertItemResult(ret_uid, "", ITEM_NEEDS_MERGE);
+// }
+
+ workbookPtr->insertAddressee(addressee);
+ modified = true;
+
+ /* TODO
+ This shouldn't be here in first place, but otherwise the plugin crashes
+ It should be in the close(), but no time to investigate what is the reason
+ or how it can be improved.
+ */
+ if ( ! workbookPtr->save(ticketPtr) ) {
+ Exception::throwError(SE_HERE, "internal error, unable to save addressbook item");
+// return InsertItemResult("", "", ITEM_OKAY);
+ }
+
+ // read out the new addressee to get the new revision
+ TDEABC::Addressee addresseeNew = workbookPtr->findByUid(uidOld);
+
+ TQString revision = lastModifiedNormalized(addresseeNew);
+ std::string uid_str(uidOld.utf8(),uidOld.utf8().length());
+ std::string rev_str(revision.utf8(),revision.utf8().length());
+ SE_LOG_DEBUG(getDisplayName(), "TDE addressbook UID= %s ADD/UPDATE (REV=%s) OK",uid_str.c_str(),rev_str.c_str() );
+ return InsertItemResult(uid_str, rev_str, state);
+}
+
+void TDEPIMAddressBookSource::readItem(const std::string &luid, std::string &item, bool raw)
+{
+
+ TDEABC::Resource *workbookPtr = ticketPtr->resource() ;
+ if ( ! workbookPtr )
+ Exception::throwError(SE_HERE, "internal readItem error,unable to find the addressbook id");
+
+ TDEABC::VCardConverter converter;
+ TQString data = "";
+ // read out the addressee
+ TQString uid = TQString::fromUtf8(luid.data(),luid.size());
+ TDEABC::Addressee addressee = workbookPtr->findByUid(uid);
+
+ if ( addressee.isEmpty() )
+ Exception::throwError(SE_HERE, "internal readItem error: invalid contact");
+
+ if (m_type == TDEPIM_CONTACT_V21 )
+ data = converter.createVCard(addressee, TDEABC::VCardConverter::v2_1);
+ else
+ data = converter.createVCard(addressee, TDEABC::VCardConverter::v3_0);
+
+ std::string data_str(data.utf8(),data.utf8().length());
+
+ item.assign(data_str.c_str());
+/* DEBUG
+ SE_LOG_DEBUG(getDisplayName(), "Item id ( %s )", luid.c_str() );
+ SE_LOG_DEBUG(getDisplayName(), "data %s", data_str.c_str());
+*/
+}
+
+void TDEPIMAddressBookSource::removeItem(const std::string &uid)
+{
+
+ TDEABC::Resource *workbookPtr = ticketPtr->resource() ;
+ if ( ! workbookPtr )
+ Exception::throwError(SE_HERE, "internal readItem error,unable to find the addressbook id");
+
+ //find addressbook entry with matching UID and delete it
+ TDEABC::Addressee addressee = workbookPtr->findByUid(TQString::fromUtf8(uid.data(),uid.size()));
+ if(!addressee.isEmpty()) {
+ workbookPtr->removeAddressee(addressee);
+ modified = true;
+ SE_LOG_DEBUG(getDisplayName(), "TDE addressbook ENTRY DELETED (UID= %s )",uid.c_str() );
+
+ if ( ! workbookPtr->save(ticketPtr) )
+ Exception::throwError(SE_HERE, "internal error, unable to save addressbook item");
+ }
+// else {
+// SE_LOG_DEBUG(getDisplayName(), "WARN: TDE addressbook ENTRY EMPTY (UID= %s )",uid.c_str() );
+// }
+}
+
+std::string TDEPIMAddressBookSource::getDescription(const string &luid)
+{
+ TDEABC::Resource *workbookPtr = ticketPtr->resource() ;
+ if ( ! workbookPtr )
+ Exception::throwError(SE_HERE, "internal getDescription error,unable to find the addressbook id");
+
+ TDEABC::Addressee addressee = workbookPtr->findByUid(TQString::fromUtf8(luid.data(),luid.size()));
+ if ( addressee.isEmpty() )
+ Exception::throwError(SE_HERE, "internal getDescription error, addressbook not found");
+
+ TDEABC::PhoneNumber::List phonelist = addressee.phoneNumbers();
+
+ TQString desc;
+ desc.append("Name: ")
+ .append(addressee.assembledName()).append(", Nick: ")
+ .append(", URI: ").append(addressee.uri())
+ .append(addressee.nickName()).append("\nPhone#: ");
+
+ for (TDEABC::PhoneNumber::List::Iterator it=phonelist.begin(); it!=phonelist.end(); it++ ) {
+ desc.append((*it).number()).append(", ");
+ }
+ desc.append("\n");
+ std::string desc_str(desc.utf8(),desc.utf8().length());
+ SE_LOG_DEBUG(getDisplayName(), "User summary %s", desc_str.c_str());
+ return desc_str;
+}
+
+void TDEPIMAddressBookSource::getSynthesisInfo(SynthesisInfo &info,
+ XMLConfigFragments &fragments)
+{
+ TrackingSyncSource::getSynthesisInfo(info, fragments);
+ info.m_backendRule = "TDE";
+ info.m_beforeWriteScript = "";
+}
+
+std::string TDEPIMAddressBookSource::getMimeType() const
+{
+ switch( m_type ) {
+ case TDEPIM_CONTACT_V21:
+ return "text/x-vcard";
+ break;
+ case TDEPIM_CONTACT_V30:
+ default:
+ return "text/vcard";
+ break;
+ }
+}
+
+std::string TDEPIMAddressBookSource::getMimeVersion() const
+{
+ switch( m_type ) {
+ case TDEPIM_CONTACT_V21:
+ return "2.1";
+ break;
+ case TDEPIM_CONTACT_V30:
+ default:
+ return "3.0";
+ break;
+ }
+}
+
+SE_END_CXX
+
+#endif /* ENABLE_TDEPIMABC */
+
+#ifdef ENABLE_MODULES
+# include "TDEPIMAddressBookSourceRegister.cpp"
+#endif
diff --git a/src/backends/tdepim/TDEPIMAddressBookSource.h b/src/backends/tdepim/TDEPIMAddressBookSource.h
new file mode 100644
index 00000000..9f9f7aa8
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMAddressBookSource.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * $Id: TDEPIMAddressBookSource.h,v 1.4 2016/09/08 22:58:08 emanoil Exp $
+ *
+ */
+
+#ifndef INCL_TDEPIMABCSOURCE
+#define INCL_TDEPIMABCSOURCE
+
+#include "config.h"
+#include "TDEPIMSyncSource.h"
+
+#ifdef ENABLE_TDEPIMABC
+
+#include <syncevo/TrackingSyncSource.h>
+
+#include <tqstring.h>
+#include <tqstringlist.h>
+
+#include <tdeabc/addressbook.h>
+#include <tdeabc/stdaddressbook.h>
+
+
+SE_BEGIN_CXX
+
+// class TimeTrackingObserver;
+
+typedef enum {
+ TDEPIM_CONTACT_V21,
+ TDEPIM_CONTACT_V30
+ } TDEPIMAddressBookSourceType;
+/**
+ * Implements access to TDE PIM address books.
+ */
+class TDEPIMAddressBookSource : public TrackingSyncSource, public SyncSourceLogging
+{
+public:
+
+ TDEPIMAddressBookSource(TDEPIMAddressBookSourceType type, const SyncSourceParams &params) ;
+
+ virtual ~TDEPIMAddressBookSource();
+ /*
+ * implementation of SyncSource
+ */
+ virtual Databases getDatabases();
+ virtual void open();
+ virtual bool isEmpty();
+ virtual void close();
+ virtual std::string getMimeType() const;
+ virtual std::string getMimeVersion() const;
+
+ /* implementation of TrackingSyncSource interface */
+ virtual void listAllItems(RevisionMap_t &revisions);
+ virtual InsertItemResult insertItem(const string &luid, const std::string &item, bool raw);
+ virtual void readItem(const std::string &luid, std::string &item, bool raw);
+ virtual void removeItem(const string &luid);
+
+ /* implementation of SyncSourceLogging interface */
+ virtual std::string getDescription(const string &luid);
+
+private:
+ TDEPIMAddressBookSourceType m_type; /* use v2.1 or v3.0 */
+
+ TDEABC::AddressBook * addressbookPtr;
+ TDEABC::Ticket * ticketPtr;
+
+ /**
+ * set when needed to save addressbook back
+ */
+ bool modified;
+
+ /**
+ * mandatory TDE app class - needs to be initialized when creating the object
+ */
+ TDEPIMSyncSource *app;
+
+ /**
+ * The type name associated with the collection
+ */
+ TQString m_typeName; // NOTE not really used except for debug in the constructor
+
+ /**
+ * The actual type to be used inside the collection. Set after opening
+ * the collection.
+ */
+ TQString m_contentMimeType; // NOTE not really used except for debug in the constructor
+
+ TQStringList m_categories; // TODO It is possible to fileter a category
+
+ /**
+ * This functions is used internally to normalize the revision field in
+ * the specific entry.
+ * If no revision is available, always return the same 0-time stamp
+ */
+ TQString lastModifiedNormalized(TDEABC::Addressee &e);
+
+// /** TODO if it makes sense to sync up only specific categories
+// * return true if at least one item in the given list is included in the categories member
+// */
+// bool hasCategory(const TQStringList &list) const;
+//
+// /** TODO
+// * return the categories as list
+// */
+// const TQStringList &getCategories() const { return m_categories; }
+
+ /* All calendar storages must suppport UID/RECURRENCE-ID,
+ * it's part of the API. Therefore we can rely on it.
+ */
+ virtual void getSynthesisInfo(SynthesisInfo &info,
+ XMLConfigFragments &fragments);
+
+};
+
+SE_END_CXX
+
+#endif // ENABLE_TDEPIMABC
+#endif // INCL_TDEPIMABCSOURCE
diff --git a/src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp b/src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp
new file mode 100644
index 00000000..6ce03509
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * $Id: TDEPIMAddressBookSourceRegister.cpp,v 1.4 2016/09/08 22:58:08 emanoil Exp $
+ *
+ */
+
+SE_BEGIN_CXX
+
+static SyncSource *createSource(const SyncSourceParams &params)
+{
+ SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
+
+ bool isMe = sourceType.m_backend == "TDE PIM Address Book";
+
+#ifndef ENABLE_TDEPIMABC
+ if (isMe) return RegisterSyncSource::InactiveSource(params);
+#else
+ if (isMe || sourceType.m_backend == "addressbook" ) {
+ if (sourceType.m_format == "" || sourceType.m_format == "text/vcard") {
+ return new TDEPIMAddressBookSource(TDEPIM_CONTACT_V30, params);
+ }
+ else if (sourceType.m_format == "text/x-vcard") {
+ return new TDEPIMAddressBookSource(TDEPIM_CONTACT_V21, params);
+ }
+ else return NULL;
+ }
+#endif
+ return NULL;
+}
+
+static class RegisterTDEPIMAddressBokSyncSource : public RegisterSyncSource
+{
+public:
+ RegisterTDEPIMAddressBokSyncSource() :
+ RegisterSyncSource ("TDE PIM Address Book/Contacts",
+#ifdef ENABLE_TDEPIMABC
+ true,
+#else
+ false,
+#endif
+ createSource,
+ "TDE PIM Address Book = TDE PIM Contacts = tdepim-contacts\n"
+ " vCard 2.1 = text/x-vcard\n"
+ " vCard 3.0 (default) = text/vcard\n"
+ " The later is the internal format of TDE PIM and preferred with\n"
+ " servers that support it.",
+ Values() +
+ (Aliases("TDE PIM Address Book") + "TDE PIM Contacts" + "tdepim-contacts")
+ )
+ {
+ // configure and register our own property;
+ // do this regardless whether the backend is enabled,
+ // so that config migration always includes this property
+/* WebDAVCredentialsOkay().setHidden(true);
+ SyncConfig::getRegistry().push_back(&WebDAVCredentialsOkay());
+*/
+ }
+} registerMe;
+
+SE_END_CXX
diff --git a/src/backends/tdepim/TDEPIMCalendarSource.cpp b/src/backends/tdepim/TDEPIMCalendarSource.cpp
new file mode 100644
index 00000000..12888160
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMCalendarSource.cpp
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPIMCalendarSource.cpp,v 1.12 2016/09/12 19:57:27 emanoil Exp $
+ *
+ */
+
+
+#include "TDEPIMCalendarSource.h"
+
+#ifdef ENABLE_TDEPIMCAL
+
+#include <syncevo/util.h>
+#include <syncevo/Exception.h>
+#include <syncevo/Logging.h>
+
+#include <libkcal/icalformat.h>
+//#include <libkcal/vcalformat.h>
+#include <libkcal/calendarlocal.h>
+
+SE_BEGIN_CXX
+
+// "PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN"
+// "VERSION:2.0"
+
+TDEPIMCalendarSource::TDEPIMCalendarSource( TDEPIMCalendarSourceType type, const SyncSourceParams &params ) :
+ TrackingSyncSource(params,1),
+ m_type(type),
+ calendarResPtr(0),
+ calendarPtr(0)
+{
+ //NOTE m_typeName not really used right now
+ switch (m_type) {
+ case TDEPIM_TASKS:
+ m_typeName = "calendar";
+ break;
+ case TDEPIM_TODO:
+ m_typeName = "task list";
+ break;
+ case TDEPIM_JOURNAL:
+ m_typeName = "memo list";
+ break;
+ default:
+ Exception::throwError(SE_HERE, "internal init error, invalid calendar type");
+ break;
+ }
+ //NOTE not really used
+ m_contentMimeType = "text/calendar";
+
+ app = new TDEPIMSyncSource("syncevo-tdepim-cal");
+
+ calendarResPtr = new KCal::CalendarResources( "UTC" );
+ if (!calendarResPtr) {
+ Exception::throwError(SE_HERE, "internal error, can not open the default calendar");
+ }
+
+ calendarResPtr->readConfig();
+ calendarResPtr->setModified(false);
+
+ SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION", " ", m_operations);
+// SE_LOG_DEBUG(getDisplayName(), "TDE calendar for %s (mime type: %s)",
+// m_typeName.latin1(), m_contentMimeType.latin1());
+}
+
+TDEPIMCalendarSource::~TDEPIMCalendarSource() {
+ delete app;
+}
+
+TQString TDEPIMCalendarSource::lastModifiedNormalized(const KCal::Incidence *e)
+{
+ TQDateTime d = e->lastModified();
+ // if no modification date is available, always return the same 0-time stamp
+ // to avoid that 2 calls deliver different times which would be treated as changed entry
+ // this would result in 1.1.1970
+ if (!d.isValid())
+ d.setTime_t(0);
+
+ // We pass UTC, because we open the calendar in UTC
+// return d.toString(TQt::ISODate);
+ return d.toString("yyyyMMddThhmmssZ");
+}
+
+TDEPIMCalendarSource::Databases TDEPIMCalendarSource::getDatabases()
+{
+
+ Databases result;
+ bool first = true;
+
+ KCal::CalendarResourceManager * mgr = calendarResPtr->resourceManager();
+ /*
+ * we pull only active resources so the user has some freedom to decide
+ * what he wants to be visible for sync this will result in setting
+ */
+ for (KRES::Manager<KCal::ResourceCalendar>::ActiveIterator i = mgr->activeBegin(); i != mgr->activeEnd(); i++) {
+
+ std::string name_str(( *i )->resourceName().utf8(),( *i )->resourceName().utf8().length());
+ std::string path_str(( *i )->identifier().utf8(),( *i )->identifier().utf8().length());
+// std::string info_str(( *i )->infoText( ).utf8(),( *i )->infoText( ).utf8().length());
+// SE_LOG_DEBUG(getDisplayName(), "resource: NAME(%s), ID(%s), INFO(%s)",
+// name_str.c_str(), path_str.c_str(), info_str.c_str());
+
+ result.push_back (
+ Database (
+ name_str, // the name of the resource
+ path_str, // the path - (we use the resource uid)
+ first, // default or not
+ ( *i )->readOnly() // read only or not
+ )
+ );
+ first = false;
+ }
+ return result;
+}
+
+void TDEPIMCalendarSource::open()
+{
+
+ std::string id = getDatabaseID();
+// SE_LOG_DEBUG(getDisplayName(), "Search for resource id: %s ", id.c_str() );
+
+ KCal::CalendarResourceManager * mgr = calendarResPtr->resourceManager();
+ /*
+ * we pull only active resources thus user has freedom to decide what wants to be visible for sync
+ */
+ for (KRES::Manager<KCal::ResourceCalendar>::ActiveIterator i = mgr->activeBegin(); i != mgr->activeEnd(); i++) {
+ std::string path_str(( *i )->identifier().utf8(),( *i )->identifier().utf8().length());
+ if ( path_str == id ) {
+// SE_LOG_DEBUG(getDisplayName(), "Resource id: %s found", path_str.c_str() );
+ calendarPtr = ( *i ) ;
+ break;
+ }
+ }
+
+ if ( ! calendarPtr )
+ Exception::throwError(SE_HERE, "internal error, calendar not found");
+
+ if ( ! calendarPtr->load() ) // TODO this fails on vcf resource
+ Exception::throwError(SE_HERE, "internal error, calendar failed loading");
+// SE_LOG_DEBUG(getDisplayName(), "Resource id: %s open OK", id.c_str() );
+}
+
+bool TDEPIMCalendarSource::isEmpty()
+{
+
+ bool status = true;
+ switch (m_type) {
+ case TDEPIM_TASKS:
+ status = calendarPtr->rawEvents( KCal::EventSortUnsorted , KCal::SortDirectionAscending ).isEmpty();
+ break;
+ case TDEPIM_TODO:
+ status = calendarPtr->rawTodos( KCal::TodoSortUnsorted , KCal::SortDirectionAscending ).isEmpty();
+ break;
+ case TDEPIM_JOURNAL:
+ status = calendarPtr->rawJournals( KCal::JournalSortUnsorted , KCal::SortDirectionAscending ).isEmpty();
+ break;
+ default:
+ Exception::throwError(SE_HERE, "internal error, invalid calendar type");
+ break;
+ }
+ return status;
+}
+
+void TDEPIMCalendarSource::close()
+{
+ calendarResPtr->save();
+ calendarPtr->close();
+ delete calendarPtr;
+ calendarPtr = 0;
+}
+
+void TDEPIMCalendarSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisions)
+{
+ KCal::Event::List e;
+ KCal::Todo::List t;
+ KCal::Journal::List j;
+ TQString id;
+ TQString lm;
+
+ switch (m_type) {
+ case TDEPIM_TASKS:
+ e = calendarPtr->rawEvents( KCal::EventSortUnsorted , KCal::SortDirectionAscending );
+ for (KCal::Event::List::ConstIterator i = e.begin(); i != e.end(); i++) {
+ id = (*i)->uid();
+ lm = lastModifiedNormalized((*i));
+ std::string id_str(id.utf8(),id.utf8().length());
+ std::string lm_str(lm.utf8(),lm.utf8().length());
+ revisions[id_str] = lm_str;
+ SE_LOG_DEBUG(getDisplayName(), "Event UID: %s last changed( %s )", id_str.c_str(), lm_str.c_str());
+ }
+ break;
+ case TDEPIM_TODO:
+ t = calendarPtr->rawTodos( KCal::TodoSortUnsorted , KCal::SortDirectionAscending );
+ for (KCal::Todo::List::ConstIterator i = t.begin(); i != t.end(); i++) {
+ id = (*i)->uid();
+ lm = lastModifiedNormalized((*i));
+ std::string id_str(id.utf8(),id.utf8().length());
+ std::string lm_str(lm.utf8(),lm.utf8().length());
+ revisions[id_str] = lm_str;
+ SE_LOG_DEBUG(getDisplayName(), "Todos UID: %s last changed( %s )", id_str.c_str(), lm_str.c_str());
+ }
+ break;
+ case TDEPIM_JOURNAL:
+ j = calendarPtr->rawJournals( KCal::JournalSortUnsorted , KCal::SortDirectionAscending );
+ for (KCal::Journal::List::ConstIterator i = j.begin(); i != j.end(); i++) {
+ id = (*i)->uid();
+ lm = lastModifiedNormalized((*i));
+ std::string id_str(id.utf8(),id.utf8().length());
+ std::string lm_str(lm.utf8(),lm.utf8().length());
+ revisions[id_str] = lm_str;
+ SE_LOG_DEBUG(getDisplayName(), "Journal UID: %s last changed( %s )", id_str.c_str(), lm_str.c_str());
+ }
+ break;
+ default:
+ Exception::throwError(SE_HERE, "internal error, invalid calendar type");
+ break;
+ }
+}
+
+TrackingSyncSource::InsertItemResult TDEPIMCalendarSource::insertItem(const std::string &luid, const std::string &item, bool raw)
+{
+
+ InsertItemResultState state = ITEM_OKAY;
+ TrackingSyncSource::InsertItemResult result;
+ KCal::ICalFormat format;
+ bool replaced = false;
+
+ TQString uid = TQString::fromUtf8(luid.data(), luid.size());
+ TQString data = TQString::fromUtf8(item.data(), item.size());
+
+ /*
+ * Check if item already exists. If yes notify the engine and do nothing here
+ */
+ KCal::Incidence *oldinc = calendarPtr->incidence(uid);
+ if (oldinc) {
+ if ( ! calendarPtr->deleteIncidence(oldinc))
+ Exception::throwError(SE_HERE, "internal error, unable to delete item from calendar");
+// If it was deleted we add it below no need to save now
+// if ( ! calendarPtr->save() )
+// Exception::throwError(SE_HERE, "internal error, unable to save calendar");
+ SE_LOG_DEBUG(getDisplayName(), "Item deleted for merge: ( %s )", uid.latin1() );
+ replaced = true;
+// FIXME ufortunately the ITEM_NEEDS_MERGE does not work well with updated items
+// std::string ret_uid(uid.utf8(), uid.utf8().length());
+// return InsertItemResult(ret_uid, "", ITEM_NEEDS_MERGE);
+ }
+
+ /*
+ * Add to local calendar, so that we may set the uid
+ */
+ KCal::CalendarLocal cal(TQString::fromLatin1( "UTC" ));
+ if (! format.fromString(&cal,data) )
+ Exception::throwError(SE_HERE, "internal error, unable to convert calendar data");
+
+ /*
+ * Add the events from the temporary calendar
+ * We iterate over the list, but it should have only one event.
+ */
+ KCal::Incidence::List itemList = cal.incidences();
+ for (KCal::Incidence::List::ConstIterator i = itemList.begin(); i != itemList.end(); i++) {
+ KCal::Incidence *e = (*i)->clone();
+ if ( replaced )
+ e->setUid( uid );
+ else
+ uid = e->uid();
+ if ( ! calendarPtr->addIncidence(e))
+ Exception::throwError(SE_HERE, "internal error, unable to add item to calendar");
+ if ( ! calendarPtr->save(e) )
+ Exception::throwError(SE_HERE, "internal error, unable to save item to calendar");
+ SE_LOG_DEBUG(getDisplayName(), "Item saved: ( %s )", uid.latin1() );
+ }
+ calendarResPtr->setModified(true);
+
+ KCal::Incidence *newinc = calendarPtr->incidence(uid);
+ if ( ! newinc )
+ Exception::throwError(SE_HERE, "internal error, unable to get item from calendar");
+
+ TQString lm=lastModifiedNormalized(newinc);
+ std::string ret_uid(newinc->uid().utf8(), newinc->uid().utf8().length());
+ std::string ret_rev(lm.utf8(), lm.utf8().length());
+ SE_LOG_DEBUG(getDisplayName(), "Item ( %s : %s ) done.", ret_uid.c_str() , ret_rev.c_str() );
+ return InsertItemResult(ret_uid, ret_rev, state);
+}
+
+void TDEPIMCalendarSource::readItem(const std::string &luid, std::string &item, bool raw)
+{
+ KCal::ICalFormat iCalFmt;
+// NOTE: The libkcal vCal (v.1.0) does not work pretty well - the support is disabled for now
+// KCal::VCalFormat vCalFmt;
+// TQString data = "";
+
+ TQString uid = TQString::fromUtf8(luid.data(),luid.size());
+
+ /* Build a local calendar for the incidence data */
+ KCal::CalendarLocal cal(TQString::fromLatin1( "UTC" ) /*calendarResPtr->timeZoneId()*/);
+
+ switch (m_type) {
+ case TDEPIM_TASKS:
+ cal.addIncidence(calendarPtr->event(uid)->clone());
+ break;
+ case TDEPIM_TODO:
+ cal.addIncidence(calendarPtr->todo(uid)->clone());
+ break;
+ case TDEPIM_JOURNAL:
+ cal.addIncidence(calendarPtr->journal(uid)->clone());
+ break;
+ default:
+ Exception::throwError(SE_HERE, "internal error, invalid calendar type");
+ break;
+ }
+
+ // Convert the data to icalendar
+ TQString data = iCalFmt.toString( &cal );
+
+// it should be possible to use data.utf8() directly, as it returns char array
+// but no time to test so far
+ std::string data_str( data.utf8(), data.utf8().length() );
+ item.assign(data_str.c_str());
+ SE_LOG_DEBUG(getDisplayName(), "Item id ( %s )", luid.c_str() );
+// SE_LOG_DEBUG(getDisplayName(), "TDE calendar Data: %s\n", data_str.c_str() );
+}
+
+
+void TDEPIMCalendarSource::removeItem(const std::string &luid)
+{
+ KCal::Incidence *inc = calendarPtr->incidence(TQString::fromUtf8(luid.data(),luid.size()));
+ if (inc) {
+ calendarPtr->deleteIncidence(inc);
+// Q: do we really need to save it here?
+// A: yes definitely
+// TODO implement save via ticket in future
+ calendarPtr->save();
+ calendarResPtr->setModified(true);
+ }
+ else
+ SE_LOG_DEBUG(getDisplayName(), "Item not found: id=%s", luid.c_str() );
+}
+
+
+std::string TDEPIMCalendarSource::getDescription(const std::string &luid)
+{
+ KCal::Incidence *inc = calendarPtr->incidence(TQString::fromUtf8(luid.data(),luid.size()));
+ if ( inc ) {
+ std::string sum_str(inc->summary().utf8(),inc->summary().utf8().length());
+ return sum_str;
+ }
+ SE_LOG_DEBUG(getDisplayName(), "Resource id(%s) not found", luid.c_str() );
+ return "";
+}
+
+
+void TDEPIMCalendarSource::getSynthesisInfo(SynthesisInfo &info, XMLConfigFragments &fragments)
+{
+ TrackingSyncSource::getSynthesisInfo(info, fragments);
+ info.m_backendRule = "TDE";
+// info.m_backendRule = "LOCALSTORAGE";
+ info.m_beforeWriteScript = "";
+// info.m_profile = "\"vCalendar\", 2";
+}
+
+
+std::string TDEPIMCalendarSource::getMimeType() const
+{
+ return "text/calendar";
+}
+
+std::string TDEPIMCalendarSource::getMimeVersion() const
+{
+ return "2.0";
+}
+
+SE_END_CXX
+
+#endif /* ENABLE_TDEPIMCAL */
+
+#ifdef ENABLE_MODULES
+# include "TDEPIMCalendarSourceRegister.cpp"
+#endif
diff --git a/src/backends/tdepim/TDEPIMCalendarSource.h b/src/backends/tdepim/TDEPIMCalendarSource.h
new file mode 100644
index 00000000..f3f76bf0
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMCalendarSource.h
@@ -0,0 +1,108 @@
+/*
+ *
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * $Id: TDEPIMCalendarSource.h,v 1.7 2016/09/08 22:58:08 emanoil Exp $
+ *
+ */
+
+#ifndef INCL_TDEPIM_CALENDARSOURCE
+#define INCL_TDEPIM_CALENDARSOURCE
+
+#include "config.h"
+
+#include "TDEPIMSyncSource.h"
+
+#ifdef ENABLE_TDEPIMCAL
+
+#include <syncevo/TrackingSyncSource.h>
+
+#include <tqstring.h>
+#include <libkcal/calendarresources.h>
+
+
+SE_BEGIN_CXX
+
+// class TimeTrackingObserver;
+
+typedef enum {
+ TDEPIM_TASKS,
+ TDEPIM_TODO,
+ TDEPIM_JOURNAL
+ } TDEPIMCalendarSourceType;
+
+class TDEPIMCalendarSource : public TrackingSyncSource, public SyncSourceLogging
+{
+public:
+
+// TDEPIMCalendarSource();
+ TDEPIMCalendarSource(TDEPIMCalendarSourceType m_type, const SyncSourceParams &params);
+
+ virtual ~TDEPIMCalendarSource();
+ //
+ // implementation of SyncSource
+ //
+ virtual Databases getDatabases();
+ virtual void open();
+ virtual bool isEmpty();
+ virtual void close();
+ virtual std::string getMimeType() const;
+ virtual std::string getMimeVersion() const;
+
+ /* implementation of TrackingSyncSource interface */
+ virtual void listAllItems(RevisionMap_t &revisions);
+ virtual InsertItemResult insertItem(const string &luid, const std::string &item, bool raw);
+ void readItem(const std::string &luid, std::string &item, bool raw);
+ virtual void removeItem(const string &luid);
+
+ /* implementation of SyncSourceLogging interface */
+ virtual std::string getDescription(const string &luid);
+
+private:
+ TDEPIMCalendarSourceType m_type; /**< use events, tasks or memos? */
+ KCal::CalendarResources *calendarResPtr;
+ KCal::ResourceCalendar *calendarPtr;
+
+ TQString m_typeName; //NOTE not really used
+
+ TDEPIMSyncSource *app;
+
+ /**
+ * The actual type to be used inside the collection. Set after opening
+ * the collection.
+ */
+ TQString m_contentMimeType; //NOTE not really used
+
+ /**
+ * This functions is used internally to normalize the revision field
+ * If no revision is available, always return the same 0-time stamp
+ */
+ TQString lastModifiedNormalized(const KCal::Incidence *e);
+
+ /* All calendar storages must suppport UID/RECURRENCE-ID,
+ * it's part of the API. Therefore we can rely on it.
+ */
+ virtual void getSynthesisInfo(SynthesisInfo &info,
+ XMLConfigFragments &fragments);
+
+};
+
+SE_END_CXX
+
+#endif // ENABLE_TDEPIMCAL
+#endif // INCL_TDEPIM_CALENDARSOURCE
diff --git a/src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp b/src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp
new file mode 100644
index 00000000..e8bf6faa
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPIMCalendarSourceRegister.cpp,v 1.5 2016/09/08 22:58:08 emanoil Exp $
+ *
+ */
+
+
+// #include "TDEPIMNotesSource.h"
+// #include "test.h"
+
+#include "TDEPIMSyncSource.h"
+
+SE_BEGIN_CXX
+
+static SyncSource *createSource ( const SyncSourceParams &params )
+{
+/*
+* NOTE: The libkcal vCal (v.1.0) does not work pretty well I had to leave
+* support only for iCal
+*/
+
+ SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
+
+// SE_LOG_DEBUG("createSource() c1", "Requested Source format %s", sourceType.m_format.c_str());
+// SE_LOG_DEBUG("createSource() c2", "Requested backend type %s", sourceType.m_backend.c_str() );
+
+ bool isMe = sourceType.m_backend == "TDE PIM Calendar";
+#ifndef ENABLE_TDEPIMCAL
+ if (isMe || sourceType.m_backend == "calendar" ) return RegisterSyncSource::InactiveSource(params);
+#else
+ if (isMe || sourceType.m_backend == "calendar" ) {
+ if ( sourceType.m_format == "" ||
+ sourceType.m_format == "text/calendar" /*||
+ sourceType.m_format == "text/x-calendar" ||
+ sourceType.m_format == "text/x-vcalendar"*/ )
+ return new TDEPIMCalendarSource ( TDEPIM_TASKS, params );
+ else return NULL;
+ }
+#endif
+
+ isMe = sourceType.m_backend == "TDE PIM Task List";
+#ifndef ENABLE_TDEPIMCAL
+ if (isMe || sourceType.m_backend == "todo") return RegisterSyncSource::InactiveSource(params);
+#else
+ if (isMe || sourceType.m_backend == "todo") {
+ if ( sourceType.m_format == "" ||
+ sourceType.m_format == "text/calendar" /*||
+ sourceType.m_format == "text/x-calendar" ||
+ sourceType.m_format == "text/x-vcalendar"*/)
+ return new TDEPIMCalendarSource ( TDEPIM_TODO, params );
+ else return NULL;
+ }
+#endif
+
+ isMe = sourceType.m_backend == "TDE PIM Memos";
+#ifndef ENABLE_TDEPIMCAL
+ if (isMe || sourceType.m_backend == "memo") return RegisterSyncSource::InactiveSource(params);
+#else
+ if (isMe || sourceType.m_backend == "memo") {
+ if ( sourceType.m_format == "" ||
+ sourceType.m_format == "text/calendar" /*||
+ sourceType.m_format == "text/x-calendar" ||
+ sourceType.m_format == "text/x-vcalendar"*/)
+ return new TDEPIMCalendarSource ( TDEPIM_JOURNAL, params );
+ else return NULL;
+ }
+#endif
+// SE_LOG_DEBUG("createSource() c6", "Calendar Source matching the format %s not found", sourceType.m_format.c_str() );
+ return NULL;
+}
+
+static class RegisterTDEPIMCalSyncSource : public RegisterSyncSource
+{
+public:
+ RegisterTDEPIMCalSyncSource() :
+ RegisterSyncSource("TDE PIM Calendar/Tasks/Memos",
+#ifdef ENABLE_TDEPIMCAL
+ true,
+#else
+ false,
+#endif
+ createSource,
+ "TDE PIM Calendar = calendar = events = tdepim-events\n"
+ " iCalendar 2.0 (default) = text/calendar\n"
+// " vCalendar 1.0 = text/x-calendar\n"
+// " vCalendar 1.0 = text/x-vcalendar\n"
+ "TDE PIM Task List = TDE Tasks = todo = tasks = tdepim-tasks\n"
+ " iCalendar 2.0 (default) = text/calendar\n"
+// " vCalendar 1.0 = text/x-calendar\n"
+// " vCalendar 1.0 = text/x-vcalendar\n"
+ "TDE PIM Memos = memo = memos = tdepim-memos\n"
+ " iCalendar 2.0 (default) = text/calendar\n"
+ /*" vCalendar 1.0 = text/x-vcalendar\n"
+ " vCalendar 1.0 = text/x-vcalendar\n"*/,
+ Values() +
+ ( Aliases ( "TDE PIM Calendar" ) + "TDE PIM Events" + "calendar" + "events" + "tdepim-calendar" ) +
+ ( Aliases ( "TDE PIM Task List" ) + "TDE PIM Tasks" + "todo" + "todos" + "tasks" + "tdepim-tasks" ) +
+ ( Aliases ( "TDE PIM Memos" ) + "TDE PIM Journal" + "memo" + "memos" + "tdepim-memos" ) )
+ {
+ // configure and register our own property;
+ // do this regardless whether the backend is enabled,
+ // so that config migration always includes this property
+/* WebDAVCredentialsOkay().setHidden(true);
+ SyncConfig::getRegistry().push_back(&WebDAVCredentialsOkay());
+*/
+ }
+} registerMe;
+
+
+SE_END_CXX
diff --git a/src/backends/tdepim/TDEPIMNotesSource.cpp b/src/backends/tdepim/TDEPIMNotesSource.cpp
new file mode 100644
index 00000000..265a3ce7
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMNotesSource.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPIMNotesSource.cpp,v 1.7 2016/09/12 19:57:27 emanoil Exp $
+ *
+ */
+
+// #include <memory>
+// using namespace std;
+
+#include "config.h"
+
+#ifdef ENABLE_TDEPIMNOTES
+
+#include <syncevo/Exception.h>
+#include <syncevo/SmartPtr.h>
+#include <syncevo/Logging.h>
+
+#include <tdeapplication.h>
+#include <kmdcodec.h>
+#include <dcopclient.h>
+
+#include "TDEPIMNotesSource.h"
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+typedef TQString TDENoteID_t;
+
+TDEPIMNotesSource::TDEPIMNotesSource( const SyncSourceParams &params ) :
+ TrackingSyncSource(params,1)
+{
+ //connect to dcop
+ DCOPClient *kn_dcop = TDEApplication::kApplication()->dcopClient();
+ if (!kn_dcop)
+ Exception::throwError(SE_HERE, "internal init error, unable to make new dcop instance for tdenotes");
+
+ appId = kn_dcop->registerAs("knotes-sync");
+
+ //check knotes running
+ QCStringList apps = kn_dcop->registeredApplications();
+ if (!apps.contains("knotes")) {
+ //start knotes if not running
+ knotesWasRunning = false;
+ system("knotes");
+ system("dcop knotes KNotesIface hideAllNotes");
+ SE_LOG_DEBUG(getDisplayName(), "knotes not running started OK");
+ } else {
+ knotesWasRunning = true;
+ SE_LOG_DEBUG(getDisplayName(), "knotes was running OK");
+ }
+
+ kn_iface = new KNotesIface_stub("knotes", "KNotesIface");
+ if ( ! kn_iface )
+ Exception::throwError(SE_HERE, "internal error, KnotesIface");
+/* SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION",
+ " ",
+ m_operations);
+*/
+}
+
+TDEPIMNotesSource::~TDEPIMNotesSource() {
+ if ( ! knotesWasRunning )
+ system("dcop knotes MainApplication-Interface quit");
+ delete kn_iface;
+ kn_iface = NULL;
+ SE_LOG_DEBUG(getDisplayName(), "kNotes exit OK");
+}
+
+TQString TDEPIMNotesSource::stripHtml(TQString input)
+{
+ TQString output = NULL;
+ unsigned int i = 0;
+ int inbraces = 0;
+ for (i = 0; i < input.length(); i++) {
+ TQCharRef cur = input[i];
+ if (cur == '<')
+ inbraces = 1;
+ if (cur == '>') {
+ inbraces = 0;
+ continue;
+ }
+ if (!inbraces)
+ output += input[i];
+ }
+ return output.stripWhiteSpace();
+}
+
+TDEPIMNotesSource::Databases TDEPIMNotesSource::getDatabases()
+{
+
+ Databases result;
+
+ const std::string name("tdenotes");
+ const std::string path("tdepimnotes");
+
+ result.push_back (
+ Database (
+ name, // the name of the resource
+ path, // the path - (we use the resource uid)
+ true, // default or not
+ false // read only or not
+ )
+ );
+
+ SE_LOG_DEBUG(getDisplayName(), "tdenotes getting database %s path: %s", name.c_str(), path.c_str());
+ return result;
+}
+
+void TDEPIMNotesSource::open()
+{
+ std::string id = getDatabaseID();
+ SE_LOG_DEBUG(getDisplayName(), "Resource id: %s opened OK", id.c_str() );
+}
+
+bool TDEPIMNotesSource::isEmpty()
+{
+
+ TQMap <TDENoteID_t,TQString> fNotes = kn_iface->notes();
+ if (kn_iface->status() != DCOPStub::CallSucceeded)
+ Exception::throwError(SE_HERE, "internal error, DCOP call failed");
+
+ TQMap<TDENoteID_t,TQString>::ConstIterator i;
+ for (i = fNotes.begin(); i != fNotes.end(); i++) {
+ if (i.key().length() > 0)
+ return false;
+ }
+ return true;
+}
+
+void TDEPIMNotesSource::close()
+{
+ const std::string id = getDatabaseID();
+ SE_LOG_DEBUG(getDisplayName(), "Resource id: %s closed OK", id.c_str() );
+}
+
+void TDEPIMNotesSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisions)
+{
+
+ KMD5 hash_value;
+ TQMap <TDENoteID_t,TQString> fNotes = kn_iface->notes();
+ if (kn_iface->status() != DCOPStub::CallSucceeded)
+ Exception::throwError(SE_HERE, "internal error, DCOP call failed");
+
+ TQMap<TDENoteID_t,TQString>::ConstIterator i;
+ for (i = fNotes.begin(); i != fNotes.end(); i++) {
+
+ TQString data = i.data() + '\n' + stripHtml(kn_iface->text(i.key()));
+ hash_value.update(data.utf8(),data.utf8().length());
+
+ std::string uid_str(i.key().utf8(),i.key().utf8().length());
+ revisions[uid_str] = hash_value.base64Digest().data();
+ hash_value.reset();
+/* DEBUG
+ SE_LOG_DEBUG(getDisplayName(), "KNotes UID: %s", static_cast<const char*>(i.key().utf8()) );
+ SE_LOG_DEBUG(getDisplayName(), "KNotes DATA: %s", static_cast<const char*>(data.utf8()));
+*/
+ }
+}
+
+TrackingSyncSource::InsertItemResult TDEPIMNotesSource::insertItem(const std::string &luid, const std::string &item, bool raw)
+{
+
+ InsertItemResultState state = ITEM_OKAY;
+ TrackingSyncSource::InsertItemResult result;
+ KMD5 hash_value;
+
+ TQString uid = TQString::fromUtf8(luid.data(), luid.size());
+ TQString data = TQString::fromUtf8(item.data(), item.size());
+
+ // store the hashed value of data to be able to find our new note later and get the id
+ hash_value.update(data.utf8(),data.utf8().length());
+ TQCString rev = hash_value.base64Digest();
+ hash_value.reset();
+
+ TQString summary = data.section('\n', 0, 0); // first line is our title == summary
+ TQString body = data.section('\n', 1); // rest
+/* DEBUG
+ SE_LOG_DEBUG(getDisplayName(), "KNotes SUM : %s", static_cast<const char*>(summary.utf8()) );
+ SE_LOG_DEBUG(getDisplayName(), "KNotes BODY: %s", static_cast<const char*>(body.utf8()) );
+ */
+ TQString newuid;
+
+ TQString d = kn_iface->text( uid );
+ if ( d.length() > 0 ) { // we have this note
+ kn_iface->setName( uid, summary );
+ kn_iface->setText( uid, body );
+ newuid = uid;
+ }
+ else {
+ newuid = kn_iface->newNote( summary, body );
+ if (kn_iface->status() != DCOPStub::CallSucceeded)
+ Exception::throwError(SE_HERE, "internal error, DCOP call failed");
+ if ( ! newuid.length() > 0 )
+ Exception::throwError(SE_HERE, "internal error, add note failed");
+ }
+
+ std::string ret_uid(newuid.utf8(), newuid.utf8().length());
+ return InsertItemResult(ret_uid, rev.data(), state);
+
+}
+
+void TDEPIMNotesSource::readItem(const std::string &luid, std::string &item, bool raw)
+{
+ TQString uid = TQString::fromUtf8(luid.data(),luid.size());
+ TQString data = kn_iface->name( uid ) + '\n' + stripHtml(kn_iface->text( uid ));
+
+ std::string data_str( data.utf8(), data.utf8().length() );
+ item.assign( data_str.c_str() );
+}
+
+void TDEPIMNotesSource::removeItem(const std::string &luid)
+{
+ TQString uid = TQString::fromUtf8(luid.data(),luid.size());
+ TQString data = kn_iface->text( uid );
+ if ( data.length() > 0 ) {
+ kn_iface->killNote( uid );
+ if (kn_iface->status() != DCOPStub::CallSucceeded)
+ Exception::throwError(SE_HERE, "internal error, DCOP call failed");
+ }
+ else
+ SE_LOG_DEBUG(getDisplayName(), "Item not found: id=%s", luid.c_str() );
+}
+
+std::string TDEPIMNotesSource::getDescription(const std::string &luid)
+{
+ TQString uid = TQString::fromUtf8(luid.data(),luid.size());
+ TQString data = kn_iface->name( uid );
+ if ( data.length() > 0 ) {
+ std::string sum_str(data.utf8(),data.utf8().length());
+ return sum_str;
+ }
+ SE_LOG_DEBUG(getDisplayName(), "Resource id(%s) not found", luid.c_str() );
+ return "";
+}
+
+void TDEPIMNotesSource::getSynthesisInfo(SynthesisInfo &info, XMLConfigFragments &fragments)
+{
+ TrackingSyncSource::getSynthesisInfo(info, fragments);
+ info.m_backendRule = "TDE";
+ info.m_beforeWriteScript = "";
+}
+
+SE_END_CXX
+
+#endif /* ENABLE_TDEPIMNOTES */
+
+#ifdef ENABLE_MODULES
+# include "TDEPIMNotesSourceRegister.cpp"
+#endif
diff --git a/src/backends/tdepim/TDEPIMNotesSource.h b/src/backends/tdepim/TDEPIMNotesSource.h
new file mode 100644
index 00000000..d8b1809a
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMNotesSource.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPIMNotesSource.h,v 1.5 2016/09/08 22:58:08 emanoil Exp $
+ *
+ */
+
+#ifndef INCL_TDEPIMNOTESSOURCE
+#define INCL_TDEPIMNOTESSOURCE
+
+#include "config.h"
+
+#include "KNotesIface_stub.h"
+#include <syncevo/TrackingSyncSource.h>
+
+#include <syncevo/declarations.h>
+SE_BEGIN_CXX
+
+#ifdef ENABLE_TDEPIMNOTES
+
+/**
+ * Implements access to TDE memo lists (stored as knotes items),
+ * exporting/importing the memos in plain UTF-8 text.
+ */
+class TDEPIMNotesSource : public TrackingSyncSource, public SyncSourceLogging
+{
+ public:
+ TDEPIMNotesSource( const SyncSourceParams &params );
+ virtual ~TDEPIMNotesSource();
+ //
+ // implementation of SyncSource
+ //
+ virtual Databases getDatabases();
+ virtual void open();
+ virtual bool isEmpty();
+ virtual void close();
+ virtual std::string getMimeType() const { return "text/plain"; }
+ virtual std::string getMimeVersion() const { return "1.0"; }
+
+ /* implementation of TrackingSyncSource interface */
+ virtual void listAllItems(RevisionMap_t &revisions);
+ virtual InsertItemResult insertItem(const string &luid, const std::string &item, bool raw);
+ void readItem(const std::string &luid, std::string &item, bool raw);
+ virtual void removeItem(const string &luid);
+
+ /* implementation of SyncSourceLogging interface */
+ virtual std::string getDescription(const string &luid);
+
+private:
+ TQString appId;
+
+ KNotesIface_stub *kn_iface;
+ DCOPClient *kn_dcop;
+
+ /** Ugly hack to restart KNotes if it was running */
+ bool knotesWasRunning;
+
+ /**
+ * This functions is used internally to strip HTML from the note
+ */
+ static TQString stripHtml(TQString input);
+
+ /**
+ * Implement some brief information extraction from the note
+ */
+ virtual void getSynthesisInfo(SynthesisInfo &info,
+ XMLConfigFragments &fragments);
+
+};
+
+#endif // ENABLE_TDEPIMNOTES
+
+
+SE_END_CXX
+#endif // INCL_TDEPIMNOTESSOURCE
diff --git a/src/backends/tdepim/TDEPIMNotesSourceRegister.cpp b/src/backends/tdepim/TDEPIMNotesSourceRegister.cpp
new file mode 100644
index 00000000..7a5152b7
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMNotesSourceRegister.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ *
+ * $Id: TDEPIMNotesSourceRegister.cpp,v 1.5 2016/09/12 19:57:27 emanoil Exp $
+ *
+ */
+
+
+#include "TDEPIMNotesSource.h"
+// #include "test.h"
+
+#include "TDEPIMSyncSource.h"
+
+SE_BEGIN_CXX
+
+static SyncSource *createSource ( const SyncSourceParams &params )
+{
+
+ SourceType sourceType = SyncSource::getSourceType(params.m_nodes);
+
+// SE_LOG_DEBUG("createSource() c1", "Requested Source format %s", sourceType.m_format.c_str());
+// SE_LOG_DEBUG("createSource() c2", "Requested backend type %s", sourceType.m_backend.c_str() );
+
+ bool isMe = sourceType.m_backend == "TDE PIM Notes";
+#ifndef ENABLE_TDEPIMNOTES
+ if (isMe) return RegisterSyncSource::InactiveSource(params);
+#else
+ if (isMe) {
+// SE_LOG_DEBUG("createSource() c3", "Calendar Source format %s", sourceType.m_format.c_str());
+ if ( sourceType.m_format == "" || sourceType.m_format == "text/plain" )
+ return new TDEPIMNotesSource ( params );
+ else return NULL;
+ }
+#endif
+
+// SE_LOG_DEBUG("createSource() c6", "Calendar Source matching the format %s not found", sourceType.m_format.c_str() );
+ return NULL;
+}
+
+static class RegisterTDEPIMNotesSyncSource : public RegisterSyncSource
+{
+public:
+ RegisterTDEPIMNotesSyncSource() :
+ RegisterSyncSource("TDE PIM Notes",
+#ifdef ENABLE_TDEPIMCAL
+ true,
+#else
+ false,
+#endif
+ createSource,
+ "TDE PIM Notes = note = notes = tdepim-notes\n"
+ " plain text in UTF-8 (default) = text/plain\n",
+ Values() +
+ ( Aliases ( "TDE PIM Notes" ) + "note" + "notes" + "tdepim-notes" ) )
+ {
+ // configure and register our own property;
+ // do this regardless whether the backend is enabled,
+ // so that config migration always includes this property
+/* WebDAVCredentialsOkay().setHidden(true);
+ SyncConfig::getRegistry().push_back(&WebDAVCredentialsOkay());
+*/
+ }
+} registerMe;
+
+// TODO finish unit tests
+
+SE_END_CXX
diff --git a/src/backends/tdepim/TDEPIMSyncSource.cpp b/src/backends/tdepim/TDEPIMSyncSource.cpp
new file mode 100644
index 00000000..5292801d
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMSyncSource.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+
+ This application 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 application 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 application; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ * $Id: TDEPIMSyncSource.cpp,v 1.4 2016/09/08 22:58:09 emanoil Exp $
+ */
+
+#include "TDEPIMSyncSource.h"
+
+#include <syncevo/Logging.h>
+#include <tdeaboutdata.h>
+#include <tdecmdlineargs.h>
+
+SE_BEGIN_CXX
+
+TDEPIMSyncSource::TDEPIMSyncSource(TQString name) :
+ tdeappPtr(0)
+{
+ m_name = name;
+ newApp = false;
+ TDEAboutData aboutData(
+ m_name.latin1(), // internal program name
+ "SyncEvolution-TDEPIM-plugin", // displayable program name.
+ "0.1", // version string
+ "SyncEvolution TDEPIM plugin", // short porgram description
+ TDEAboutData::License_GPL, // license type
+ "(c) 2016, emanoil.kotsev@fincom.at" // copyright statement
+ );
+
+ static const char *argv[] = { "SyncEvolution" };
+ static int argc = 1;
+
+ TDECmdLineArgs::init(argc, (char **)argv, &aboutData );
+ // Don't allow TDEApplication to mess with SIGINT/SIGTERM.
+ // Restore current behavior after construction.
+ struct sigaction oldsigint, oldsigterm;
+ sigaction(SIGINT, NULL, &oldsigint);
+ sigaction(SIGTERM, NULL, &oldsigterm);
+ if ( kapp ) {
+ tdeappPtr = kapp;
+ } else {
+ tdeappPtr = new TDEApplication( false, false );
+ newApp=true;
+ }
+ // restore
+ sigaction(SIGINT, &oldsigint, NULL);
+ sigaction(SIGTERM, &oldsigterm, NULL);
+
+// SE_LOG_DEBUG(NULL, "TDE base created OK");
+}
+
+TDEPIMSyncSource::~TDEPIMSyncSource()
+{
+ if ( newApp ) {
+ delete tdeappPtr;
+ tdeappPtr = 0;
+ }
+// SE_LOG_DEBUG(NULL, "TDE base destroyed OK");
+}
+
+
+SE_END_CXX
diff --git a/src/backends/tdepim/TDEPIMSyncSource.h b/src/backends/tdepim/TDEPIMSyncSource.h
new file mode 100644
index 00000000..bbddd38b
--- /dev/null
+++ b/src/backends/tdepim/TDEPIMSyncSource.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 Emanoil Kotsev emanoil.kotsev@fincom.at
+
+ This application 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 application 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 application; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ * $Id: TDEPIMSyncSource.h,v 1.2 2016/09/01 10:40:06 emanoil Exp $
+ *
+ */
+
+#ifndef TDEPIMSYNCSOURCE_H
+#define TDEPIMSYNCSOURCE_H
+
+// #include "config.h"
+
+//#ifdef ENABLE_TDEPIM
+
+#include <tdeapplication.h>
+#include <syncevo/util.h>
+
+/**
+ * General purpose TDEPIM Sync Source.
+ */
+
+SE_BEGIN_CXX
+
+class TDEPIMSyncSource
+{
+public:
+
+ TDEPIMSyncSource(TQString);
+
+ ~TDEPIMSyncSource();
+
+private:
+ TDEApplication *tdeappPtr;
+ TQString m_name;
+ bool newApp;
+
+};
+
+SE_END_CXX
+//#endif // ENABLE_TDEPIM
+#endif // TDEPIMSYNCSOURCE_H
diff --git a/src/backends/tdepim/configure-sub.in b/src/backends/tdepim/configure-sub.in
new file mode 100644
index 00000000..9f074510
--- /dev/null
+++ b/src/backends/tdepim/configure-sub.in
@@ -0,0 +1,144 @@
+dnl -*- mode: Autoconf; -*-
+dnl Invoke autogen.sh to produce a configure script.
+
+TDEPIMFOUND=no
+TDEPIMCALFOUND=no
+TDEPIMABCFOUND=no
+TDEPIMDCOPFOUND=no
+TDEPIMNOTESFOUND=no
+
+AC_CHECK_PROGS([TQMAKE], [tqmake tqmake])
+PKG_CHECK_MODULES(TQT, tqt, TQTFOUND=yes, [TQTFOUND=no])
+
+# Check for TDEPIM. There is no .pc file for it,
+# so fall back to normal header file and library checking.
+# libtdepim1-trinity-dev and tdelibs14-trinity-dev >= 14.0.2 provides the necessary files.
+# it could be backwords compat but we do not guarantee success
+
+if ! test "$TDEPIM_CFLAGS"; then
+ TDEPIM_CFLAGS="-I/opt/trinity/include"
+ if test "$TQMAKE"; then
+ TDEPIM_CFLAGS="$TDEPIM_CFLAGS $TQT_CFLAGS"
+ fi
+fi
+if ! test "$TDEPIM_LIBS"; then
+ TDEPIM_LIBS="-L/opt/trinity/lib"
+ if test "$TQMAKE"; then
+ TDEPIM_LIBS="$TDEPIM_LIBS $TQT_LIBS"
+ fi
+fi
+
+AC_LANG_PUSH(C++)
+old_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $TDEPIM_CFLAGS"
+AC_CHECK_HEADERS(libkcal/calendarresources.h, [TDEPIMCALFOUND=yes], [TDEPIMCALFOUND=no], [])
+CPPFLAGS="$old_CPPFLAGS"
+AC_LANG_POP(C++)
+
+AC_LANG_PUSH(C++)
+old_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $TDEPIM_CFLAGS"
+AC_CHECK_HEADERS(tdeabc/stdaddressbook.h, [TDEPIMABCFOUND=yes], [TDEPIMABCFOUND=no], [])
+CPPFLAGS="$old_CPPFLAGS"
+AC_LANG_POP(C++)
+
+AC_LANG_PUSH(C++)
+old_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $TDEPIM_CFLAGS"
+AC_CHECK_HEADERS(dcopclient.h, [TDEPIMDCOPFOUND=yes], [TDEPIMDCOPFOUND=no], [])
+CPPFLAGS="$old_CPPFLAGS"
+AC_LANG_POP(C++)
+
+AC_LANG_PUSH(C++)
+old_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $TDEPIM_CFLAGS"
+AC_CHECK_HEADERS(KNotesIface.h, [TDEPIMNOTESFOUND=yes], [TDEPIMNOTESFOUND=no], [])
+CPPFLAGS="$old_CPPFLAGS"
+AC_LANG_POP(C++)
+
+# In contrast to the Evolution backend, the tdepim backend is
+# currently considered optional. "configure" will enable it only
+# if explicitly enabled
+SE_ARG_ENABLE_BACKEND(tdepimcal, tdepim,
+ [AS_HELP_STRING([--enable-tdepimcal],
+ [enable access to PIM calendar in TDE (default off)])],
+ [enable_tdepimcal="$enableval"], [enable_tdepimcal="no"]
+ )
+SE_ARG_ENABLE_BACKEND(tdepimabc, tdepim,
+ [AS_HELP_STRING([--enable-tdepimabc],
+ [enable access to PIM addressbook in TDE (default off)])],
+ [enable_tdepimabc="$enableval"], [enable_tdepimabc="no"]
+ )
+
+SE_ARG_ENABLE_BACKEND(tdepimnotes, tdepim,
+ [AS_HELP_STRING([--enable-tdepimnotes],
+ [enable access to TDE NOTES (default off)])],
+ [enable_tdepimnotes="$enableval"], [enable_tdepimnotes="no"]
+ )
+#if test "x${TDEPIMCALFOUND}" = "xyes" && test "x${TDEPIMABCFOUND}" = "xyes" && test "x${TDEPIMDCOPFOUND}" = "xyes"; then
+# TDEPIMFOUND="yes"
+#fi
+
+if test $enable_tdepimcal = yes ; then
+ test $TDEPIMCALFOUND = yes || AC_MSG_ERROR([--enable-tdepimcal requires packages libtdepim1-trinity-dev,
+ tdelibs14-trinity-dev, but they were not found])
+ AC_DEFINE(ENABLE_TDEPIMCAL, 1, [TDE PIM Calendar available])
+else
+ # avoid unneeded dependencies on TDEPIM
+ TDEPIMCAL_CFLAGS=
+ TDEPIMCAL_LIBS=
+fi
+
+if test $enable_tdepimabc = yes ; then
+ test $TDEPIMABCFOUND = yes || AC_MSG_ERROR([--enable-tdepimabc requires packages libtdepim1-trinity-dev,
+ tdelibs14-trinity-dev, but they were not found])
+ AC_DEFINE(ENABLE_TDEPIMABC, 1, [TDE PIM Address Book available])
+else
+ # avoid unneeded dependencies on TDEPIM
+ TDEPIMABC_CFLAGS=
+ TDEPIMABC_LIBS=
+fi
+
+if test $enable_tdepimnotes = yes ; then
+ test $TDEPIMNOTESFOUND = yes || AC_MSG_ERROR([--enable-tdepimnotes requires packages tdelibs14-trinity-dev,
+ tdepim-trinity-dev, but they were not found])
+ AC_DEFINE(ENABLE_TDEPIMNOTES, 1, [TDE PIM Address Book available])
+else
+ # avoid unneeded dependencies on TDEPIM
+ TDEPIMNOTES_CFLAGS=
+ TDEPIMNOTES_LIBS=
+fi
+
+if test "x${TDEPIMCALFOUND}" = "xyes"; then
+ TDEPIMCAL_CFLAGS="$TDEPIM_CFLAGS"
+ TDEPIMCAL_LIBS="$TDEPIM_LIBS -ltdecore -lkcal -ltderesources"
+fi
+
+if test "x${TDEPIMABCFOUND}" = "xyes"; then
+ TDEPIMABC_CFLAGS="$TDEPIM_CFLAGS"
+ TDEPIMABC_LIBS="$TDEPIM_LIBS -ltdecore -ltdeabc -ltderesources"
+fi
+
+if test "x${TDEPIMDCOPFOUND}" = "xyes"; then
+ TDEPIMNOTES_CFLAGS="$TDEPIM_CFLAGS -I."
+ TDEPIMNOTES_LIBS="$TDEPIM_LIBS -L. -ltdecore -lDCOP"
+fi
+
+AC_SUBST(TDEPIMCAL_LIBS)
+AC_SUBST(TDEPIMABC_LIBS)
+AC_SUBST(TDEPIMNOTES_LIBS)
+AC_SUBST(TDEPIMCAL_CFLAGS)
+AC_SUBST(TDEPIMABC_CFLAGS)
+AC_SUBST(TDEPIMNOTES_CFLAGS)
+
+# conditional compilation in make
+AM_CONDITIONAL([ENABLE_TDEPIMCAL], [test "$enable_tdepimcal" = "yes"])
+AM_CONDITIONAL([ENABLE_TDEPIMABC], [test "$enable_tdepimabc" = "yes"])
+AM_CONDITIONAL([ENABLE_TDEPIMNOTES], [test "$enable_tdepimnotes" = "yes"])
+
+# # let others include TDEPIM backend's header file
+# # (not strictly necessary, could be avoided by not
+# # including TDEPIM header files in public header file
+# # of source)
+
+BACKEND_CPPFLAGS="$BACKEND_CPPFLAGS $TDEPIMCAL_CFLAGS $TDEPIMABC_CFLAGS $TDEPINOTES_CFLAGS"
diff --git a/src/backends/tdepim/tdepim.am b/src/backends/tdepim/tdepim.am
new file mode 100644
index 00000000..e26e375e
--- /dev/null
+++ b/src/backends/tdepim/tdepim.am
@@ -0,0 +1,65 @@
+dist_noinst_DATA += src/backends/tdepim/configure-sub.in \
+ src/backends/tdepim/README
+
+src_backends_tdepim_lib = src/backends/tdepim/synctdepimcal.la \
+ src/backends/tdepim/synctdepimabc.la \
+ src/backends/tdepim/synctdepimnotes.la
+
+MOSTLYCLEANFILES += $(src_backends_tdepim_lib)
+if ENABLE_MODULES
+src_backends_tdepim_backenddir = $(BACKENDS_DIRECTORY)
+src_backends_tdepim_backend_LTLIBRARIES = $(src_backends_tdepim_lib)
+else
+noinst_LTLIBRARIES += $(src_backends_tdepim_lib)
+endif
+
+src_backends_tdepim_synctdepimcal_src = \
+ src/backends/tdepim/TDEPIMSyncSource.h \
+ src/backends/tdepim/TDEPIMSyncSource.cpp \
+ src/backends/tdepim/TDEPIMCalendarSource.h \
+ src/backends/tdepim/TDEPIMCalendarSource.cpp \
+ $(NOP)
+
+src_backends_tdepim_synctdepimabc_src = \
+ src/backends/tdepim/TDEPIMSyncSource.h \
+ src/backends/tdepim/TDEPIMSyncSource.cpp \
+ src/backends/tdepim/TDEPIMAddressBookSource.h \
+ src/backends/tdepim/TDEPIMAddressBookSource.cpp
+
+src_backends_tdepim_synctdepimnotes_src = \
+ src/backends/tdepim/TDEPIMSyncSource.h \
+ src/backends/tdepim/TDEPIMSyncSource.cpp \
+ src/backends/tdepim/KNotesIface_stub.h \
+ src/backends/tdepim/KNotesIface_stub.cpp \
+ src/backends/tdepim/TDEPIMNotesSource.h \
+ src/backends/tdepim/TDEPIMNotesSource.cpp
+
+src_backends_tdepim_cppflags = \
+ $(SYNCEVOLUTION_CFLAGS) \
+ -I$(top_srcdir)/test \
+ $(BACKEND_CPPFLAGS) \
+ -I$(top_srcdir)/src/backends/tdepim
+
+#src_backends_tdepim_src = $(src_backends_tdepim_synctdepimcal_src) $(src_backends_tdepim_synctdepimabc_src)
+
+src_backends_tdepim_synctdepimcal_la_SOURCES = $(src_backends_tdepim_synctdepimcal_src)
+src_backends_tdepim_synctdepimcal_la_LIBADD = $(TDEPIMCAL_LIBS) $(SYNCEVOLUTION_LIBS)
+src_backends_tdepim_synctdepimcal_la_CPPFLAGS = $(TDEPIMCAL_CFLAGS) $(src_backends_tdepim_cppflags)
+src_backends_tdepim_synctdepimcal_la_LDFLAGS = -module -avoid-version -ldl
+src_backends_tdepim_synctdepimcal_la_CXXFLAGS = $(TDEPIMCAL_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(SYNCEVO_WFLAGS) $(src_backends_tdepim_cppflags)
+src_backends_tdepim_synctdepimcal_la_DEPENDENCIES = src/syncevo/libsyncevolution.la
+
+src_backends_tdepim_synctdepimabc_la_SOURCES = $(src_backends_tdepim_synctdepimabc_src)
+src_backends_tdepim_synctdepimabc_la_LIBADD = $(TDEPIMABC_LIBS) $(SYNCEVOLUTION_LIBS)
+src_backends_tdepim_synctdepimabc_la_LDFLAGS = -module -avoid-version
+src_backends_tdepim_synctdepimabc_la_CXXFLAGS = $(TDEPIMABC_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(SYNCEVO_WFLAGS) $(src_backends_tdepim_cppflags)
+src_backends_tdepim_synctdepimabc_la_CPPFLAGS = $(TDEPIMABC_CFLAGS) $(src_backends_tdepim_cppflags)
+src_backends_tdepim_synctdepimabc_la_DEPENDENCIES = src/syncevo/libsyncevolution.la
+
+src_backends_tdepim_synctdepimnotes_la_SOURCES = $(src_backends_tdepim_synctdepimnotes_src)
+src_backends_tdepim_synctdepimnotes_la_LIBADD = $(TDEPIMNOTES_LIBS) $(TDEPIM_LIBS) $(SYNCEVOLUTION_LIBS)
+src_backends_tdepim_synctdepimnotes_la_LDFLAGS = -module -avoid-version
+src_backends_tdepim_synctdepimnotes_la_CXXFLAGS = $(TDEPIMCAL_CFLAGS) $(TDEPIM_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(SYNCEVO_WFLAGS)
+src_backends_tdepim_synctdepimnotes_la_CPPFLAGS = $(TDEPIMCAL_CFLAGS) $(TDEPIM_CFLAGS) $(src_backends_tdepim_cppflags)
+# $(src_backends_tdepim_synctdepimnotes_cppflags)
+src_backends_tdepim_synctdepimnotes_la_DEPENDENCIES = src/syncevo/libsyncevolution.la