From cb34f4972bcbde44b8dc702fff3a7d791a317fc0 Mon Sep 17 00:00:00 2001 From: deloptes Date: Mon, 26 Sep 2016 21:07:55 +0200 Subject: tde, tdepim: backend for the TDE desktop (FDO #97780) This is the code for TDE < 14.1. --- src/backends/tde/TDEPlatform.cpp | 198 +++++++++++ src/backends/tde/TDEPlatform.h | 51 +++ src/backends/tde/TDEPlatformRegister.cpp | 48 +++ src/backends/tde/configure-sub.in | 60 ++++ src/backends/tde/tde.am | 23 ++ src/backends/tdepim/KNotesIface_stub.cpp | 302 ++++++++++++++++ src/backends/tdepim/KNotesIface_stub.h | 45 +++ src/backends/tdepim/README | 171 +++++++++ src/backends/tdepim/TDEPIMAddressBookSource.cpp | 389 ++++++++++++++++++++ src/backends/tdepim/TDEPIMAddressBookSource.h | 134 +++++++ .../tdepim/TDEPIMAddressBookSourceRegister.cpp | 76 ++++ src/backends/tdepim/TDEPIMCalendarSource.cpp | 393 +++++++++++++++++++++ src/backends/tdepim/TDEPIMCalendarSource.h | 108 ++++++ .../tdepim/TDEPIMCalendarSourceRegister.cpp | 127 +++++++ src/backends/tdepim/TDEPIMNotesSource.cpp | 266 ++++++++++++++ src/backends/tdepim/TDEPIMNotesSource.h | 91 +++++ src/backends/tdepim/TDEPIMNotesSourceRegister.cpp | 83 +++++ src/backends/tdepim/TDEPIMSyncSource.cpp | 76 ++++ src/backends/tdepim/TDEPIMSyncSource.h | 56 +++ src/backends/tdepim/configure-sub.in | 144 ++++++++ src/backends/tdepim/tdepim.am | 65 ++++ 21 files changed, 2906 insertions(+) create mode 100644 src/backends/tde/TDEPlatform.cpp create mode 100644 src/backends/tde/TDEPlatform.h create mode 100644 src/backends/tde/TDEPlatformRegister.cpp create mode 100644 src/backends/tde/configure-sub.in create mode 100644 src/backends/tde/tde.am create mode 100644 src/backends/tdepim/KNotesIface_stub.cpp create mode 100644 src/backends/tdepim/KNotesIface_stub.h create mode 100644 src/backends/tdepim/README create mode 100644 src/backends/tdepim/TDEPIMAddressBookSource.cpp create mode 100644 src/backends/tdepim/TDEPIMAddressBookSource.h create mode 100644 src/backends/tdepim/TDEPIMAddressBookSourceRegister.cpp create mode 100644 src/backends/tdepim/TDEPIMCalendarSource.cpp create mode 100644 src/backends/tdepim/TDEPIMCalendarSource.h create mode 100644 src/backends/tdepim/TDEPIMCalendarSourceRegister.cpp create mode 100644 src/backends/tdepim/TDEPIMNotesSource.cpp create mode 100644 src/backends/tdepim/TDEPIMNotesSource.h create mode 100644 src/backends/tdepim/TDEPIMNotesSourceRegister.cpp create mode 100644 src/backends/tdepim/TDEPIMSyncSource.cpp create mode 100644 src/backends/tdepim/TDEPIMSyncSource.h create mode 100644 src/backends/tdepim/configure-sub.in create mode 100644 src/backends/tdepim/tdepim.am 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 + +#ifdef ENABLE_TDEWALLET + +#include "TDEPlatform.h" + +#include +#include +#include + +#include +#include +#include + +#include + +#include +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(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 , 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 + +#include + +#include + +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 + +#ifdef ENABLE_TDEWALLET + +#include "TDEPlatform.h" +#include +#include + +#include +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 + +#include + + +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 KNotesIface_stub::notes() +{ + TQMap result; + if ( !dcopClient() ) { + setStatus( CallFailed ); + return result; + } + TQByteArray data, replyData; + TQCString replyType; + if ( dcopClient()->call( app(), obj(), "notes()", data, replyType, replyData ) ) { + if ( replyType == "TQMap" ) { + 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 +#include +#include +#include + + +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 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) +/syncevolution/configure --with-synthesis-src=/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 +#include +#include + +#include +#include + + +SE_BEGIN_CXX + +TDEPIMAddressBookSource::TDEPIMAddressBookSource( TDEPIMAddressBookSourceType type, const SyncSourceParams ¶ms) : + 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("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 lit = addressbookPtr->resources(); + TQPtrListIterator 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 lit = addressbookPtr->resources(); + TQPtrListIterator 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 + +#include +#include + +#include +#include + + +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 ¶ms) ; + + 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 ¶ms) +{ + 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 +#include +#include + +#include +//#include +#include + +SE_BEGIN_CXX + +// "PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN" +// "VERSION:2.0" + +TDEPIMCalendarSource::TDEPIMCalendarSource( TDEPIMCalendarSourceType type, const SyncSourceParams ¶ms ) : + 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("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::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::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 + +#include +#include + + +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 ¶ms); + + 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 ¶ms ) +{ +/* +* 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 +// using namespace std; + +#include "config.h" + +#ifdef ENABLE_TDEPIMNOTES + +#include +#include +#include + +#include +#include +#include + +#include "TDEPIMNotesSource.h" + +#include +SE_BEGIN_CXX + +typedef TQString TDENoteID_t; + +TDEPIMNotesSource::TDEPIMNotesSource( const SyncSourceParams ¶ms ) : + 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("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 fNotes = kn_iface->notes(); + if (kn_iface->status() != DCOPStub::CallSucceeded) + Exception::throwError(SE_HERE, "internal error, DCOP call failed"); + + TQMap::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 fNotes = kn_iface->notes(); + if (kn_iface->status() != DCOPStub::CallSucceeded) + Exception::throwError(SE_HERE, "internal error, DCOP call failed"); + + TQMap::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(i.key().utf8()) ); + SE_LOG_DEBUG(getDisplayName(), "KNotes DATA: %s", static_cast(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(summary.utf8()) ); + SE_LOG_DEBUG(getDisplayName(), "KNotes BODY: %s", static_cast(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 + +#include +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 ¶ms ); + 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 ¶ms ) +{ + + 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 +#include +#include + +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 +#include + +/** + * 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 -- cgit v1.2.3