summaryrefslogtreecommitdiffstats
path: root/kabc/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'kabc/plugins')
-rw-r--r--kabc/plugins/Makefile.am1
-rw-r--r--kabc/plugins/dir/Makefile.am28
-rw-r--r--kabc/plugins/dir/dir.desktop92
-rw-r--r--kabc/plugins/dir/resourcedir.cpp310
-rw-r--r--kabc/plugins/dir/resourcedir.h113
-rw-r--r--kabc/plugins/dir/resourcedirconfig.cpp107
-rw-r--r--kabc/plugins/dir/resourcedirconfig.h54
-rw-r--r--kabc/plugins/dir/resourcedirplugin.cpp32
-rw-r--r--kabc/plugins/evolution/Makefile.am19
-rw-r--r--kabc/plugins/evolution/README15
-rw-r--r--kabc/plugins/evolution/dbwrapper.cpp187
-rw-r--r--kabc/plugins/evolution/dbwrapper.h60
-rw-r--r--kabc/plugins/evolution/evolution.desktop26
-rw-r--r--kabc/plugins/evolution/resourceevo.cpp132
-rw-r--r--kabc/plugins/evolution/resourceevo.h23
-rw-r--r--kabc/plugins/file/Makefile.am28
-rw-r--r--kabc/plugins/file/file.desktop82
-rw-r--r--kabc/plugins/file/resourcefile.cpp395
-rw-r--r--kabc/plugins/file/resourcefile.h162
-rw-r--r--kabc/plugins/file/resourcefileconfig.cpp118
-rw-r--r--kabc/plugins/file/resourcefileconfig.h57
-rw-r--r--kabc/plugins/file/resourcefileplugin.cpp32
-rw-r--r--kabc/plugins/ldapkio/Makefile.am28
-rw-r--r--kabc/plugins/ldapkio/ldapkio.desktop10
-rw-r--r--kabc/plugins/ldapkio/resourceldapkio.cpp1041
-rw-r--r--kabc/plugins/ldapkio/resourceldapkio.h171
-rw-r--r--kabc/plugins/ldapkio/resourceldapkioconfig.cpp388
-rw-r--r--kabc/plugins/ldapkio/resourceldapkioconfig.h118
-rw-r--r--kabc/plugins/ldapkio/resourceldapkioplugin.cpp36
-rw-r--r--kabc/plugins/net/Makefile.am28
-rw-r--r--kabc/plugins/net/net.desktop90
-rw-r--r--kabc/plugins/net/resourcenet.cpp390
-rw-r--r--kabc/plugins/net/resourcenet.h117
-rw-r--r--kabc/plugins/net/resourcenetconfig.cpp102
-rw-r--r--kabc/plugins/net/resourcenetconfig.h53
-rw-r--r--kabc/plugins/net/resourcenetplugin.cpp32
-rw-r--r--kabc/plugins/sql/Makefile.am20
-rw-r--r--kabc/plugins/sql/resourcesql.cpp338
-rw-r--r--kabc/plugins/sql/resourcesql.h63
-rw-r--r--kabc/plugins/sql/resourcesqlconfig.cpp95
-rw-r--r--kabc/plugins/sql/resourcesqlconfig.h51
-rw-r--r--kabc/plugins/sql/sql.desktop10
42 files changed, 5254 insertions, 0 deletions
diff --git a/kabc/plugins/Makefile.am b/kabc/plugins/Makefile.am
new file mode 100644
index 000000000..4024cc9f9
--- /dev/null
+++ b/kabc/plugins/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = file dir ldapkio
diff --git a/kabc/plugins/dir/Makefile.am b/kabc/plugins/dir/Makefile.am
new file mode 100644
index 000000000..bf07e6af3
--- /dev/null
+++ b/kabc/plugins/dir/Makefile.am
@@ -0,0 +1,28 @@
+INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc -I$(top_builddir) $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = resourcedirconfig.h
+
+lib_LTLIBRARIES = libkabc_dir.la
+libkabc_dir_la_SOURCES = resourcedir.cpp resourcedirconfig.cpp
+libkabc_dir_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined
+libkabc_dir_la_LIBADD = $(LIB_KABC)
+libkabc_dir_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h
+
+kde_module_LTLIBRARIES = kabc_dir.la
+kabc_dir_la_SOURCES = resourcedirplugin.cpp
+kabc_dir_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -no-undefined
+kabc_dir_la_LIBADD = libkabc_dir.la
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kabc_dir.pot
+
+kabcincludedir = $(includedir)/kabc
+kabcinclude_HEADERS = resourcedir.h
+
+servicedir = $(kde_servicesdir)/kresources/kabc
+service_DATA = dir.desktop
+
+resourcedirplugin.lo: ../../addressee.h
diff --git a/kabc/plugins/dir/dir.desktop b/kabc/plugins/dir/dir.desktop
new file mode 100644
index 000000000..faffd99d4
--- /dev/null
+++ b/kabc/plugins/dir/dir.desktop
@@ -0,0 +1,92 @@
+[Desktop Entry]
+Name=Directory
+Name[af]=Gids
+Name[ar]=دليل
+Name[az]=Cərgə
+Name[be]=Тэчка
+Name[bn]=ডিরেক্টরি
+Name[br]=Renkell
+Name[bs]=Direktorij
+Name[ca]=Directori
+Name[cs]=Adresář
+Name[csb]=Katalog
+Name[cy]=Cyfeiriadur
+Name[da]=Mappe
+Name[de]=Verzeichnis
+Name[el]=Κατάλογος
+Name[eo]=Dosierujo
+Name[es]=Directorio
+Name[et]=Kataloog
+Name[eu]=Direktorioa
+Name[fa]=فهرست راهنما
+Name[fi]=Hakemisto
+Name[fo]=Fíluskrá
+Name[fr]=Dossier
+Name[fy]=Map
+Name[ga]=Comhadlann
+Name[gl]=Directório
+Name[he]=ספריה
+Name[hi]=डिरेक्ट्री
+Name[hr]=Mapa
+Name[hsb]=Zapisk
+Name[hu]=Könyvtár
+Name[id]=Direktori
+Name[is]=Mappa
+Name[it]=Cartella
+Name[ja]=ディレクトリ
+Name[ka]=დასტა
+Name[kk]=Каталог
+Name[km]=ថត
+Name[ko]=자료방
+Name[ku]=Peldank
+Name[lb]=Verzeechnis
+Name[lt]=Aplankas
+Name[lv]=Direktorija
+Name[mk]=Именик
+Name[mn]=Лавлах
+Name[ms]=Direktori
+Name[mt]=Direttorju
+Name[nb]=Katalog
+Name[nds]=Orner
+Name[ne]=डाइरेक्टरी
+Name[nl]=Map
+Name[nn]=Katalog
+Name[nso]=Tshupetso
+Name[oc]=Directori
+Name[pa]=ਡਾਇਰੈਕਟਰੀ
+Name[pl]=Katalog
+Name[pt]=Directoria
+Name[pt_BR]=Diretório
+Name[ro]=Director
+Name[ru]=Каталог
+Name[rw]=ububiko
+Name[se]=Ohcu
+Name[sk]=Priečinok
+Name[sl]=Imenik
+Name[sq]=Fioka
+Name[sr]=Фасцикла
+Name[sr@Latn]=Fascikla
+Name[ss]=I-directory
+Name[sv]=Katalog
+Name[ta]=அடைவு
+Name[te]=డైరక్టరి
+Name[tg]=Феҳраст
+Name[th]=ไดเรกทอรี
+Name[tr]=Dizin
+Name[tt]=Törgäk
+Name[uk]=Каталог
+Name[uz]=Jild
+Name[uz@cyrillic]=Жилд
+Name[ven]=Tsumbavhulwo
+Name[vi]=Thư mục
+Name[wa]=Ridant
+Name[xh]=Ulawulo
+Name[zh_CN]=目录
+Name[zh_HK]=目錄
+Name[zh_TW]=目錄
+Name[zu]=Uhlu lwamafayela
+X-KDE-Library=kabc_dir
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=dir
diff --git a/kabc/plugins/dir/resourcedir.cpp b/kabc/plugins/dir/resourcedir.cpp
new file mode 100644
index 000000000..1947e98f3
--- /dev/null
+++ b/kabc/plugins/dir/resourcedir.cpp
@@ -0,0 +1,310 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 - 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <qregexp.h>
+#include <qtimer.h>
+#include <qwidget.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kurlrequester.h>
+
+#include "addressbook.h"
+#include "formatfactory.h"
+#include "resourcedirconfig.h"
+#include "stdaddressbook.h"
+#include "lock.h"
+
+#include "resourcedir.h"
+
+using namespace KABC;
+
+extern "C"
+{
+ void *init_kabc_dir()
+ {
+ return new KRES::PluginFactory<ResourceDir,ResourceDirConfig>();
+ }
+}
+
+
+ResourceDir::ResourceDir( const KConfig *config )
+ : Resource( config ), mAsynchronous( false )
+{
+ if ( config ) {
+ init( config->readPathEntry( "FilePath", StdAddressBook::directoryName() ),
+ config->readEntry( "FileFormat", "vcard" ) );
+ } else {
+ init( StdAddressBook::directoryName(), "vcard" );
+ }
+}
+
+ResourceDir::ResourceDir( const QString &path, const QString &format )
+ : Resource( 0 ), mAsynchronous( false )
+{
+ init( path, format );
+}
+
+void ResourceDir::init( const QString &path, const QString &format )
+{
+ mFormatName = format;
+
+ FormatFactory *factory = FormatFactory::self();
+ mFormat = factory->format( mFormatName );
+
+ if ( !mFormat ) {
+ mFormatName = "vcard";
+ mFormat = factory->format( mFormatName );
+ }
+
+ mLock = 0;
+
+ connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( pathChanged() ) );
+ connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( pathChanged() ) );
+ connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( pathChanged() ) );
+
+ setPath( path );
+}
+
+ResourceDir::~ResourceDir()
+{
+ delete mFormat;
+ mFormat = 0;
+}
+
+void ResourceDir::writeConfig( KConfig *config )
+{
+ Resource::writeConfig( config );
+
+ if ( mPath == StdAddressBook::directoryName() )
+ config->deleteEntry( "FilePath" );
+ else
+ config->writePathEntry( "FilePath", mPath );
+
+ config->writeEntry( "FileFormat", mFormatName );
+}
+
+Ticket *ResourceDir::requestSaveTicket()
+{
+ kdDebug(5700) << "ResourceDir::requestSaveTicket()" << endl;
+
+ if ( !addressBook() ) return 0;
+
+ delete mLock;
+ mLock = new Lock( mPath );
+
+ if ( mLock->lock() ) {
+ addressBook()->emitAddressBookLocked();
+ } else {
+ addressBook()->error( mLock->error() );
+ kdDebug(5700) << "ResourceFile::requestSaveTicket(): Unable to lock path '"
+ << mPath << "': " << mLock->error() << endl;
+ return 0;
+ }
+
+ return createTicket( this );
+}
+
+void ResourceDir::releaseSaveTicket( Ticket *ticket )
+{
+ delete ticket;
+
+ delete mLock;
+ mLock = 0;
+}
+
+bool ResourceDir::doOpen()
+{
+ QDir dir( mPath );
+ if ( !dir.exists() ) { // no directory available
+ return dir.mkdir( dir.path() );
+ } else {
+ QString testName = dir.entryList( QDir::Files )[0];
+ if ( testName.isNull() || testName.isEmpty() ) // no file in directory
+ return true;
+
+ QFile file( mPath + "/" + testName );
+ if ( file.open( IO_ReadOnly ) )
+ return true;
+
+ if ( file.size() == 0 )
+ return true;
+
+ bool ok = mFormat->checkFormat( &file );
+ file.close();
+ return ok;
+ }
+}
+
+void ResourceDir::doClose()
+{
+}
+
+bool ResourceDir::load()
+{
+ kdDebug(5700) << "ResourceDir::load(): '" << mPath << "'" << endl;
+
+ mAsynchronous = false;
+
+ QDir dir( mPath );
+ QStringList files = dir.entryList( QDir::Files );
+
+ QStringList::Iterator it;
+ bool ok = true;
+ for ( it = files.begin(); it != files.end(); ++it ) {
+ QFile file( mPath + "/" + (*it) );
+
+ if ( !file.open( IO_ReadOnly ) ) {
+ addressBook()->error( i18n( "Unable to open file '%1' for reading" ).arg( file.name() ) );
+ ok = false;
+ continue;
+ }
+
+ if ( !mFormat->loadAll( addressBook(), this, &file ) )
+ ok = false;
+
+ file.close();
+ }
+
+ return ok;
+}
+
+bool ResourceDir::asyncLoad()
+{
+ mAsynchronous = true;
+
+ bool ok = load();
+ if ( !ok )
+ emit loadingError( this, i18n( "Loading resource '%1' failed!" )
+ .arg( resourceName() ) );
+ else
+ emit loadingFinished( this );
+
+ return ok;
+}
+
+bool ResourceDir::save( Ticket * )
+{
+ kdDebug(5700) << "ResourceDir::save(): '" << mPath << "'" << endl;
+
+ Addressee::Map::Iterator it;
+ bool ok = true;
+
+ mDirWatch.stopScan();
+
+ for ( it = mAddrMap.begin(); it != mAddrMap.end(); ++it ) {
+ if ( !it.data().changed() )
+ continue;
+
+ QFile file( mPath + "/" + (*it).uid() );
+ if ( !file.open( IO_WriteOnly ) ) {
+ addressBook()->error( i18n( "Unable to open file '%1' for writing" ).arg( file.name() ) );
+ continue;
+ }
+
+ mFormat->save( *it, &file );
+
+ // mark as unchanged
+ (*it).setChanged( false );
+
+ file.close();
+ }
+
+ mDirWatch.startScan();
+
+ return ok;
+}
+
+bool ResourceDir::asyncSave( Ticket *ticket )
+{
+ bool ok = save( ticket );
+ if ( !ok )
+ emit savingError( this, i18n( "Saving resource '%1' failed!" )
+ .arg( resourceName() ) );
+ else
+ emit savingFinished( this );
+
+ return ok;
+}
+
+void ResourceDir::setPath( const QString &path )
+{
+ mDirWatch.stopScan();
+ if ( mDirWatch.contains( mPath ) )
+ mDirWatch.removeDir( mPath );
+
+ mPath = path;
+ mDirWatch.addDir( mPath, true );
+ mDirWatch.startScan();
+}
+
+QString ResourceDir::path() const
+{
+ return mPath;
+}
+
+void ResourceDir::setFormat( const QString &format )
+{
+ mFormatName = format;
+
+ if ( mFormat )
+ delete mFormat;
+
+ FormatFactory *factory = FormatFactory::self();
+ mFormat = factory->format( mFormatName );
+}
+
+QString ResourceDir::format() const
+{
+ return mFormatName;
+}
+
+void ResourceDir::pathChanged()
+{
+ if ( !addressBook() )
+ return;
+
+ clear();
+ if ( mAsynchronous )
+ asyncLoad();
+ else {
+ load();
+ addressBook()->emitAddressBookChanged();
+ }
+}
+
+void ResourceDir::removeAddressee( const Addressee& addr )
+{
+ QFile::remove( mPath + "/" + addr.uid() );
+ mAddrMap.erase( addr.uid() );
+}
+
+#include "resourcedir.moc"
diff --git a/kabc/plugins/dir/resourcedir.h b/kabc/plugins/dir/resourcedir.h
new file mode 100644
index 000000000..b54f0ddda
--- /dev/null
+++ b/kabc/plugins/dir/resourcedir.h
@@ -0,0 +1,113 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 - 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_RESOURCEDIR_H
+#define KABC_RESOURCEDIR_H
+
+#include <kconfig.h>
+#include <kdirwatch.h>
+
+#include <sys/types.h>
+
+#include <kabc/resource.h>
+
+class QTimer;
+
+namespace KABC {
+
+class FormatPlugin;
+class Lock;
+
+/**
+ @internal
+*/
+class KABC_EXPORT ResourceDir : public Resource
+{
+ Q_OBJECT
+
+ public:
+ ResourceDir( const KConfig* );
+ ResourceDir( const QString &path, const QString &type = "vcard" );
+ ~ResourceDir();
+
+ virtual void writeConfig( KConfig* );
+
+ virtual bool doOpen();
+ virtual void doClose();
+
+ virtual Ticket *requestSaveTicket();
+ virtual void releaseSaveTicket( Ticket* );
+
+ virtual bool load();
+ virtual bool asyncLoad();
+ virtual bool save( Ticket* ticket );
+ virtual bool asyncSave( Ticket* ticket );
+
+ /**
+ Set path to be used for saving.
+ */
+ void setPath( const QString & );
+
+ /**
+ Return path used for loading and saving the address book.
+ */
+ QString path() const;
+
+ /**
+ Set the format by name.
+ */
+ void setFormat( const QString &format );
+
+ /**
+ Returns the format name.
+ */
+ QString format() const;
+
+ /**
+ Remove a addressee from its source.
+ This method is mainly called by KABC::AddressBook.
+ */
+ virtual void removeAddressee( const Addressee& addr );
+
+ protected slots:
+ void pathChanged();
+
+ protected:
+ void init( const QString &path, const QString &format );
+
+ private:
+ FormatPlugin *mFormat;
+
+ KDirWatch mDirWatch;
+
+ QString mPath;
+ QString mFormatName;
+
+ Lock *mLock;
+
+ bool mAsynchronous;
+
+ class ResourceDirPrivate;
+ ResourceDirPrivate *d;
+};
+
+}
+
+#endif
diff --git a/kabc/plugins/dir/resourcedirconfig.cpp b/kabc/plugins/dir/resourcedirconfig.cpp
new file mode 100644
index 000000000..ada7c1f9d
--- /dev/null
+++ b/kabc/plugins/dir/resourcedirconfig.cpp
@@ -0,0 +1,107 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kdialog.h>
+
+#include "formatfactory.h"
+#include "resourcedir.h"
+#include "stdaddressbook.h"
+
+#include "resourcedirconfig.h"
+
+using namespace KABC;
+
+ResourceDirConfig::ResourceDirConfig( QWidget* parent, const char* name )
+ : KRES::ConfigWidget( parent, name )
+{
+ QGridLayout *mainLayout = new QGridLayout( this, 2, 2, 0,
+ KDialog::spacingHint() );
+
+ QLabel *label = new QLabel( i18n( "Format:" ), this );
+ mFormatBox = new KComboBox( this );
+
+ mainLayout->addWidget( label, 0, 0 );
+ mainLayout->addWidget( mFormatBox, 0, 1 );
+
+ label = new QLabel( i18n( "Location:" ), this );
+ mFileNameEdit = new KURLRequester( this );
+ mFileNameEdit->setMode( KFile::Directory );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mFileNameEdit, 1, 1 );
+
+ FormatFactory *factory = FormatFactory::self();
+ QStringList formats = factory->formats();
+ QStringList::Iterator it;
+ for ( it = formats.begin(); it != formats.end(); ++it ) {
+ FormatInfo *info = factory->info( *it );
+ if ( info ) {
+ mFormatTypes << (*it);
+ mFormatBox->insertItem( info->nameLabel );
+ }
+ }
+
+ mInEditMode = false;
+}
+
+void ResourceDirConfig::setEditMode( bool value )
+{
+ mFormatBox->setEnabled( !value );
+ mInEditMode = value;
+}
+
+void ResourceDirConfig::loadSettings( KRES::Resource *res )
+{
+ ResourceDir *resource = dynamic_cast<ResourceDir*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceDirConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ mFormatBox->setCurrentItem( mFormatTypes.findIndex( resource->format() ) );
+
+ mFileNameEdit->setURL( resource->path() );
+ if ( mFileNameEdit->url().isEmpty() )
+ mFileNameEdit->setURL( KABC::StdAddressBook::directoryName() );
+}
+
+void ResourceDirConfig::saveSettings( KRES::Resource *res )
+{
+ ResourceDir *resource = dynamic_cast<ResourceDir*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceDirConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ if ( mInEditMode )
+ resource->setFormat( mFormatTypes[ mFormatBox->currentItem() ] );
+
+ resource->setPath( mFileNameEdit->url() );
+}
+
+#include "resourcedirconfig.moc"
diff --git a/kabc/plugins/dir/resourcedirconfig.h b/kabc/plugins/dir/resourcedirconfig.h
new file mode 100644
index 000000000..46d446b36
--- /dev/null
+++ b/kabc/plugins/dir/resourcedirconfig.h
@@ -0,0 +1,54 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCEDIRCONFIG_H
+#define RESOURCEDIRCONFIG_H
+
+#include <kcombobox.h>
+#include <kurlrequester.h>
+
+#include <kresources/configwidget.h>
+
+namespace KABC {
+
+class KABC_EXPORT ResourceDirConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+public:
+ ResourceDirConfig( QWidget* parent = 0, const char* name = 0 );
+
+ void setEditMode( bool value );
+
+public slots:
+ void loadSettings( KRES::Resource* );
+ void saveSettings( KRES::Resource* );
+
+private:
+ KComboBox* mFormatBox;
+ KURLRequester* mFileNameEdit;
+
+ QStringList mFormatTypes;
+
+ bool mInEditMode;
+};
+
+}
+#endif
diff --git a/kabc/plugins/dir/resourcedirplugin.cpp b/kabc/plugins/dir/resourcedirplugin.cpp
new file mode 100644
index 000000000..a2bd6d138
--- /dev/null
+++ b/kabc/plugins/dir/resourcedirplugin.cpp
@@ -0,0 +1,32 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 - 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "resourcedir.h"
+#include "resourcedirconfig.h"
+
+using namespace KABC;
+
+extern "C"
+{
+ KDE_EXPORT void *init_kabc_dir()
+ {
+ return new KRES::PluginFactory<ResourceDir, ResourceDirConfig>();
+ }
+}
diff --git a/kabc/plugins/evolution/Makefile.am b/kabc/plugins/evolution/Makefile.am
new file mode 100644
index 000000000..ea3f950f7
--- /dev/null
+++ b/kabc/plugins/evolution/Makefile.am
@@ -0,0 +1,19 @@
+INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = resourceevo.h dbwrapper.h
+
+kde_module_LTLIBRARIES = kabc_evo.la
+
+kabc_evo_la_SOURCES = dbwrapper.cpp resourceevo.cpp
+
+kabc_evo_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kabc_evo_la_LIBADD = ../../../kabc/libkabc.la ../../../kdeui/libkdeui.la -ldb ../../../kabc/vcardparser/libvcards.la
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kabc_evolution.pot
+
+servicedir = $(kde_servicesdir)/kresources/kabc
+service_DATA = evolution.desktop
diff --git a/kabc/plugins/evolution/README b/kabc/plugins/evolution/README
new file mode 100644
index 000000000..7dfefce00
--- /dev/null
+++ b/kabc/plugins/evolution/README
@@ -0,0 +1,15 @@
+A Resource using DB3 to access the evolution
+addressbook make sure the wombat is not running
+In future versions I may use bonobo to access it...
+
+
+DESIGN:
+The Format vs Resource idea is somehow not applyable to the
+Evolution PAS
+
+Format would be vCard and Resource would be DB3..
+BUT
+Format get's a QFile* pointer which is just not usable
+with a DB3
+INSTEAD we will use the vCardImpl directly to convert
+a string to Addressee \ No newline at end of file
diff --git a/kabc/plugins/evolution/dbwrapper.cpp b/kabc/plugins/evolution/dbwrapper.cpp
new file mode 100644
index 000000000..cc566344c
--- /dev/null
+++ b/kabc/plugins/evolution/dbwrapper.cpp
@@ -0,0 +1,187 @@
+#include <db.h>
+
+#include <qfile.h>
+
+#include "dbwrapper.h"
+
+
+using namespace Evolution;
+
+struct DBIterator::Data {
+ DBWrapper *wrapper;
+ QString key;
+ QString data;
+ DBC* cursor;
+ bool atEnd;
+};
+
+DBIterator::DBIterator( DBWrapper* wra) {
+ data = new Data;
+ data->wrapper = wra;
+ data->atEnd = false;
+ data->cursor = 0l;
+}
+DBIterator::DBIterator( const DBIterator& copy ) {
+ data = new Data;
+ data->wrapper = copy.data->wrapper;
+ data->key = copy.data->key;
+ data->data = copy.data->data;
+ data->atEnd = copy.data->atEnd;
+ if (copy.data->cursor )
+ copy.data->cursor->c_dup(copy.data->cursor, &data->cursor, 0 );
+ else
+ data->cursor = 0l;
+}
+DBIterator::~DBIterator() {
+ if (data->cursor)
+ data->cursor->c_close(data->cursor);
+ delete data;
+}
+DBIterator& DBIterator::operator=( const DBIterator& rhs ) {
+ if ( *this == rhs )
+ return *this;
+ if (data->cursor)
+ data->cursor->c_close(data->cursor);
+ delete data;
+ data = new Data;
+ data->wrapper = rhs.data->wrapper;
+ data->key = rhs.data->key;
+ data->data = rhs.data->data;
+ data->atEnd = rhs.data->atEnd;
+ if ( rhs.data->cursor )
+ rhs.data->cursor->c_dup(rhs.data->cursor, &data->cursor, 0 );
+ else
+ data->cursor = 0l;
+
+ return *this;
+}
+QString DBIterator::key()const{
+ return data->key;
+}
+QString DBIterator::value()const {
+ return data->data;
+}
+QString DBIterator::operator*() {
+ return data->data;
+}
+DBIterator& DBIterator::operator++() {
+ DBT key, val;
+ ::memset(&key, 0, sizeof(key) );
+ ::memset(&val, 0, sizeof(val) );
+ if ( data->cursor )
+ if ( data->cursor->c_get(data->cursor, &key, &val,DB_NEXT ) != 0 )
+ data->atEnd = true;
+ data->key = QString::fromUtf8( (char*)key.data, key.size );
+ data->data = QString::fromUtf8( (char*)val.data, val.size );
+ return *this;
+}
+DBIterator& DBIterator::operator--() {
+ DBT key, val;
+ ::memset(&key, 0, sizeof(key) );
+ ::memset(&val, 0, sizeof(val) );
+ if ( data->cursor )
+ if ( data->cursor->c_get(data->cursor, &key, &val,DB_PREV ) != 0 )
+ data->atEnd = true;
+ data->key = QString::fromUtf8( (char*)key.data, key.size );
+ data->data = QString::fromUtf8( (char*)val.data, val.size );
+ return *this;
+}
+bool DBIterator::operator==( const DBIterator& rhs ) {
+ if ( data->atEnd && data->atEnd == rhs.data->atEnd ) return true;
+
+ return false;
+}
+bool DBIterator::operator!=( const DBIterator& rhs ) {
+ return !this->operator==(rhs );
+}
+struct DBWrapper::Data {
+ DB* db;
+ bool only;
+};
+DBWrapper::DBWrapper() {
+ data = new Data;
+ (void)db_create(&data->db, NULL, 0 );
+ data->only = false;
+}
+DBWrapper::~DBWrapper() {
+ data->db->close(data->db, 0 );
+ delete data;
+}
+bool DBWrapper::open( const QString& file, bool on) {
+ data->only = on;
+ return !data->db->open(data->db, QFile::encodeName( file ), NULL, DB_HASH, 0, 0666 );
+}
+bool DBWrapper::save() {
+ return true;
+}
+DBIterator DBWrapper::begin() {
+ DBIterator it(this);
+ DBC* cursor;
+ DBT key, val;
+ int ret;
+ ret = data->db->cursor(data->db, NULL, &cursor, 0 );
+ if (ret ) {
+ it.data->atEnd = true;
+ return it;
+ }
+
+ ::memset(&key, 0, sizeof(key) );
+ ::memset(&val, 0, sizeof(val) );
+ ret = cursor->c_get(cursor, &key, &val, DB_FIRST );
+ if (ret ) {
+ it.data->atEnd = true;
+ return it;
+ }
+
+ it.data->cursor = cursor;
+ it.data->key = QString::fromUtf8((char*)key.data, key.size );
+ it.data->data = QString::fromUtf8((char*)val.data, val.size );
+
+ return it;
+}
+DBIterator DBWrapper::end() {
+ DBIterator it(this);
+ it.data->atEnd = true;
+
+ return it;
+}
+bool DBWrapper::find( const QString& _key, QString& _val ) {
+ DBT key, val;
+ ::memset(&key, 0, sizeof(key) );
+ ::memset(&val, 0, sizeof(val) );
+
+ QCString db_key = _key.local8Bit();
+ key.data = db_key.data();
+ key.size = db_key.size();
+
+ int ret = data->db->get(data->db, NULL, &key, &val, 0 );
+ if (!ret) {
+ _val = QString::fromUtf8( (char*)val.data, val.size );
+ qWarning("key: %s val: %sXXX", (char*)key.data, (char*)val.data );
+ return true;
+ }
+ return false;
+}
+bool DBWrapper::add( const QString& _key, const QString& _val ) {
+ QCString db_key = _key.local8Bit();
+ QCString db_val = _val.local8Bit();
+ DBT key, val;
+ ::memset(&key, 0, sizeof(key) );
+ ::memset(&val, 0, sizeof(val) );
+
+ key.data = db_key.data();
+ key.size = db_key.size();
+ val.data = db_val.data();
+ val.size = db_val.size();
+
+ return !data->db->put(data->db, NULL, &key, &val, 0 );
+}
+bool DBWrapper::remove( const QString& _key ) {
+ QCString db_key = _key.local8Bit();
+ DBT key;
+ memset(&key, 0, sizeof(key) );
+ key.data = db_key.data();
+ key.size = db_key.size();
+
+ return !data->db->del(data->db, NULL, &key, 0 );
+}
diff --git a/kabc/plugins/evolution/dbwrapper.h b/kabc/plugins/evolution/dbwrapper.h
new file mode 100644
index 000000000..484605acf
--- /dev/null
+++ b/kabc/plugins/evolution/dbwrapper.h
@@ -0,0 +1,60 @@
+#ifndef KABC_EVOLUTION_DB_WRAPPER
+#define KABC_EVOLUTION_DB_WRAPPER
+
+#include <db.h>
+
+#include <qstring.h>
+#include <qpair.h>
+
+namespace Evolution {
+
+ class DBWrapper;
+ class DBIterator {
+ friend class DBWrapper;
+ public:
+ DBIterator( DBWrapper* = 0l );
+ ~DBIterator();
+
+ DBIterator( const DBIterator& );
+ DBIterator &operator=( const DBIterator& );
+
+ QString key()const;
+ QString value()const;
+
+ QString operator*();
+
+ DBIterator &operator++();
+ DBIterator &operator--();
+
+ bool operator==( const DBIterator& );
+ bool operator!=( const DBIterator& );
+ private:
+ struct Data;
+ Data* data;
+ };
+ class DBWrapper {
+ public:
+ DBWrapper();
+ ~DBWrapper();
+
+ QString lastError()const;
+
+ bool open( const QString& file, bool readOnly = false);
+ bool save();
+ DBIterator begin();
+ DBIterator end();
+
+ bool find( const QString& key, QString& value );
+ bool add( const QString& key, const QString& val );
+ bool remove( const QString& key );
+ private:
+ // DBT element( const QString& );
+ struct Data;
+ Data* data;
+
+ };
+
+}
+
+
+#endif
diff --git a/kabc/plugins/evolution/evolution.desktop b/kabc/plugins/evolution/evolution.desktop
new file mode 100644
index 000000000..87397d92e
--- /dev/null
+++ b/kabc/plugins/evolution/evolution.desktop
@@ -0,0 +1,26 @@
+[Desktop Entry]
+Name=Evolution
+Name[be]=Эвалюцыя
+Name[bn]=ইভোলিউশন
+Name[eo]=Evoluo
+Name[fa]=اوولوشن
+Name[hi]=एवॉल्यूशन
+Name[ko]=에볼루션
+Name[mn]=Хөгжил
+Name[ne]=इभोल्युसन
+Name[pa]=ਏਵੂਲੇਸ਼ਨ
+Name[sr]=Еволуција
+Name[sr@Latn]=Evolucija
+Name[ta]=படிப்படியான வளர்ச்சி
+Name[te]=ఎవల్యుషన్
+Name[th]=เอฟโวลูชัน
+Name[tt]=Üseş
+Name[ven]=Tsikoni
+Name[wa]=Evolucion
+Name[xh]=Utshintsho lwendawo ngokwenqanawa
+Name[zu]=Evolushini
+X-KDE-Library=kabc_evo
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=evolution
diff --git a/kabc/plugins/evolution/resourceevo.cpp b/kabc/plugins/evolution/resourceevo.cpp
new file mode 100644
index 000000000..a1858bf83
--- /dev/null
+++ b/kabc/plugins/evolution/resourceevo.cpp
@@ -0,0 +1,132 @@
+#include <qdir.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <stdio.h>
+
+#include <kabc/vcardparser/vcardtool.h>
+
+#include "dbwrapper.h"
+#include "resourceevo.h"
+
+using namespace Evolution;
+using namespace KABC;
+
+class EvolutionFactory : public KRES::PluginFactoryBase
+{
+ public:
+ KRES::Resource *resource( const KConfig *config )
+ {
+ return new ResourceEvolution( config );
+ }
+
+ KRES::ConfigWidget *configWidget( QWidget * )
+ {
+ return 0;
+ }
+};
+
+extern "C"
+{
+ KDE_EXPORT void *init_kabc_evo()
+ {
+ return ( new EvolutionFactory() );
+ }
+}
+
+ResourceEvolution::ResourceEvolution( const KConfig* conf )
+ : Resource( conf ), mWrap(0l)
+{
+ m_isOpen = false;
+}
+ResourceEvolution::~ResourceEvolution() {
+ delete mWrap;
+}
+bool ResourceEvolution::doOpen() {
+ mWrap = new DBWrapper;
+ if (!mWrap->open( QDir::homeDirPath() + "/evolution/local/Contacts/addressbook.db" ) ) {
+ return false;
+ }
+
+ QString val;
+ if (!mWrap->find( "PAS-DB-VERSION", val ) )
+ return false;
+
+ if (!val.startsWith("0.2") )
+ return false;
+
+ m_isOpen = true;
+
+ return true;
+}
+void ResourceEvolution::doClose() {
+ delete mWrap;
+ mWrap = 0l;
+ m_isOpen = false;
+}
+Ticket* ResourceEvolution::requestSaveTicket() {
+ if ( !addressBook() ) return 0;
+ return createTicket( this );
+}
+/*
+ * skip the first key
+ */
+
+bool ResourceEvolution::load() {
+ /* doOpen never get's called :( */
+ if (!doOpen()) return false;
+ if (!mWrap ) return false; // open first!
+
+ DBIterator it = mWrap->begin();
+ // skip the "PAS-DB-VERSION"
+
+ for ( ; it != mWrap->end(); ++it ) {
+ if ( it.key().startsWith("PAS-DB-VERSION") )
+ continue;
+
+ qWarning( "val:%s", it.value().latin1() );
+ VCardTool tool;
+ QString str = it.value().stripWhiteSpace();
+ Addressee::List list = tool.parseVCards( str );
+ if (!list.first().isEmpty() ) {
+ Addressee adr = list.first();
+ adr.setResource(this);
+ addressBook()->insertAddressee( adr );
+ }
+ }
+ return true;
+}
+bool ResourceEvolution::save( Ticket* ticket ) {
+ delete ticket;
+ if (!m_isOpen ) return false;
+
+ // just delete the summary so evolution will regenerate it
+ // on next start up
+ (void)QFile::remove( QDir::homeDirPath() + "/evolution/local/Contacts/addressbook.db.summary" );
+
+
+ AddressBook::Iterator it;
+ Addressee::List list;
+ for ( it = addressBook()->begin(); it !=addressBook()->end(); ++it ) {
+ if ( (*it).resource() != this || !(*it).changed() )
+ continue;
+
+ // remove, convert add set unchanged false
+ list.clear();
+ mWrap->remove( (*it).uid() );
+ VCardTool tool;
+ list.append( (*it) );
+ mWrap->add( (*it).uid(), tool.createVCards( list, VCard::v2_1) );
+
+ (*it).setChanged( false );
+ }
+
+ return true;
+}
+void ResourceEvolution::removeAddressee( const Addressee& rem) {
+ if (!m_isOpen) return;
+
+ mWrap->remove( rem.uid() );
+}
diff --git a/kabc/plugins/evolution/resourceevo.h b/kabc/plugins/evolution/resourceevo.h
new file mode 100644
index 000000000..0f5b3a0d2
--- /dev/null
+++ b/kabc/plugins/evolution/resourceevo.h
@@ -0,0 +1,23 @@
+#include "resource.h"
+
+namespace Evolution {
+ class DBWrapper;
+}
+
+namespace KABC {
+ class ResourceEvolution : public Resource {
+ public:
+ ResourceEvolution( const KConfig* config );
+ ~ResourceEvolution();
+
+ bool doOpen();
+ void doClose();
+ Ticket* requestSaveTicket();
+ bool load();
+ bool save( Ticket* ticket );
+ void removeAddressee( const Addressee& );
+ private:
+ Evolution::DBWrapper *mWrap;
+ bool m_isOpen : 1;
+ };
+}
diff --git a/kabc/plugins/file/Makefile.am b/kabc/plugins/file/Makefile.am
new file mode 100644
index 000000000..9e3fc8360
--- /dev/null
+++ b/kabc/plugins/file/Makefile.am
@@ -0,0 +1,28 @@
+INCLUDES = -I$(top_builddir)/kabc -I$(top_srcdir)/kabc $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = resourcefileconfig.h
+
+lib_LTLIBRARIES = libkabc_file.la
+libkabc_file_la_SOURCES = resourcefile.cpp resourcefileconfig.cpp
+libkabc_file_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined
+libkabc_file_la_LIBADD = $(LIB_KABC)
+libkabc_file_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h
+
+
+kde_module_LTLIBRARIES = kabc_file.la
+kabc_file_la_SOURCES = resourcefileplugin.cpp
+kabc_file_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -no-undefined
+kabc_file_la_LIBADD = libkabc_file.la
+kabc_file_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kabc_file.pot
+
+kabcincludedir = $(includedir)/kabc
+kabcinclude_HEADERS = resourcefile.h
+
+servicedir = $(kde_servicesdir)/kresources/kabc
+service_DATA = file.desktop
diff --git a/kabc/plugins/file/file.desktop b/kabc/plugins/file/file.desktop
new file mode 100644
index 000000000..559cfcf21
--- /dev/null
+++ b/kabc/plugins/file/file.desktop
@@ -0,0 +1,82 @@
+[Desktop Entry]
+Name=File
+Name[af]=Lêer
+Name[ar]=ملفّ
+Name[az]=Fayl
+Name[be]=Файл
+Name[bn]=ফাইল
+Name[br]=Restr
+Name[bs]=Datoteka
+Name[ca]=Fitxer
+Name[cs]=Soubor
+Name[csb]=Lopk
+Name[cy]=Ffeil
+Name[da]=Fil
+Name[de]=Datei
+Name[el]=Αρχείο
+Name[eo]=Dosiero
+Name[es]=Archivo
+Name[et]=Fail
+Name[eu]=Fitxategia
+Name[fa]=پرونده
+Name[fi]=Tiedosto
+Name[fr]=Fichier
+Name[fy]=Triem
+Name[ga]=Comhad
+Name[gl]=Ficheiro
+Name[he]=קובץ
+Name[hi]=फ़ाइल
+Name[hr]=Datoteka
+Name[hsb]=Dataja
+Name[hu]=Fájl
+Name[id]=Berkas
+Name[is]=Skrá
+Name[ja]=ファイル
+Name[ka]=ფაილი
+Name[kk]=Файл
+Name[km]=ឯកសារ
+Name[ko]=파일
+Name[lb]=Datei
+Name[lt]=Byla
+Name[lv]=Fails
+Name[mk]=Датотека
+Name[mn]=Файл
+Name[ms]=Fail
+Name[nb]=Fil
+Name[nds]=Datei
+Name[ne]=फाइल
+Name[nl]=Bestand
+Name[nn]=Fil
+Name[pa]=ਫਾਇਲ
+Name[pl]=Plik
+Name[pt]=Ficheiro
+Name[pt_BR]=Arquivo
+Name[ro]=Fişier
+Name[ru]=Файл
+Name[rw]=Idosiye
+Name[se]=Fiila
+Name[sk]=Súbor
+Name[sl]=Datoteka
+Name[sq]=Skedë
+Name[sr]=Фајл
+Name[sr@Latn]=Fajl
+Name[sv]=Fil
+Name[ta]=கோப்பு
+Name[te]=దస్త్రం
+Name[tg]=Файл
+Name[th]=แฟ้ม
+Name[tr]=Dosya
+Name[tt]=Birem
+Name[uk]=Файл
+Name[uz]=Fayl
+Name[uz@cyrillic]=Файл
+Name[vi]=Tập tin
+Name[wa]=Fitchî
+Name[zh_CN]=文件
+Name[zh_HK]=檔案
+Name[zh_TW]=檔案
+X-KDE-Library=kabc_file
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=file
diff --git a/kabc/plugins/file/resourcefile.cpp b/kabc/plugins/file/resourcefile.cpp
new file mode 100644
index 000000000..9c0f85fb8
--- /dev/null
+++ b/kabc/plugins/file/resourcefile.cpp
@@ -0,0 +1,395 @@
+/*
+ This file is part of libkabc.
+
+ Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2006 Tom Abers <tomalbers@kde.nl>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtimer.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kio/scheduler.h>
+#include <klocale.h>
+#include <ksavefile.h>
+#include <kstandarddirs.h>
+
+#include "formatfactory.h"
+#include "resourcefileconfig.h"
+#include "stdaddressbook.h"
+#include "lock.h"
+
+#include "resourcefile.h"
+
+using namespace KABC;
+
+ResourceFile::ResourceFile( const KConfig *config )
+ : Resource( config ), mFormat( 0 ),
+ mAsynchronous( false )
+{
+ QString fileName, formatName;
+
+ if ( config ) {
+ fileName = config->readPathEntry( "FileName", StdAddressBook::fileName() );
+ formatName = config->readEntry( "FileFormat", "vcard" );
+ } else {
+ fileName = StdAddressBook::fileName();
+ formatName = "vcard";
+ }
+
+ init( fileName, formatName );
+}
+
+ResourceFile::ResourceFile( const QString &fileName,
+ const QString &formatName )
+ : Resource( 0 ), mFormat( 0 ),
+ mAsynchronous( false )
+{
+ init( fileName, formatName );
+}
+
+void ResourceFile::init( const QString &fileName, const QString &formatName )
+{
+ mFormatName = formatName;
+
+ FormatFactory *factory = FormatFactory::self();
+ mFormat = factory->format( mFormatName );
+
+ if ( !mFormat ) {
+ mFormatName = "vcard";
+ mFormat = factory->format( mFormatName );
+ }
+
+ connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) );
+ connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) );
+ connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) );
+
+ setFileName( fileName );
+
+ mLock = 0;
+}
+
+ResourceFile::~ResourceFile()
+{
+ delete mFormat;
+ mFormat = 0;
+}
+
+void ResourceFile::writeConfig( KConfig *config )
+{
+ Resource::writeConfig( config );
+
+ if ( mFileName == StdAddressBook::fileName() )
+ config->deleteEntry( "FileName" );
+ else
+ config->writePathEntry( "FileName", mFileName );
+
+ config->writeEntry( "FileFormat", mFormatName );
+}
+
+Ticket *ResourceFile::requestSaveTicket()
+{
+ kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl;
+
+ if ( !addressBook() ) return 0;
+
+ delete mLock;
+ mLock = new Lock( mFileName );
+
+ if ( mLock->lock() ) {
+ addressBook()->emitAddressBookLocked();
+ } else {
+ addressBook()->error( mLock->error() );
+ kdDebug(5700) << "ResourceFile::requestSaveTicket(): Unable to lock file '"
+ << mFileName << "': " << mLock->error() << endl;
+ return 0;
+ }
+
+ return createTicket( this );
+}
+
+void ResourceFile::releaseSaveTicket( Ticket *ticket )
+{
+ delete ticket;
+
+ delete mLock;
+ mLock = 0;
+
+ addressBook()->emitAddressBookUnlocked();
+}
+
+bool ResourceFile::doOpen()
+{
+ QFile file( mFileName );
+
+ if ( !file.exists() ) {
+ // try to create the file
+ bool ok = file.open( IO_WriteOnly );
+ if ( ok )
+ file.close();
+
+ return ok;
+ } else {
+ QFileInfo fileInfo( mFileName );
+ if ( readOnly() || !fileInfo.isWritable() ) {
+ if ( !file.open( IO_ReadOnly ) )
+ return false;
+ } else {
+ if ( !file.open( IO_ReadWrite ) )
+ return false;
+ }
+
+ if ( file.size() == 0 ) {
+ file.close();
+ kdDebug() << "File size is zero. Evaluating backups" << endl;
+ for (int i=0; i!=20; i++)
+ {
+ QFile backup( mFileName + "__" + QString::number(i) );
+ kdDebug() << "Evaluating" << backup.name() << " size: " << backup.size() << endl;
+ if ( backup.size() != 0 )
+ {
+ kdDebug() << "Restoring backup " << i << endl;
+ const QString src = mFileName + "__" + QString::number(i);
+ const QString dest = mFileName;
+
+ // remove dest
+ QFile::remove( dest );
+
+ // copy src to dest
+ if ( backup.open( IO_ReadOnly ) ) {
+ const QByteArray data = backup.readAll();
+
+ QFile out( dest );
+ if ( out.open( IO_WriteOnly ) ) {
+ out.writeBlock( data );
+ out.close();
+ }
+
+ backup.close();
+ }
+ return true;
+ }
+ }
+ return true;
+ }
+
+ bool ok = mFormat->checkFormat( &file );
+ file.close();
+
+ return ok;
+ }
+}
+
+void ResourceFile::doClose()
+{
+}
+
+bool ResourceFile::load()
+{
+ kdDebug(5700) << "ResourceFile::load(): '" << mFileName << "'" << endl;
+
+ mAsynchronous = false;
+
+ QFile file( mFileName );
+ if ( !file.open( IO_ReadOnly ) ) {
+ addressBook()->error( i18n( "Unable to open file '%1'." ).arg( mFileName ) );
+ return false;
+ }
+
+ clear();
+
+ return mFormat->loadAll( addressBook(), this, &file );
+}
+
+bool ResourceFile::asyncLoad()
+{
+ kdDebug(5700) << "ResourceFile::asyncLoad()" << endl;
+
+ mAsynchronous = true;
+
+ bool ok = load();
+
+ if ( !ok )
+ emitLoadingError();
+ else
+ emitLoadingFinished();
+
+ return true;
+}
+
+bool ResourceFile::save( Ticket * )
+{
+ kdDebug(5700) << "ResourceFile::save()" << endl;
+
+ // Only do the logrotate dance when the __0 file is not 0 bytes.
+ QFile file( mFileName + "__0" );
+ if ( file.size() != 0 ) {
+ const QString last = mFileName + "__20";
+ kdDebug() << "deleting " << last << endl;
+
+ QFile::remove( last );
+
+ for (int i=19; i>=0; i--)
+ {
+ const QString src = mFileName + "__" + QString::number(i);
+ const QString dest = mFileName + "__" + QString::number(i+1);
+ kdDebug() << "moving " << src << " -> " << dest << endl;
+
+ // copy src to dest
+ QFile in( src );
+ if ( in.open( IO_ReadOnly ) ) {
+ const QByteArray data = in.readAll();
+
+ QFile out( dest );
+ if ( out.open( IO_WriteOnly ) ) {
+ out.writeBlock( data );
+ out.close();
+ }
+
+ in.close();
+ }
+
+ // remove src
+ QFile::remove( src );
+ }
+ } else
+ kdDebug() << "Not starting logrotate __0 is 0 bytes." << endl;
+
+ QString extension = "__0";
+ (void) KSaveFile::backupFile( mFileName, QString::null /*directory*/,
+ extension );
+
+ mDirWatch.stopScan();
+
+ KSaveFile saveFile( mFileName );
+ bool ok = false;
+
+ if ( saveFile.status() == 0 && saveFile.file() ) {
+ mFormat->saveAll( addressBook(), this, saveFile.file() );
+ ok = saveFile.close();
+ }
+
+ if ( !ok ) {
+ saveFile.abort();
+ addressBook()->error( i18n( "Unable to save file '%1'." ).arg( mFileName ) );
+ }
+
+ mDirWatch.startScan();
+
+ return ok;
+}
+
+bool ResourceFile::asyncSave( Ticket *ticket )
+{
+ kdDebug(5700) << "ResourceFile::asyncSave()" << endl;
+
+ bool ok = save( ticket );
+
+ if ( !ok )
+ QTimer::singleShot( 0, this, SLOT( emitSavingError() ) );
+ else
+ QTimer::singleShot( 0, this, SLOT( emitSavingFinished() ) );
+
+ return ok;
+}
+
+void ResourceFile::setFileName( const QString &fileName )
+{
+ mDirWatch.stopScan();
+ if ( mDirWatch.contains( mFileName ) )
+ mDirWatch.removeFile( mFileName );
+
+ mFileName = fileName;
+
+ mDirWatch.addFile( mFileName );
+ mDirWatch.startScan();
+}
+
+QString ResourceFile::fileName() const
+{
+ return mFileName;
+}
+
+void ResourceFile::setFormat( const QString &format )
+{
+ mFormatName = format;
+ delete mFormat;
+
+ FormatFactory *factory = FormatFactory::self();
+ mFormat = factory->format( mFormatName );
+}
+
+QString ResourceFile::format() const
+{
+ return mFormatName;
+}
+
+void ResourceFile::fileChanged()
+{
+ kdDebug(5700) << "ResourceFile::fileChanged(): " << mFileName << endl;
+
+ if ( !addressBook() )
+ return;
+
+ if ( mAsynchronous )
+ asyncLoad();
+ else {
+ load();
+ kdDebug() << "addressBookChanged() " << endl;
+ addressBook()->emitAddressBookChanged();
+ }
+}
+
+void ResourceFile::removeAddressee( const Addressee &addr )
+{
+ QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) );
+ QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) );
+ QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) );
+
+ mAddrMap.erase( addr.uid() );
+}
+
+void ResourceFile::emitSavingFinished()
+{
+ emit savingFinished( this );
+}
+
+void ResourceFile::emitSavingError()
+{
+ emit savingError( this, i18n( "Unable to save file '%1'." ).arg( mFileName ) );
+}
+
+void ResourceFile::emitLoadingFinished()
+{
+ emit loadingFinished( this );
+}
+
+void ResourceFile::emitLoadingError()
+{
+ emit loadingError( this, i18n( "Problems during parsing file '%1'." ).arg( mFileName ) );
+}
+
+#include "resourcefile.moc"
diff --git a/kabc/plugins/file/resourcefile.h b/kabc/plugins/file/resourcefile.h
new file mode 100644
index 000000000..84dfc7cda
--- /dev/null
+++ b/kabc/plugins/file/resourcefile.h
@@ -0,0 +1,162 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_RESOURCEFILE_H
+#define KABC_RESOURCEFILE_H
+
+#include <kconfig.h>
+#include <kdirwatch.h>
+
+#include <sys/types.h>
+
+#include <kabc/resource.h>
+
+namespace KABC {
+
+class FormatPlugin;
+class ResourceConfigWidget;
+class Lock;
+
+/**
+ This resource allows access to a local file.
+*/
+class KABC_EXPORT ResourceFile : public Resource
+{
+ Q_OBJECT
+
+ public:
+ /**
+ Constructor.
+
+ @param cfg The config object where custom resource settings are stored.
+ */
+ ResourceFile( const KConfig *cfg );
+
+ /**
+ Construct file resource on file @arg fileName using format @arg formatName.
+ */
+ ResourceFile( const QString &fileName, const QString &formatName = "vcard" );
+
+ /**
+ Destructor.
+ */
+ ~ResourceFile();
+
+ /**
+ Writes the config back.
+ */
+ virtual void writeConfig( KConfig *cfg );
+
+ /**
+ Tries to open the file and checks for the proper format.
+ This method should be called before load().
+ */
+ virtual bool doOpen();
+
+ /**
+ Closes the file again.
+ */
+ virtual void doClose();
+
+ /**
+ Requests a save ticket, that is used by save()
+ */
+ virtual Ticket *requestSaveTicket();
+
+ virtual void releaseSaveTicket( Ticket* );
+
+ /**
+ Loads all addressees from file to the address book.
+ Returns true if all addressees could be loaded otherwise false.
+ */
+ virtual bool load();
+
+ virtual bool asyncLoad();
+
+ /**
+ Saves all addresses from address book to file.
+ Returns true if all addressees could be saved otherwise false.
+
+ @param ticket The ticket returned by requestSaveTicket()
+ */
+ virtual bool save( Ticket *ticket );
+
+ virtual bool asyncSave( Ticket *ticket );
+
+ /**
+ Set name of file to be used for saving.
+ */
+ void setFileName( const QString & );
+
+ /**
+ Return name of file used for loading and saving the address book.
+ */
+ QString fileName() const;
+
+ /**
+ Sets a new format by name.
+ */
+ void setFormat( const QString &name );
+
+ /**
+ Returns the format name.
+ */
+ QString format() const;
+
+ /**
+ Remove a addressee from its source.
+ This method is mainly called by KABC::AddressBook.
+ */
+ virtual void removeAddressee( const Addressee& addr );
+
+ private slots:
+ void emitLoadingFinished();
+ void emitLoadingError();
+ void emitSavingFinished();
+ void emitSavingError();
+
+ protected slots:
+ void fileChanged();
+
+ protected:
+ void init( const QString &fileName, const QString &format );
+
+ bool lock( const QString &fileName );
+ void unlock( const QString &fileName );
+
+ private:
+ QString mFileName;
+ QString mFormatName;
+
+ FormatPlugin *mFormat;
+
+ Lock *mLock;
+
+ KDirWatch mDirWatch;
+
+ bool mAsynchronous;
+
+ class ResourceFilePrivate;
+ ResourceFilePrivate *d;
+};
+
+}
+
+#endif
diff --git a/kabc/plugins/file/resourcefileconfig.cpp b/kabc/plugins/file/resourcefileconfig.cpp
new file mode 100644
index 000000000..a6d8ab4f9
--- /dev/null
+++ b/kabc/plugins/file/resourcefileconfig.cpp
@@ -0,0 +1,118 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kdialog.h>
+
+#include <unistd.h>
+
+#include "formatfactory.h"
+#include "resourcefile.h"
+#include "stdaddressbook.h"
+
+#include "resourcefileconfig.h"
+
+using namespace KABC;
+
+ResourceFileConfig::ResourceFileConfig( QWidget* parent, const char* name )
+ : ConfigWidget( parent, name )
+{
+ QGridLayout *mainLayout = new QGridLayout( this, 2, 2, 0,
+ KDialog::spacingHint() );
+
+ QLabel *label = new QLabel( i18n( "Format:" ), this );
+ mFormatBox = new KComboBox( this );
+
+ mainLayout->addWidget( label, 0, 0 );
+ mainLayout->addWidget( mFormatBox, 0, 1 );
+
+ label = new QLabel( i18n( "Location:" ), this );
+ mFileNameEdit = new KURLRequester( this );
+
+ connect( mFileNameEdit, SIGNAL( textChanged( const QString & ) ),
+ SLOT( checkFilePermissions( const QString & ) ) );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mFileNameEdit, 1, 1 );
+
+ FormatFactory *factory = FormatFactory::self();
+ QStringList formats = factory->formats();
+ QStringList::Iterator it;
+ for ( it = formats.begin(); it != formats.end(); ++it ) {
+ FormatInfo *info = factory->info( *it );
+ if ( info ) {
+ mFormatTypes << (*it);
+ mFormatBox->insertItem( info->nameLabel );
+ }
+ }
+
+ mInEditMode = false;
+}
+
+void ResourceFileConfig::setEditMode( bool value )
+{
+ mFormatBox->setEnabled( !value );
+ mInEditMode = value;
+}
+
+void ResourceFileConfig::loadSettings( KRES::Resource *res )
+{
+ ResourceFile *resource = dynamic_cast<ResourceFile*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceFileConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ mFormatBox->setCurrentItem( mFormatTypes.findIndex( resource->format() ) );
+
+ mFileNameEdit->setURL( resource->fileName() );
+ if ( mFileNameEdit->url().isEmpty() )
+ mFileNameEdit->setURL( KABC::StdAddressBook::fileName() );
+}
+
+void ResourceFileConfig::saveSettings( KRES::Resource *res )
+{
+ ResourceFile *resource = dynamic_cast<ResourceFile*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceFileConfig::saveSettings(): cast failed" << endl;
+ return;
+ }
+
+ if ( !mInEditMode )
+ resource->setFormat( mFormatTypes[ mFormatBox->currentItem() ] );
+
+ resource->setFileName( mFileNameEdit->url() );
+}
+
+void ResourceFileConfig::checkFilePermissions( const QString& fileName )
+{
+ // If file exist but is not writeable...
+ if ( access( QFile::encodeName( fileName ), F_OK ) == 0 )
+ emit setReadOnly( access( QFile::encodeName( fileName ), W_OK ) < 0 );
+}
+
+#include "resourcefileconfig.moc"
diff --git a/kabc/plugins/file/resourcefileconfig.h b/kabc/plugins/file/resourcefileconfig.h
new file mode 100644
index 000000000..3e92f0728
--- /dev/null
+++ b/kabc/plugins/file/resourcefileconfig.h
@@ -0,0 +1,57 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCEFILECONFIG_H
+#define RESOURCEFILECONFIG_H
+
+#include <kcombobox.h>
+#include <kurlrequester.h>
+
+#include <kresources/configwidget.h>
+
+namespace KABC {
+
+class KABC_EXPORT ResourceFileConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+public:
+ ResourceFileConfig( QWidget* parent = 0, const char* name = 0 );
+
+ void setEditMode( bool value );
+
+public slots:
+ void loadSettings( KRES::Resource *resource );
+ void saveSettings( KRES::Resource *resource );
+
+protected slots:
+ void checkFilePermissions( const QString& fileName );
+
+private:
+ KComboBox* mFormatBox;
+ KURLRequester* mFileNameEdit;
+ bool mInEditMode;
+
+ QStringList mFormatTypes;
+};
+
+}
+
+#endif
diff --git a/kabc/plugins/file/resourcefileplugin.cpp b/kabc/plugins/file/resourcefileplugin.cpp
new file mode 100644
index 000000000..4dce19bc0
--- /dev/null
+++ b/kabc/plugins/file/resourcefileplugin.cpp
@@ -0,0 +1,32 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "resourcefile.h"
+#include "resourcefileconfig.h"
+
+using namespace KABC;
+
+extern "C"
+{
+ KDE_EXPORT void *init_kabc_file()
+ {
+ return new KRES::PluginFactory<ResourceFile, ResourceFileConfig>();
+ }
+}
diff --git a/kabc/plugins/ldapkio/Makefile.am b/kabc/plugins/ldapkio/Makefile.am
new file mode 100644
index 000000000..64a72b8f2
--- /dev/null
+++ b/kabc/plugins/ldapkio/Makefile.am
@@ -0,0 +1,28 @@
+INCLUDES = -I$(top_srcdir)/kabc -I$(top_builddir)/kabc $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = resourceldapkioconfig.h
+
+lib_LTLIBRARIES = libkabc_ldapkio.la
+libkabc_ldapkio_la_SOURCES = resourceldapkio.cpp resourceldapkioconfig.cpp
+libkabc_ldapkio_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined
+libkabc_ldapkio_la_LIBADD = $(top_builddir)/kabc/libkabc.la $(LIB_KIO)
+libkabc_ldapkio_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h
+
+kde_module_LTLIBRARIES = kabc_ldapkio.la
+kabc_ldapkio_la_SOURCES = resourceldapkioplugin.cpp
+kabc_ldapkio_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kabc_ldapkio_la_LIBADD = libkabc_ldapkio.la
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kabc_ldapkio.pot
+
+kabcincludedir = $(includedir)/kabc
+kabcinclude_HEADERS = resourceldapkio.h
+
+servicedir = $(kde_servicesdir)/kresources/kabc
+service_DATA = ldapkio.desktop
+
+resourceldapkioplugin.lo: ../../addressee.h
diff --git a/kabc/plugins/ldapkio/ldapkio.desktop b/kabc/plugins/ldapkio/ldapkio.desktop
new file mode 100644
index 000000000..ebd8b98dd
--- /dev/null
+++ b/kabc/plugins/ldapkio/ldapkio.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Name=LDAP
+Name[bn]=এল-ডি-এ-পি (LDAP)
+Name[hi]=एलडीएपी (LDAP)
+Name[te]=ఎల్డిఏపి
+X-KDE-Library=kabc_ldapkio
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=ldapkio
diff --git a/kabc/plugins/ldapkio/resourceldapkio.cpp b/kabc/plugins/ldapkio/resourceldapkio.cpp
new file mode 100644
index 000000000..30b8ba7e0
--- /dev/null
+++ b/kabc/plugins/ldapkio/resourceldapkio.cpp
@@ -0,0 +1,1041 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+ Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include <qapplication.h>
+#include <qbuffer.h>
+#include <qfile.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstringhandler.h>
+#include <ktempfile.h>
+
+#include <stdlib.h>
+#include <kio/netaccess.h>
+#include <kabc/ldif.h>
+#include <kabc/ldapurl.h>
+
+#include "resourceldapkio.h"
+#include "resourceldapkioconfig.h"
+
+using namespace KABC;
+
+// Hack from Netaccess
+void qt_enter_modal( QWidget *widget );
+void qt_leave_modal( QWidget *widget );
+
+class ResourceLDAPKIO::ResourceLDAPKIOPrivate
+{
+ public:
+ LDIF mLdif;
+ bool mTLS,mSSL,mSubTree;
+ QString mResultDn;
+ Addressee mAddr;
+ Address mAd;
+ Resource::Iterator mSaveIt;
+ bool mSASL;
+ QString mMech;
+ QString mRealm, mBindDN;
+ LDAPUrl mLDAPUrl;
+ int mVer, mSizeLimit, mTimeLimit, mRDNPrefix;
+ int mError;
+ int mCachePolicy;
+ bool mReadOnly;
+ bool mAutoCache;
+ QString mCacheDst;
+ KTempFile *mTmp;
+};
+
+ResourceLDAPKIO::ResourceLDAPKIO( const KConfig *config )
+ : Resource( config )
+{
+ d = new ResourceLDAPKIOPrivate;
+ if ( config ) {
+ QMap<QString, QString> attrList;
+ QStringList attributes = config->readListEntry( "LdapAttributes" );
+ for ( uint pos = 0; pos < attributes.count(); pos += 2 )
+ mAttributes.insert( attributes[ pos ], attributes[ pos + 1 ] );
+
+ mUser = config->readEntry( "LdapUser" );
+ mPassword = KStringHandler::obscure( config->readEntry( "LdapPassword" ) );
+ mDn = config->readEntry( "LdapDn" );
+ mHost = config->readEntry( "LdapHost" );
+ mPort = config->readNumEntry( "LdapPort", 389 );
+ mFilter = config->readEntry( "LdapFilter" );
+ mAnonymous = config->readBoolEntry( "LdapAnonymous" );
+ d->mTLS = config->readBoolEntry( "LdapTLS" );
+ d->mSSL = config->readBoolEntry( "LdapSSL" );
+ d->mSubTree = config->readBoolEntry( "LdapSubTree" );
+ d->mSASL = config->readBoolEntry( "LdapSASL" );
+ d->mMech = config->readEntry( "LdapMech" );
+ d->mRealm = config->readEntry( "LdapRealm" );
+ d->mBindDN = config->readEntry( "LdapBindDN" );
+ d->mVer = config->readNumEntry( "LdapVer", 3 );
+ d->mTimeLimit = config->readNumEntry( "LdapTimeLimit", 0 );
+ d->mSizeLimit = config->readNumEntry( "LdapSizeLimit", 0 );
+ d->mRDNPrefix = config->readNumEntry( "LdapRDNPrefix", 0 );
+ d->mCachePolicy = config->readNumEntry( "LdapCachePolicy", 0 );
+ d->mAutoCache = config->readBoolEntry( "LdapAutoCache", true );
+ } else {
+ mPort = 389;
+ mAnonymous = true;
+ mUser = mPassword = mHost = mFilter = mDn = "";
+ d->mMech = d->mRealm = d->mBindDN = "";
+ d->mTLS = d->mSSL = d->mSubTree = d->mSASL = false;
+ d->mVer = 3; d->mRDNPrefix = 0;
+ d->mTimeLimit = d->mSizeLimit = 0;
+ d->mCachePolicy = Cache_No;
+ d->mAutoCache = true;
+ }
+ d->mCacheDst = KGlobal::dirs()->saveLocation("cache", "ldapkio") + "/" +
+ type() + "_" + identifier();
+ init();
+}
+
+ResourceLDAPKIO::~ResourceLDAPKIO()
+{
+ delete d;
+}
+
+void ResourceLDAPKIO::enter_loop()
+{
+ QWidget dummy(0,0,WType_Dialog | WShowModal);
+ dummy.setFocusPolicy( QWidget::NoFocus );
+ qt_enter_modal(&dummy);
+ qApp->enter_loop();
+ qt_leave_modal(&dummy);
+}
+
+void ResourceLDAPKIO::entries( KIO::Job*, const KIO::UDSEntryList & list )
+{
+ KIO::UDSEntryListConstIterator it = list.begin();
+ KIO::UDSEntryListConstIterator end = list.end();
+ for (; it != end; ++it) {
+ KIO::UDSEntry::ConstIterator it2 = (*it).begin();
+ for( ; it2 != (*it).end(); it2++ ) {
+ if ( (*it2).m_uds == KIO::UDS_URL ) {
+ KURL tmpurl( (*it2).m_str );
+ d->mResultDn = tmpurl.path();
+ kdDebug(7125) << "findUid(): " << d->mResultDn << endl;
+ if ( d->mResultDn.startsWith("/") ) d->mResultDn.remove(0,1);
+ return;
+ }
+ }
+ }
+}
+
+void ResourceLDAPKIO::listResult( KIO::Job *job)
+{
+ d->mError = job->error();
+ if ( d->mError && d->mError != KIO::ERR_USER_CANCELED )
+ mErrorMsg = job->errorString();
+ else
+ mErrorMsg = "";
+ qApp->exit_loop();
+}
+
+QString ResourceLDAPKIO::findUid( const QString &uid )
+{
+ LDAPUrl url( d->mLDAPUrl );
+ KIO::UDSEntry entry;
+
+ mErrorMsg = d->mResultDn = "";
+
+ url.setAttributes("dn");
+ url.setFilter( "(" + mAttributes[ "uid" ] + "=" + uid + ")" + mFilter );
+ url.setExtension( "x-dir", "one" );
+
+ kdDebug(7125) << "ResourceLDAPKIO::findUid() uid: " << uid << " url " <<
+ url.prettyURL() << endl;
+
+ KIO::ListJob * listJob = KIO::listDir( url, false /* no GUI */ );
+ connect( listJob,
+ SIGNAL( entries( KIO::Job *, const KIO::UDSEntryList& ) ),
+ SLOT( entries( KIO::Job*, const KIO::UDSEntryList& ) ) );
+ connect( listJob, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( listResult( KIO::Job* ) ) );
+
+ enter_loop();
+ return d->mResultDn;
+}
+
+QCString ResourceLDAPKIO::addEntry( const QString &attr, const QString &value, bool mod )
+{
+ QCString tmp;
+ if ( !attr.isEmpty() ) {
+ if ( mod ) tmp += LDIF::assembleLine( "replace", attr ) + "\n";
+ tmp += LDIF::assembleLine( attr, value ) + "\n";
+ if ( mod ) tmp += "-\n";
+ }
+ return ( tmp );
+}
+
+bool ResourceLDAPKIO::AddresseeToLDIF( QByteArray &ldif, const Addressee &addr,
+ const QString &olddn )
+{
+ QCString tmp;
+ QString dn;
+ QByteArray data;
+ bool mod = false;
+
+ if ( olddn.isEmpty() ) {
+ //insert new entry
+ switch ( d->mRDNPrefix ) {
+ case 1:
+ dn = mAttributes[ "uid" ] + "=" + addr.uid() + "," +mDn;
+ break;
+ case 0:
+ default:
+ dn = mAttributes[ "commonName" ] + "=" + addr.assembledName() + "," +mDn;
+ break;
+ }
+ } else {
+ //modify existing entry
+ mod = true;
+ if ( olddn.startsWith( mAttributes[ "uid" ] ) ) {
+ dn = mAttributes[ "uid" ] + "=" + addr.uid() + "," + olddn.section( ',', 1 );
+ } else if ( olddn.startsWith( mAttributes[ "commonName" ] ) ) {
+ dn = mAttributes[ "commonName" ] + "=" + addr.assembledName() + "," +
+ olddn.section( ',', 1 );
+ } else {
+ dn = olddn;
+ }
+
+ if ( olddn.lower() != dn.lower() ) {
+ tmp = LDIF::assembleLine( "dn", olddn ) + "\n";
+ tmp += "changetype: modrdn\n";
+ tmp += LDIF::assembleLine( "newrdn", dn.section( ',', 0, 0 ) ) + "\n";
+ tmp += "deleteoldrdn: 1\n\n";
+ }
+ }
+
+
+ tmp += LDIF::assembleLine( "dn", dn ) + "\n";
+ if ( mod ) tmp += "changetype: modify\n";
+ if ( !mod ) {
+ tmp += "objectClass: top\n";
+ QStringList obclass = QStringList::split( ',', mAttributes[ "objectClass" ] );
+ for ( QStringList::iterator it = obclass.begin(); it != obclass.end(); it++ ) {
+ tmp += LDIF::assembleLine( "objectClass", *it ) + "\n";
+ }
+ }
+
+ tmp += addEntry( mAttributes[ "commonName" ], addr.assembledName(), mod );
+ tmp += addEntry( mAttributes[ "formattedName" ], addr.formattedName(), mod );
+ tmp += addEntry( mAttributes[ "givenName" ], addr.givenName(), mod );
+ tmp += addEntry( mAttributes[ "familyName" ], addr.familyName(), mod );
+ tmp += addEntry( mAttributes[ "uid" ], addr.uid(), mod );
+
+ PhoneNumber number;
+ number = addr.phoneNumber( PhoneNumber::Home );
+ tmp += addEntry( mAttributes[ "phoneNumber" ], number.number().utf8(), mod );
+ number = addr.phoneNumber( PhoneNumber::Work );
+ tmp += addEntry( mAttributes[ "telephoneNumber" ], number.number().utf8(), mod );
+ number = addr.phoneNumber( PhoneNumber::Fax );
+ tmp += addEntry( mAttributes[ "facsimileTelephoneNumber" ], number.number().utf8(), mod );
+ number = addr.phoneNumber( PhoneNumber::Cell );
+ tmp += addEntry( mAttributes[ "mobile" ], number.number().utf8(), mod );
+ number = addr.phoneNumber( PhoneNumber::Pager );
+ tmp += addEntry( mAttributes[ "pager" ], number.number().utf8(), mod );
+
+ tmp += addEntry( mAttributes[ "description" ], addr.note(), mod );
+ tmp += addEntry( mAttributes[ "title" ], addr.title(), mod );
+ tmp += addEntry( mAttributes[ "organization" ], addr.organization(), mod );
+
+ Address ad = addr.address( Address::Home );
+ if ( !ad.isEmpty() ) {
+ tmp += addEntry( mAttributes[ "street" ], ad.street(), mod );
+ tmp += addEntry( mAttributes[ "state" ], ad.region(), mod );
+ tmp += addEntry( mAttributes[ "city" ], ad.locality(), mod );
+ tmp += addEntry( mAttributes[ "postalcode" ], ad.postalCode(), mod );
+ }
+
+ QStringList emails = addr.emails();
+ QStringList::ConstIterator mailIt = emails.begin();
+
+ if ( !mAttributes[ "mail" ].isEmpty() ) {
+ if ( mod ) tmp +=
+ LDIF::assembleLine( "replace", mAttributes[ "mail" ] ) + "\n";
+ if ( mailIt != emails.end() ) {
+ tmp += LDIF::assembleLine( mAttributes[ "mail" ], *mailIt ) + "\n";
+ mailIt ++;
+ }
+ if ( mod && mAttributes[ "mail" ] != mAttributes[ "mailAlias" ] ) tmp += "-\n";
+ }
+
+ if ( !mAttributes[ "mailAlias" ].isEmpty() ) {
+ if ( mod && mAttributes[ "mail" ] != mAttributes[ "mailAlias" ] ) tmp +=
+ LDIF::assembleLine( "replace", mAttributes[ "mailAlias" ] ) + "\n";
+ for ( ; mailIt != emails.end(); ++mailIt ) {
+ tmp += LDIF::assembleLine( mAttributes[ "mailAlias" ], *mailIt ) + "\n" ;
+ }
+ if ( mod ) tmp += "-\n";
+ }
+
+ if ( !mAttributes[ "jpegPhoto" ].isEmpty() ) {
+ QByteArray pic;
+ QBuffer buffer( pic );
+ buffer.open( IO_WriteOnly );
+ addr.photo().data().save( &buffer, "JPEG" );
+
+ if ( mod ) tmp +=
+ LDIF::assembleLine( "replace", mAttributes[ "jpegPhoto" ] ) + "\n";
+ tmp += LDIF::assembleLine( mAttributes[ "jpegPhoto" ], pic, 76 ) + "\n";
+ if ( mod ) tmp += "-\n";
+ }
+
+ tmp += "\n";
+ kdDebug(7125) << "ldif: " << QString::fromUtf8(tmp) << endl;
+ ldif = tmp;
+ return true;
+}
+
+void ResourceLDAPKIO::setReadOnly( bool value )
+{
+ //save the original readonly flag, because offline using disables writing
+ d->mReadOnly = true;
+ Resource::setReadOnly( value );
+}
+
+void ResourceLDAPKIO::init()
+{
+ if ( mPort == 0 ) mPort = 389;
+
+ /**
+ If you want to add new attributes, append them here, add a
+ translation string in the ctor of AttributesDialog and
+ handle them in the load() method below.
+ These are the default values
+ */
+ if ( !mAttributes.contains("objectClass") )
+ mAttributes.insert( "objectClass", "inetOrgPerson" );
+ if ( !mAttributes.contains("commonName") )
+ mAttributes.insert( "commonName", "cn" );
+ if ( !mAttributes.contains("formattedName") )
+ mAttributes.insert( "formattedName", "displayName" );
+ if ( !mAttributes.contains("familyName") )
+ mAttributes.insert( "familyName", "sn" );
+ if ( !mAttributes.contains("givenName") )
+ mAttributes.insert( "givenName", "givenName" );
+ if ( !mAttributes.contains("mail") )
+ mAttributes.insert( "mail", "mail" );
+ if ( !mAttributes.contains("mailAlias") )
+ mAttributes.insert( "mailAlias", "" );
+ if ( !mAttributes.contains("phoneNumber") )
+ mAttributes.insert( "phoneNumber", "homePhone" );
+ if ( !mAttributes.contains("telephoneNumber") )
+ mAttributes.insert( "telephoneNumber", "telephoneNumber" );
+ if ( !mAttributes.contains("facsimileTelephoneNumber") )
+ mAttributes.insert( "facsimileTelephoneNumber", "facsimileTelephoneNumber" );
+ if ( !mAttributes.contains("mobile") )
+ mAttributes.insert( "mobile", "mobile" );
+ if ( !mAttributes.contains("pager") )
+ mAttributes.insert( "pager", "pager" );
+ if ( !mAttributes.contains("description") )
+ mAttributes.insert( "description", "description" );
+
+ if ( !mAttributes.contains("title") )
+ mAttributes.insert( "title", "title" );
+ if ( !mAttributes.contains("street") )
+ mAttributes.insert( "street", "street" );
+ if ( !mAttributes.contains("state") )
+ mAttributes.insert( "state", "st" );
+ if ( !mAttributes.contains("city") )
+ mAttributes.insert( "city", "l" );
+ if ( !mAttributes.contains("organization") )
+ mAttributes.insert( "organization", "o" );
+ if ( !mAttributes.contains("postalcode") )
+ mAttributes.insert( "postalcode", "postalCode" );
+
+ if ( !mAttributes.contains("uid") )
+ mAttributes.insert( "uid", "uid" );
+ if ( !mAttributes.contains("jpegPhoto") )
+ mAttributes.insert( "jpegPhoto", "jpegPhoto" );
+
+ d->mLDAPUrl = KURL();
+ if ( !mAnonymous ) {
+ d->mLDAPUrl.setUser( mUser );
+ d->mLDAPUrl.setPass( mPassword );
+ }
+ d->mLDAPUrl.setProtocol( d->mSSL ? "ldaps" : "ldap");
+ d->mLDAPUrl.setHost( mHost );
+ d->mLDAPUrl.setPort( mPort );
+ d->mLDAPUrl.setDn( mDn );
+
+ if (!mAttributes.empty()) {
+ QMap<QString,QString>::Iterator it;
+ QStringList attr;
+ for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) {
+ if ( !it.data().isEmpty() && it.key() != "objectClass" )
+ attr.append( it.data() );
+ }
+ d->mLDAPUrl.setAttributes( attr );
+ }
+
+ d->mLDAPUrl.setScope( d->mSubTree ? LDAPUrl::Sub : LDAPUrl::One );
+ if ( !mFilter.isEmpty() && mFilter != "(objectClass=*)" )
+ d->mLDAPUrl.setFilter( mFilter );
+ d->mLDAPUrl.setExtension( "x-dir", "base" );
+ if ( d->mTLS ) d->mLDAPUrl.setExtension( "x-tls", "" );
+ d->mLDAPUrl.setExtension( "x-ver", QString::number( d->mVer ) );
+ if ( d->mSizeLimit )
+ d->mLDAPUrl.setExtension( "x-sizelimit", QString::number( d->mSizeLimit ) );
+ if ( d->mTimeLimit )
+ d->mLDAPUrl.setExtension( "x-timelimit", QString::number( d->mTimeLimit ) );
+ if ( d->mSASL ) {
+ d->mLDAPUrl.setExtension( "x-sasl", "" );
+ if ( !d->mBindDN.isEmpty() ) d->mLDAPUrl.setExtension( "bindname", d->mBindDN );
+ if ( !d->mMech.isEmpty() ) d->mLDAPUrl.setExtension( "x-mech", d->mMech );
+ if ( !d->mRealm.isEmpty() ) d->mLDAPUrl.setExtension( "x-realm", d->mRealm );
+ }
+
+ d->mReadOnly = readOnly();
+
+ kdDebug(7125) << "resource_ldapkio url: " << d->mLDAPUrl.prettyURL() << endl;
+}
+
+void ResourceLDAPKIO::writeConfig( KConfig *config )
+{
+ Resource::writeConfig( config );
+
+ config->writeEntry( "LdapUser", mUser );
+ config->writeEntry( "LdapPassword", KStringHandler::obscure( mPassword ) );
+ config->writeEntry( "LdapDn", mDn );
+ config->writeEntry( "LdapHost", mHost );
+ config->writeEntry( "LdapPort", mPort );
+ config->writeEntry( "LdapFilter", mFilter );
+ config->writeEntry( "LdapAnonymous", mAnonymous );
+ config->writeEntry( "LdapTLS", d->mTLS );
+ config->writeEntry( "LdapSSL", d->mSSL );
+ config->writeEntry( "LdapSubTree", d->mSubTree );
+ config->writeEntry( "LdapSASL", d->mSASL );
+ config->writeEntry( "LdapMech", d->mMech );
+ config->writeEntry( "LdapVer", d->mVer );
+ config->writeEntry( "LdapTimeLimit", d->mTimeLimit );
+ config->writeEntry( "LdapSizeLimit", d->mSizeLimit );
+ config->writeEntry( "LdapRDNPrefix", d->mRDNPrefix );
+ config->writeEntry( "LdapRealm", d->mRealm );
+ config->writeEntry( "LdapBindDN", d->mBindDN );
+ config->writeEntry( "LdapCachePolicy", d->mCachePolicy );
+ config->writeEntry( "LdapAutoCache", d->mAutoCache );
+
+ QStringList attributes;
+ QMap<QString, QString>::Iterator it;
+ for ( it = mAttributes.begin(); it != mAttributes.end(); ++it )
+ attributes << it.key() << it.data();
+
+ config->writeEntry( "LdapAttributes", attributes );
+}
+
+Ticket *ResourceLDAPKIO::requestSaveTicket()
+{
+ if ( !addressBook() ) {
+ kdDebug(7125) << "no addressbook" << endl;
+ return 0;
+ }
+
+ return createTicket( this );
+}
+
+void ResourceLDAPKIO::releaseSaveTicket( Ticket *ticket )
+{
+ delete ticket;
+}
+
+bool ResourceLDAPKIO::doOpen()
+{
+ return true;
+}
+
+void ResourceLDAPKIO::doClose()
+{
+}
+
+void ResourceLDAPKIO::createCache()
+{
+ d->mTmp = NULL;
+ if ( d->mCachePolicy == Cache_NoConnection && d->mAutoCache ) {
+ d->mTmp = new KTempFile( d->mCacheDst, "tmp" );
+ d->mTmp->setAutoDelete( true );
+ }
+}
+
+void ResourceLDAPKIO::activateCache()
+{
+ if ( d->mTmp && d->mError == 0 ) {
+ d->mTmp->close();
+ rename( QFile::encodeName( d->mTmp->name() ), QFile::encodeName( d->mCacheDst ) );
+ }
+ if ( d->mTmp ) {
+ delete d->mTmp;
+ d->mTmp = 0;
+ }
+}
+
+KIO::Job *ResourceLDAPKIO::loadFromCache()
+{
+ KIO::Job *job = NULL;
+ if ( d->mCachePolicy == Cache_Always ||
+ ( d->mCachePolicy == Cache_NoConnection &&
+ d->mError == KIO::ERR_COULD_NOT_CONNECT ) ) {
+
+ d->mAddr = Addressee();
+ d->mAd = Address( Address::Home );
+ //initialize ldif parser
+ d->mLdif.startParsing();
+
+ Resource::setReadOnly( true );
+
+ KURL url( d->mCacheDst );
+ job = KIO::get( url, true, false );
+ connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
+ this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
+ }
+ return job;
+}
+
+bool ResourceLDAPKIO::load()
+{
+ kdDebug(7125) << "ResourceLDAPKIO::load()" << endl;
+ KIO::Job *job;
+
+ clear();
+ //clear the addressee
+ d->mAddr = Addressee();
+ d->mAd = Address( Address::Home );
+ //initialize ldif parser
+ d->mLdif.startParsing();
+
+ //set to original settings, offline use will disable writing
+ Resource::setReadOnly( d->mReadOnly );
+
+ createCache();
+ if ( d->mCachePolicy != Cache_Always ) {
+ job = KIO::get( d->mLDAPUrl, true, false );
+ connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
+ this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
+ connect( job, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( syncLoadSaveResult( KIO::Job* ) ) );
+ enter_loop();
+ }
+
+ job = loadFromCache();
+ if ( job ) {
+ connect( job, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( syncLoadSaveResult( KIO::Job* ) ) );
+ enter_loop();
+ }
+ if ( mErrorMsg.isEmpty() ) {
+ kdDebug(7125) << "ResourceLDAPKIO load ok!" << endl;
+ return true;
+ } else {
+ kdDebug(7125) << "ResourceLDAPKIO load finished with error: " << mErrorMsg << endl;
+ addressBook()->error( mErrorMsg );
+ return false;
+ }
+}
+
+bool ResourceLDAPKIO::asyncLoad()
+{
+ clear();
+ //clear the addressee
+ d->mAddr = Addressee();
+ d->mAd = Address( Address::Home );
+ //initialize ldif parser
+ d->mLdif.startParsing();
+
+ Resource::setReadOnly( d->mReadOnly );
+
+ createCache();
+ if ( d->mCachePolicy != Cache_Always ) {
+ KIO::Job *job = KIO::get( d->mLDAPUrl, true, false );
+ connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
+ this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
+ connect( job, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( result( KIO::Job* ) ) );
+ } else {
+ result( NULL );
+ }
+ return true;
+}
+
+void ResourceLDAPKIO::data( KIO::Job *, const QByteArray &data )
+{
+ if ( data.size() ) {
+ d->mLdif.setLDIF( data );
+ if ( d->mTmp ) {
+ d->mTmp->file()->writeBlock( data );
+ }
+ } else {
+ d->mLdif.endLDIF();
+ }
+
+ LDIF::ParseVal ret;
+ QString name;
+ QByteArray value;
+ do {
+ ret = d->mLdif.nextItem();
+ switch ( ret ) {
+ case LDIF::NewEntry:
+ kdDebug(7125) << "new entry: " << d->mLdif.dn() << endl;
+ break;
+ case LDIF::Item:
+ name = d->mLdif.attr().lower();
+ value = d->mLdif.val();
+ if ( name == mAttributes[ "commonName" ].lower() ) {
+ if ( !d->mAddr.formattedName().isEmpty() ) {
+ QString fn = d->mAddr.formattedName();
+ d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
+ d->mAddr.setFormattedName( fn );
+ } else
+ d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "formattedName" ].lower() ) {
+ d->mAddr.setFormattedName( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "givenName" ].lower() ) {
+ d->mAddr.setGivenName( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "mail" ].lower() ) {
+ d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), true );
+ } else if ( name == mAttributes[ "mailAlias" ].lower() ) {
+ d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), false );
+ } else if ( name == mAttributes[ "phoneNumber" ].lower() ) {
+ PhoneNumber phone;
+ phone.setNumber( QString::fromUtf8( value, value.size() ) );
+ d->mAddr.insertPhoneNumber( phone );
+ } else if ( name == mAttributes[ "telephoneNumber" ].lower() ) {
+ PhoneNumber phone( QString::fromUtf8( value, value.size() ),
+ PhoneNumber::Work );
+ d->mAddr.insertPhoneNumber( phone );
+ } else if ( name == mAttributes[ "facsimileTelephoneNumber" ].lower() ) {
+ PhoneNumber phone( QString::fromUtf8( value, value.size() ),
+ PhoneNumber::Fax );
+ d->mAddr.insertPhoneNumber( phone );
+ } else if ( name == mAttributes[ "mobile" ].lower() ) {
+ PhoneNumber phone( QString::fromUtf8( value, value.size() ),
+ PhoneNumber::Cell );
+ d->mAddr.insertPhoneNumber( phone );
+ } else if ( name == mAttributes[ "pager" ].lower() ) {
+ PhoneNumber phone( QString::fromUtf8( value, value.size() ),
+ PhoneNumber::Pager );
+ d->mAddr.insertPhoneNumber( phone );
+ } else if ( name == mAttributes[ "description" ].lower() ) {
+ d->mAddr.setNote( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "title" ].lower() ) {
+ d->mAddr.setTitle( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "street" ].lower() ) {
+ d->mAd.setStreet( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "state" ].lower() ) {
+ d->mAd.setRegion( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "city" ].lower() ) {
+ d->mAd.setLocality( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "postalcode" ].lower() ) {
+ d->mAd.setPostalCode( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "organization" ].lower() ) {
+ d->mAddr.setOrganization( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "familyName" ].lower() ) {
+ d->mAddr.setFamilyName( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "uid" ].lower() ) {
+ d->mAddr.setUid( QString::fromUtf8( value, value.size() ) );
+ } else if ( name == mAttributes[ "jpegPhoto" ].lower() ) {
+ KABC::Picture photo;
+ QImage img( value );
+ if ( !img.isNull() ) {
+ photo.setData( img );
+ photo.setType( "image/jpeg" );
+ d->mAddr.setPhoto( photo );
+ }
+ }
+
+ break;
+ case LDIF::EndEntry: {
+ d->mAddr.setResource( this );
+ d->mAddr.insertAddress( d->mAd );
+ d->mAddr.setChanged( false );
+ insertAddressee( d->mAddr );
+ //clear the addressee
+ d->mAddr = Addressee();
+ d->mAd = Address( Address::Home );
+ }
+ break;
+ default:
+ break;
+ }
+ } while ( ret != LDIF::MoreData );
+}
+
+void ResourceLDAPKIO::loadCacheResult( KIO::Job *job )
+{
+ mErrorMsg = "";
+ d->mError = job->error();
+ if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
+ mErrorMsg = job->errorString();
+ }
+ if ( !mErrorMsg.isEmpty() )
+ emit loadingError( this, mErrorMsg );
+ else
+ emit loadingFinished( this );
+}
+
+void ResourceLDAPKIO::result( KIO::Job *job )
+{
+ mErrorMsg = "";
+ if ( job ) {
+ d->mError = job->error();
+ if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
+ mErrorMsg = job->errorString();
+ }
+ } else {
+ d->mError = 0;
+ }
+ activateCache();
+
+ KIO::Job *cjob;
+ cjob = loadFromCache();
+ if ( cjob ) {
+ connect( cjob, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( loadCacheResult( KIO::Job* ) ) );
+ } else {
+ if ( !mErrorMsg.isEmpty() )
+ emit loadingError( this, mErrorMsg );
+ else
+ emit loadingFinished( this );
+ }
+}
+
+bool ResourceLDAPKIO::save( Ticket* )
+{
+ kdDebug(7125) << "ResourceLDAPKIO save" << endl;
+
+ d->mSaveIt = begin();
+ KIO::Job *job = KIO::put( d->mLDAPUrl, -1, true, false, false );
+ connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
+ this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
+ connect( job, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( syncLoadSaveResult( KIO::Job* ) ) );
+ enter_loop();
+ if ( mErrorMsg.isEmpty() ) {
+ kdDebug(7125) << "ResourceLDAPKIO save ok!" << endl;
+ return true;
+ } else {
+ kdDebug(7125) << "ResourceLDAPKIO finished with error: " << mErrorMsg << endl;
+ addressBook()->error( mErrorMsg );
+ return false;
+ }
+}
+
+bool ResourceLDAPKIO::asyncSave( Ticket* )
+{
+ kdDebug(7125) << "ResourceLDAPKIO asyncSave" << endl;
+ d->mSaveIt = begin();
+ KIO::Job *job = KIO::put( d->mLDAPUrl, -1, true, false, false );
+ connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
+ this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
+ connect( job, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( saveResult( KIO::Job* ) ) );
+ return true;
+}
+
+void ResourceLDAPKIO::syncLoadSaveResult( KIO::Job *job )
+{
+ d->mError = job->error();
+ if ( d->mError && d->mError != KIO::ERR_USER_CANCELED )
+ mErrorMsg = job->errorString();
+ else
+ mErrorMsg = "";
+ activateCache();
+
+ qApp->exit_loop();
+}
+
+void ResourceLDAPKIO::saveResult( KIO::Job *job )
+{
+ d->mError = job->error();
+ if ( d->mError && d->mError != KIO::ERR_USER_CANCELED )
+ emit savingError( this, job->errorString() );
+ else
+ emit savingFinished( this );
+}
+
+void ResourceLDAPKIO::saveData( KIO::Job*, QByteArray& data )
+{
+ while ( d->mSaveIt != end() &&
+ !(*d->mSaveIt).changed() ) d->mSaveIt++;
+
+ if ( d->mSaveIt == end() ) {
+ kdDebug(7125) << "ResourceLDAPKIO endData" << endl;
+ data.resize(0);
+ return;
+ }
+
+ kdDebug(7125) << "ResourceLDAPKIO saveData: " << (*d->mSaveIt).assembledName() << endl;
+
+ AddresseeToLDIF( data, *d->mSaveIt, findUid( (*d->mSaveIt).uid() ) );
+// kdDebug(7125) << "ResourceLDAPKIO save LDIF: " << QString::fromUtf8(data) << endl;
+ // mark as unchanged
+ (*d->mSaveIt).setChanged( false );
+
+ d->mSaveIt++;
+}
+
+void ResourceLDAPKIO::removeAddressee( const Addressee& addr )
+{
+ QString dn = findUid( addr.uid() );
+
+ kdDebug(7125) << "ResourceLDAPKIO: removeAddressee: " << dn << endl;
+
+ if ( !mErrorMsg.isEmpty() ) {
+ addressBook()->error( mErrorMsg );
+ return;
+ }
+ if ( !dn.isEmpty() ) {
+ kdDebug(7125) << "ResourceLDAPKIO: found uid: " << dn << endl;
+ LDAPUrl url( d->mLDAPUrl );
+ url.setPath( "/" + dn );
+ url.setExtension( "x-dir", "base" );
+ url.setScope( LDAPUrl::Base );
+ if ( KIO::NetAccess::del( url, NULL ) ) mAddrMap.erase( addr.uid() );
+ } else {
+ //maybe it's not saved yet
+ mAddrMap.erase( addr.uid() );
+ }
+}
+
+
+void ResourceLDAPKIO::setUser( const QString &user )
+{
+ mUser = user;
+}
+
+QString ResourceLDAPKIO::user() const
+{
+ return mUser;
+}
+
+void ResourceLDAPKIO::setPassword( const QString &password )
+{
+ mPassword = password;
+}
+
+QString ResourceLDAPKIO::password() const
+{
+ return mPassword;
+}
+
+void ResourceLDAPKIO::setDn( const QString &dn )
+{
+ mDn = dn;
+}
+
+QString ResourceLDAPKIO::dn() const
+{
+ return mDn;
+}
+
+void ResourceLDAPKIO::setHost( const QString &host )
+{
+ mHost = host;
+}
+
+QString ResourceLDAPKIO::host() const
+{
+ return mHost;
+}
+
+void ResourceLDAPKIO::setPort( int port )
+{
+ mPort = port;
+}
+
+int ResourceLDAPKIO::port() const
+{
+ return mPort;
+}
+
+void ResourceLDAPKIO::setVer( int ver )
+{
+ d->mVer = ver;
+}
+
+int ResourceLDAPKIO::ver() const
+{
+ return d->mVer;
+}
+
+void ResourceLDAPKIO::setSizeLimit( int sizelimit )
+{
+ d->mSizeLimit = sizelimit;
+}
+
+int ResourceLDAPKIO::sizeLimit()
+{
+ return d->mSizeLimit;
+}
+
+void ResourceLDAPKIO::setTimeLimit( int timelimit )
+{
+ d->mTimeLimit = timelimit;
+}
+
+int ResourceLDAPKIO::timeLimit()
+{
+ return d->mTimeLimit;
+}
+
+void ResourceLDAPKIO::setFilter( const QString &filter )
+{
+ mFilter = filter;
+}
+
+QString ResourceLDAPKIO::filter() const
+{
+ return mFilter;
+}
+
+void ResourceLDAPKIO::setIsAnonymous( bool value )
+{
+ mAnonymous = value;
+}
+
+bool ResourceLDAPKIO::isAnonymous() const
+{
+ return mAnonymous;
+}
+
+void ResourceLDAPKIO::setIsTLS( bool value )
+{
+ d->mTLS = value;
+}
+
+bool ResourceLDAPKIO::isTLS() const
+{
+ return d->mTLS;
+}
+void ResourceLDAPKIO::setIsSSL( bool value )
+{
+ d->mSSL = value;
+}
+
+bool ResourceLDAPKIO::isSSL() const
+{
+ return d->mSSL;
+}
+
+void ResourceLDAPKIO::setIsSubTree( bool value )
+{
+ d->mSubTree = value;
+}
+
+bool ResourceLDAPKIO::isSubTree() const
+{
+ return d->mSubTree;
+}
+
+void ResourceLDAPKIO::setAttributes( const QMap<QString, QString> &attributes )
+{
+ mAttributes = attributes;
+}
+
+QMap<QString, QString> ResourceLDAPKIO::attributes() const
+{
+ return mAttributes;
+}
+
+void ResourceLDAPKIO::setRDNPrefix( int value )
+{
+ d->mRDNPrefix = value;
+}
+
+int ResourceLDAPKIO::RDNPrefix() const
+{
+ return d->mRDNPrefix;
+}
+
+void ResourceLDAPKIO::setIsSASL( bool value )
+{
+ d->mSASL = value;
+}
+
+bool ResourceLDAPKIO::isSASL() const
+{
+ return d->mSASL;
+}
+
+void ResourceLDAPKIO::setMech( const QString &mech )
+{
+ d->mMech = mech;
+}
+
+QString ResourceLDAPKIO::mech() const
+{
+ return d->mMech;
+}
+
+void ResourceLDAPKIO::setRealm( const QString &realm )
+{
+ d->mRealm = realm;
+}
+
+QString ResourceLDAPKIO::realm() const
+{
+ return d->mRealm;
+}
+
+void ResourceLDAPKIO::setBindDN( const QString &binddn )
+{
+ d->mBindDN = binddn;
+}
+
+QString ResourceLDAPKIO::bindDN() const
+{
+ return d->mBindDN;
+}
+
+void ResourceLDAPKIO::setCachePolicy( int pol )
+{
+ d->mCachePolicy = pol;
+}
+
+int ResourceLDAPKIO::cachePolicy() const
+{
+ return d->mCachePolicy;
+}
+
+void ResourceLDAPKIO::setAutoCache( bool value )
+{
+ d->mAutoCache = value;
+}
+
+bool ResourceLDAPKIO::autoCache()
+{
+ return d->mAutoCache;
+}
+
+QString ResourceLDAPKIO::cacheDst() const
+{
+ return d->mCacheDst;
+}
+
+
+#include "resourceldapkio.moc"
diff --git a/kabc/plugins/ldapkio/resourceldapkio.h b/kabc/plugins/ldapkio/resourceldapkio.h
new file mode 100644
index 000000000..bd72a9b11
--- /dev/null
+++ b/kabc/plugins/ldapkio/resourceldapkio.h
@@ -0,0 +1,171 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+ Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_RESOURCELDAP_H
+#define KABC_RESOURCELDAP_H
+
+#include <kabc/resource.h>
+#include <kabc/ldif.h>
+#include <kio/job.h>
+
+class KConfig;
+
+namespace KABC {
+
+class KABC_EXPORT ResourceLDAPKIO : public Resource
+{
+ Q_OBJECT
+
+ public:
+ enum CachePolicy{ Cache_No, Cache_NoConnection, Cache_Always };
+
+ ResourceLDAPKIO( const KConfig* );
+ virtual ~ResourceLDAPKIO();
+ /**
+ * Call this after you used one of the set... methods
+ */
+ virtual void init();
+
+ virtual void writeConfig( KConfig* );
+
+ virtual bool doOpen();
+ virtual void doClose();
+
+ virtual Ticket *requestSaveTicket();
+ virtual void releaseSaveTicket( Ticket* );
+
+ virtual bool readOnly() const { return Resource::readOnly(); }
+ virtual void setReadOnly( bool value );
+
+ virtual bool load();
+ virtual bool asyncLoad();
+ virtual bool save( Ticket * ticket );
+ virtual bool asyncSave( Ticket * ticket );
+
+ virtual void removeAddressee( const Addressee& addr );
+
+ void setUser( const QString &user );
+ QString user() const;
+
+ void setPassword( const QString &password );
+ QString password() const;
+
+ void setRealm( const QString &realm );
+ QString realm() const;
+
+ void setBindDN( const QString &binddn );
+ QString bindDN() const;
+
+ void setDn( const QString &dn );
+ QString dn() const;
+
+ void setHost( const QString &host );
+ QString host() const;
+
+ void setPort( int port );
+ int port() const;
+
+ void setVer( int ver );
+ int ver() const;
+
+ void setSizeLimit( int sizelimit );
+ int sizeLimit();
+
+ void setTimeLimit( int timelimit );
+ int timeLimit();
+
+ void setFilter( const QString &filter );
+ QString filter() const;
+
+ void setIsAnonymous( bool value );
+ bool isAnonymous() const;
+
+ void setAttributes( const QMap<QString, QString> &attributes );
+ QMap<QString, QString> attributes() const;
+
+ void setRDNPrefix( int value );
+ int RDNPrefix() const;
+
+ void setIsTLS( bool value );
+ bool isTLS() const ;
+
+ void setIsSSL( bool value );
+ bool isSSL() const;
+
+ void setIsSubTree( bool value );
+ bool isSubTree() const ;
+
+ void setIsSASL( bool value );
+ bool isSASL() const ;
+
+ void setMech( const QString &mech );
+ QString mech() const;
+
+ void setCachePolicy( int pol );
+ int cachePolicy() const;
+
+ void setAutoCache( bool value );
+ bool autoCache();
+
+ QString cacheDst() const;
+
+protected slots:
+ void entries( KIO::Job*, const KIO::UDSEntryList& );
+ void data( KIO::Job*, const QByteArray& );
+ void result( KIO::Job* );
+ void listResult( KIO::Job* );
+ void syncLoadSaveResult( KIO::Job* );
+ void saveResult( KIO::Job* );
+ void saveData( KIO::Job*, QByteArray& );
+ void loadCacheResult( KIO::Job* );
+
+ private:
+ QString mUser;
+ QString mPassword;
+ QString mDn;
+ QString mHost;
+ QString mFilter;
+ int mPort;
+ bool mAnonymous;
+ QMap<QString, QString> mAttributes;
+
+ KURL mLDAPUrl;
+ int mGetCounter; //KDE 4: remove
+ bool mErrorOccured; //KDE 4: remove
+ QString mErrorMsg;
+ QMap<KIO::Job*, QByteArray> mJobMap; //KDE 4: remove
+
+ KIO::Job *loadFromCache();
+ void createCache();
+ void activateCache();
+ void enter_loop();
+ QCString addEntry( const QString &attr, const QString &value, bool mod );
+ QString findUid( const QString &uid );
+ bool AddresseeToLDIF( QByteArray &ldif, const Addressee &addr,
+ const QString &olddn );
+
+ class ResourceLDAPKIOPrivate;
+ ResourceLDAPKIOPrivate *d;
+};
+
+}
+
+#endif
diff --git a/kabc/plugins/ldapkio/resourceldapkioconfig.cpp b/kabc/plugins/ldapkio/resourceldapkioconfig.cpp
new file mode 100644
index 000000000..ae54ab8c3
--- /dev/null
+++ b/kabc/plugins/ldapkio/resourceldapkioconfig.cpp
@@ -0,0 +1,388 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 - 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#include <qapplication.h>
+
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qspinbox.h>
+#include <qvbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+#include <qradiobutton.h>
+
+#include <kaccelmanager.h>
+#include <kcombobox.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <klocale.h>
+#include <klineedit.h>
+#include <kmessagebox.h>
+#include <kio/netaccess.h>
+
+#include "resourceldapkio.h"
+
+#include "resourceldapkioconfig.h"
+#include "resourceldapkioconfig.moc"
+
+using namespace KABC;
+
+ResourceLDAPKIOConfig::ResourceLDAPKIOConfig( QWidget* parent, const char* name )
+ : KRES::ConfigWidget( parent, name )
+{
+ QBoxLayout *mainLayout = new QVBoxLayout( this );
+ mainLayout->setAutoAdd( true );
+ cfg = new LdapConfigWidget( LdapConfigWidget::W_ALL, this );
+
+ mSubTree = new QCheckBox( i18n( "Sub-tree query" ), this );
+ QHBox *box = new QHBox( this );
+ box->setSpacing( KDialog::spacingHint() );
+ mEditButton = new QPushButton( i18n( "Edit Attributes..." ), box );
+ mCacheButton = new QPushButton( i18n( "Offline Use..." ), box );
+
+ connect( mEditButton, SIGNAL( clicked() ), SLOT( editAttributes() ) );
+ connect( mCacheButton, SIGNAL( clicked() ), SLOT( editCache() ) );
+}
+
+void ResourceLDAPKIOConfig::loadSettings( KRES::Resource *res )
+{
+ ResourceLDAPKIO *resource = dynamic_cast<ResourceLDAPKIO*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceLDAPKIOConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ cfg->setUser( resource->user() );
+ cfg->setPassword( resource->password() );
+ cfg->setRealm( resource->realm() );
+ cfg->setBindDN( resource->bindDN() );
+ cfg->setHost( resource->host() );
+ cfg->setPort( resource->port() );
+ cfg->setVer( resource->ver() );
+ cfg->setTimeLimit( resource->timeLimit() );
+ cfg->setSizeLimit( resource->sizeLimit() );
+ cfg->setDn( resource->dn() );
+ cfg->setFilter( resource->filter() );
+ cfg->setMech( resource->mech() );
+ if ( resource->isTLS() ) cfg->setSecTLS();
+ else if ( resource->isSSL() ) cfg->setSecSSL();
+ else cfg->setSecNO();
+ if ( resource->isAnonymous() ) cfg->setAuthAnon();
+ else if ( resource->isSASL() ) cfg->setAuthSASL();
+ else cfg->setAuthSimple();
+
+ mSubTree->setChecked( resource->isSubTree() );
+ mAttributes = resource->attributes();
+ mRDNPrefix = resource->RDNPrefix();
+ mCachePolicy = resource->cachePolicy();
+ mCacheDst = resource->cacheDst();
+ mAutoCache = resource->autoCache();
+}
+
+void ResourceLDAPKIOConfig::saveSettings( KRES::Resource *res )
+{
+ ResourceLDAPKIO *resource = dynamic_cast<ResourceLDAPKIO*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceLDAPKIOConfig::saveSettings(): cast failed" << endl;
+ return;
+ }
+
+ resource->setUser( cfg->user() );
+ resource->setPassword( cfg->password() );
+ resource->setRealm( cfg->realm() );
+ resource->setBindDN( cfg->bindDN() );
+ resource->setHost( cfg->host() );
+ resource->setPort( cfg->port() );
+ resource->setVer( cfg->ver() );
+ resource->setTimeLimit( cfg->timeLimit() );
+ resource->setSizeLimit( cfg->sizeLimit() );
+ resource->setDn( cfg->dn() );
+ resource->setFilter( cfg->filter() );
+ resource->setIsAnonymous( cfg->isAuthAnon() );
+ resource->setIsSASL( cfg->isAuthSASL() );
+ resource->setMech( cfg->mech() );
+ resource->setIsTLS( cfg->isSecTLS() );
+ resource->setIsSSL( cfg->isSecSSL() );
+ resource->setIsSubTree( mSubTree->isChecked() );
+ resource->setAttributes( mAttributes );
+ resource->setRDNPrefix( mRDNPrefix );
+ resource->setCachePolicy( mCachePolicy );
+ resource->init();
+
+}
+
+void ResourceLDAPKIOConfig::editAttributes()
+{
+ AttributesDialog dlg( mAttributes, mRDNPrefix, this );
+ if ( dlg.exec() ) {
+ mAttributes = dlg.attributes();
+ mRDNPrefix = dlg.rdnprefix();
+ }
+}
+
+void ResourceLDAPKIOConfig::editCache()
+{
+ LDAPUrl src;
+ QStringList attr;
+
+ src = cfg->url();
+ src.setScope( mSubTree->isChecked() ? LDAPUrl::Sub : LDAPUrl::One );
+ if (!mAttributes.empty()) {
+ QMap<QString,QString>::Iterator it;
+ QStringList attr;
+ for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) {
+ if ( !it.data().isEmpty() && it.key() != "objectClass" )
+ attr.append( it.data() );
+ }
+ src.setAttributes( attr );
+ }
+ src.setExtension( "x-dir", "base" );
+ OfflineDialog dlg( mAutoCache, mCachePolicy, src, mCacheDst, this );
+ if ( dlg.exec() ) {
+ mCachePolicy = dlg.cachePolicy();
+ mAutoCache = dlg.autoCache();
+ }
+
+}
+
+AttributesDialog::AttributesDialog( const QMap<QString, QString> &attributes,
+ int rdnprefix,
+ QWidget *parent, const char *name )
+ : KDialogBase( Plain, i18n( "Attributes Configuration" ), Ok | Cancel,
+ Ok, parent, name, true, true )
+{
+ mNameDict.setAutoDelete( true );
+ mNameDict.insert( "objectClass", new QString( i18n( "Object classes" ) ) );
+ mNameDict.insert( "commonName", new QString( i18n( "Common name" ) ) );
+ mNameDict.insert( "formattedName", new QString( i18n( "Formatted name" ) ) );
+ mNameDict.insert( "familyName", new QString( i18n( "Family name" ) ) );
+ mNameDict.insert( "givenName", new QString( i18n( "Given name" ) ) );
+ mNameDict.insert( "organization", new QString( i18n( "Organization" ) ) );
+ mNameDict.insert( "title", new QString( i18n( "Title" ) ) );
+ mNameDict.insert( "street", new QString( i18n( "Street" ) ) );
+ mNameDict.insert( "state", new QString( i18n( "State" ) ) );
+ mNameDict.insert( "city", new QString( i18n( "City" ) ) );
+ mNameDict.insert( "postalcode", new QString( i18n( "Postal code" ) ) );
+ mNameDict.insert( "mail", new QString( i18n( "Email" ) ) );
+ mNameDict.insert( "mailAlias", new QString( i18n( "Email alias" ) ) );
+ mNameDict.insert( "phoneNumber", new QString( i18n( "Telephone number" ) ) );
+ mNameDict.insert( "telephoneNumber", new QString( i18n( "Work telephone number" ) ) );
+ mNameDict.insert( "facsimileTelephoneNumber", new QString( i18n( "Fax number" ) ) );
+ mNameDict.insert( "mobile", new QString( i18n( "Cell phone number" ) ) );
+ mNameDict.insert( "pager", new QString( i18n( "Pager" ) ) );
+ mNameDict.insert( "description", new QString( i18n( "Note" ) ) );
+ mNameDict.insert( "uid", new QString( i18n( "UID" ) ) );
+ mNameDict.insert( "jpegPhoto", new QString( i18n( "Photo" ) ) );
+
+ // default map
+ mDefaultMap.insert( "objectClass", "inetOrgPerson" );
+ mDefaultMap.insert( "commonName", "cn" );
+ mDefaultMap.insert( "formattedName", "displayName" );
+ mDefaultMap.insert( "familyName", "sn" );
+ mDefaultMap.insert( "givenName", "givenName" );
+ mDefaultMap.insert( "title", "title" );
+ mDefaultMap.insert( "street", "street" );
+ mDefaultMap.insert( "state", "st" );
+ mDefaultMap.insert( "city", "l" );
+ mDefaultMap.insert( "organization", "o" );
+ mDefaultMap.insert( "postalcode", "postalCode" );
+ mDefaultMap.insert( "mail", "mail" );
+ mDefaultMap.insert( "mailAlias", "" );
+ mDefaultMap.insert( "phoneNumber", "homePhone" );
+ mDefaultMap.insert( "telephoneNumber", "telephoneNumber" );
+ mDefaultMap.insert( "facsimileTelephoneNumber", "facsimileTelephoneNumber" );
+ mDefaultMap.insert( "mobile", "mobile" );
+ mDefaultMap.insert( "pager", "pager" );
+ mDefaultMap.insert( "description", "description" );
+ mDefaultMap.insert( "uid", "uid" );
+ mDefaultMap.insert( "jpegPhoto", "jpegPhoto" );
+
+ // overwrite the default values here
+ QMap<QString, QString> kolabMap, netscapeMap, evolutionMap, outlookMap;
+
+ // kolab
+ kolabMap.insert( "formattedName", "display-name" );
+ kolabMap.insert( "mailAlias", "mailalias" );
+
+ // evolution
+ evolutionMap.insert( "formattedName", "fileAs" );
+
+ mMapList.append( attributes );
+ mMapList.append( kolabMap );
+ mMapList.append( netscapeMap );
+ mMapList.append( evolutionMap );
+ mMapList.append( outlookMap );
+
+ QFrame *page = plainPage();
+ QGridLayout *layout = new QGridLayout( page, 4, ( attributes.count() + 4 ) >> 1,
+ 0, spacingHint() );
+
+ QLabel *label = new QLabel( i18n( "Template:" ), page );
+ layout->addWidget( label, 0, 0 );
+ mMapCombo = new KComboBox( page );
+ layout->addWidget( mMapCombo, 0, 1 );
+
+ mMapCombo->insertItem( i18n( "User Defined" ) );
+ mMapCombo->insertItem( i18n( "Kolab" ) );
+ mMapCombo->insertItem( i18n( "Netscape" ) );
+ mMapCombo->insertItem( i18n( "Evolution" ) );
+ mMapCombo->insertItem( i18n( "Outlook" ) );
+ connect( mMapCombo, SIGNAL( activated( int ) ), SLOT( mapChanged( int ) ) );
+
+ label = new QLabel( i18n( "RDN prefix attribute:" ), page );
+ layout->addWidget( label, 1, 0 );
+ mRDNCombo = new KComboBox( page );
+ layout->addWidget( mRDNCombo, 1, 1 );
+ mRDNCombo->insertItem( i18n( "commonName" ) );
+ mRDNCombo->insertItem( i18n( "UID" ) );
+ mRDNCombo->setCurrentItem( rdnprefix );
+
+ QMap<QString, QString>::ConstIterator it;
+ int i, j = 0;
+ for ( i = 2, it = attributes.begin(); it != attributes.end(); ++it, ++i ) {
+ if ( mNameDict[ it.key() ] == 0 ) {
+ i--;
+ continue;
+ }
+ if ( (uint)(i - 2) == ( mNameDict.count() >> 1 ) ) {
+ i = 0;
+ j = 2;
+ }
+ kdDebug(7125) << "itkey: " << it.key() << " i: " << i << endl;
+ label = new QLabel( *mNameDict[ it.key() ] + ":", page );
+ KLineEdit *lineedit = new KLineEdit( page );
+ mLineEditDict.insert( it.key(), lineedit );
+ lineedit->setText( it.data() );
+ label->setBuddy( lineedit );
+ layout->addWidget( label, i, j );
+ layout->addWidget( lineedit, i, j+1 );
+ }
+
+ for ( i = 1; i < mMapCombo->count(); i++ ) {
+ QDictIterator<KLineEdit> it2( mLineEditDict );
+ for ( ; it2.current(); ++it2 ) {
+ if ( mMapList[ i ].contains( it2.currentKey() ) ) {
+ if ( mMapList[ i ][ it2.currentKey() ] != it2.current()->text() ) break;
+ } else {
+ if ( mDefaultMap[ it2.currentKey() ] != it2.current()->text() ) break;
+ }
+ }
+ if ( !it2.current() ) {
+ mMapCombo->setCurrentItem( i );
+ break;
+ }
+ }
+
+ KAcceleratorManager::manage( this );
+}
+
+AttributesDialog::~AttributesDialog()
+{
+}
+
+QMap<QString, QString> AttributesDialog::attributes() const
+{
+ QMap<QString, QString> map;
+
+ QDictIterator<KLineEdit> it( mLineEditDict );
+ for ( ; it.current(); ++it )
+ map.insert( it.currentKey(), it.current()->text() );
+
+ return map;
+}
+
+int AttributesDialog::rdnprefix() const
+{
+ return mRDNCombo->currentItem();
+}
+
+void AttributesDialog::mapChanged( int pos )
+{
+
+ // apply first the default and than the spezific changes
+ QMap<QString, QString>::Iterator it;
+ for ( it = mDefaultMap.begin(); it != mDefaultMap.end(); ++it )
+ mLineEditDict[ it.key() ]->setText( it.data() );
+
+ for ( it = mMapList[ pos ].begin(); it != mMapList[ pos ].end(); ++it ) {
+ if ( !it.data().isEmpty() ) {
+ KLineEdit *le = mLineEditDict[ it.key() ];
+ if ( le ) le->setText( it.data() );
+ }
+ }
+}
+
+OfflineDialog::OfflineDialog( bool autoCache, int cachePolicy, const KURL &src,
+ const QString &dst, QWidget *parent, const char *name )
+ : KDialogBase( Plain, i18n( "Offline Configuration" ), Ok | Cancel,
+ Ok, parent, name, true, true )
+{
+ QFrame *page = plainPage();
+ QVBoxLayout *layout = new QVBoxLayout( page );
+ layout->setAutoAdd( true );
+
+ mSrc = src; mDst = dst;
+ mCacheGroup = new QButtonGroup( 1, Qt::Horizontal,
+ i18n("Offline Cache Policy"), page );
+
+ QRadioButton *bt;
+ new QRadioButton( i18n("Do not use offline cache"), mCacheGroup );
+ bt = new QRadioButton( i18n("Use local copy if no connection"), mCacheGroup );
+ new QRadioButton( i18n("Always use local copy"), mCacheGroup );
+ mCacheGroup->setButton( cachePolicy );
+
+ mAutoCache = new QCheckBox( i18n("Refresh offline cache automatically"),
+ page );
+ mAutoCache->setChecked( autoCache );
+ mAutoCache->setEnabled( bt->isChecked() );
+
+ connect( bt, SIGNAL(toggled(bool)), mAutoCache, SLOT(setEnabled(bool)) );
+
+ QPushButton *lcache = new QPushButton( i18n("Load into Cache"), page );
+ connect( lcache, SIGNAL( clicked() ), SLOT( loadCache() ) );
+}
+
+OfflineDialog::~OfflineDialog()
+{
+}
+
+bool OfflineDialog::autoCache() const
+{
+ return mAutoCache->isChecked();
+}
+
+int OfflineDialog::cachePolicy() const
+{
+ return mCacheGroup->selectedId();
+}
+
+void OfflineDialog::loadCache()
+{
+ if ( KIO::NetAccess::download( mSrc, mDst, this ) ) {
+ KMessageBox::information( this,
+ i18n("Successfully downloaded directory server contents!") );
+ } else {
+ KMessageBox::error( this,
+ i18n("An error occurred downloading directory server contents into file %1.").arg(mDst) );
+ }
+}
diff --git a/kabc/plugins/ldapkio/resourceldapkioconfig.h b/kabc/plugins/ldapkio/resourceldapkioconfig.h
new file mode 100644
index 000000000..c261cbd06
--- /dev/null
+++ b/kabc/plugins/ldapkio/resourceldapkioconfig.h
@@ -0,0 +1,118 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 - 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCELDAPCONFIG_H
+#define RESOURCELDAPCONFIG_H
+
+#include <qmap.h>
+#include <qradiobutton.h>
+#include <qcombobox.h>
+#include <qdict.h>
+
+#include <kdialogbase.h>
+#include <kresources/configwidget.h>
+#include <kabc/ldif.h>
+#include <kabc/ldapconfigwidget.h>
+
+
+class QCheckBox;
+class QPushButton;
+class QSpinBox;
+class QString;
+
+class KComboBox;
+class KLineEdit;
+
+namespace KABC {
+
+class KABC_EXPORT ResourceLDAPKIOConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+ public:
+ ResourceLDAPKIOConfig( QWidget* parent = 0, const char* name = 0 );
+
+ public slots:
+ void loadSettings( KRES::Resource* );
+ void saveSettings( KRES::Resource* );
+
+ private slots:
+ void editAttributes();
+ void editCache();
+ private:
+ QPushButton *mEditButton, *mCacheButton;
+ LdapConfigWidget *cfg;
+ QCheckBox *mSubTree;
+ QMap<QString, QString> mAttributes;
+ int mRDNPrefix, mCachePolicy;
+ bool mAutoCache;
+ QString mCacheDst;
+};
+
+class AttributesDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ AttributesDialog( const QMap<QString, QString> &attributes, int rdnprefix,
+ QWidget *parent, const char *name = 0 );
+ ~AttributesDialog();
+
+ QMap<QString, QString> attributes() const;
+ int rdnprefix() const;
+
+ private slots:
+ void mapChanged( int pos );
+
+ private:
+ enum { UserMap, KolabMap, NetscapeMap, EvolutionMap, OutlookMap };
+
+ KComboBox *mMapCombo, *mRDNCombo;
+ QValueList< QMap<QString, QString> > mMapList;
+ QMap<QString, QString> mDefaultMap;
+ QDict<KLineEdit> mLineEditDict;
+ QDict<QString> mNameDict;
+};
+
+class OfflineDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ OfflineDialog( bool autoCache, int cachePolicy, const KURL &src,
+ const QString &dst, QWidget *parent, const char *name = 0 );
+ ~OfflineDialog();
+
+ int cachePolicy() const;
+ bool autoCache() const;
+
+ private slots:
+ void loadCache();
+
+ private:
+ KURL mSrc;
+ QString mDst;
+ QButtonGroup *mCacheGroup;
+ QCheckBox *mAutoCache;
+};
+
+}
+
+#endif
diff --git a/kabc/plugins/ldapkio/resourceldapkioplugin.cpp b/kabc/plugins/ldapkio/resourceldapkioplugin.cpp
new file mode 100644
index 000000000..98b21061e
--- /dev/null
+++ b/kabc/plugins/ldapkio/resourceldapkioplugin.cpp
@@ -0,0 +1,36 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "resourceldapkio.h"
+#include "resourceldapkioconfig.h"
+
+#include <kglobal.h>
+#include <klocale.h>
+
+using namespace KABC;
+
+extern "C"
+{
+ KDE_EXPORT void *init_kabc_ldapkio()
+ {
+ KGlobal::locale()->insertCatalogue("kabc_ldapkio");
+ return new KRES::PluginFactory<ResourceLDAPKIO, ResourceLDAPKIOConfig>();
+ }
+}
diff --git a/kabc/plugins/net/Makefile.am b/kabc/plugins/net/Makefile.am
new file mode 100644
index 000000000..8e7305303
--- /dev/null
+++ b/kabc/plugins/net/Makefile.am
@@ -0,0 +1,28 @@
+INCLUDES = -I$(top_srcdir)/kabc -I$(top_builddir)/kabc $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = resourcenetconfig.h
+
+lib_LTLIBRARIES = libkabc_net.la
+libkabc_net_la_SOURCES = resourcenet.cpp resourcenetconfig.cpp
+libkabc_net_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined
+libkabc_net_la_LIBADD = $(top_builddir)/kabc/libkabc.la $(LIB_KIO)
+libkabc_net_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h
+
+kde_module_LTLIBRARIES = kabc_net.la
+kabc_net_la_SOURCES = resourcenetplugin.cpp
+kabc_net_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kabc_net_la_LIBADD = libkabc_net.la
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kabc_net.pot
+
+kabcincludedir = $(includedir)/kabc
+kabcinclude_HEADERS = resourcenet.h
+
+servicedir = $(kde_servicesdir)/kresources/kabc
+service_DATA = net.desktop
+
+resourcenetplugin.lo: ../../addressee.h
diff --git a/kabc/plugins/net/net.desktop b/kabc/plugins/net/net.desktop
new file mode 100644
index 000000000..eadc38ba8
--- /dev/null
+++ b/kabc/plugins/net/net.desktop
@@ -0,0 +1,90 @@
+[Desktop Entry]
+Name=Network
+Name[af]=Netwerk
+Name[ar]=الشبكة
+Name[az]=Şəbəkə
+Name[be]=Сетка
+Name[bn]=নেটওয়ার্ক
+Name[br]=Rouedad
+Name[bs]=Mreža
+Name[ca]=Xarxa
+Name[cs]=Síť
+Name[csb]=Sec
+Name[cy]=Rhydwaith
+Name[da]=Netværk
+Name[de]=Netzwerk
+Name[el]=Δίκτυο
+Name[eo]=Reto
+Name[es]=Red
+Name[et]=Võrk
+Name[eu]=Sarea
+Name[fa]=شبکه
+Name[fi]=Verkko
+Name[fr]=Réseau
+Name[fy]=Netwurk
+Name[ga]=Líonra
+Name[gl]=Rede
+Name[he]=רשת
+Name[hi]=नेटवर्क
+Name[hr]=Mreža
+Name[hsb]=Syć
+Name[hu]=Hálózat
+Name[id]=Jaringan
+Name[is]=Net
+Name[it]=Rete
+Name[ja]=ネットワーク
+Name[ka]=ქსელი
+Name[kk]=Желі
+Name[km]=បណ្តាញ
+Name[ko]=네트워크
+Name[ku]=Tor
+Name[lb]=Netzwierk
+Name[lt]=Tinklas
+Name[lv]=Tīkls
+Name[mi]=Hao
+Name[mk]=Мрежа
+Name[mn]=Сүлжээ
+Name[ms]=Jaringan
+Name[nds]=Nettwark
+Name[ne]=सञ्जाल
+Name[nl]=Netwerk
+Name[nn]=Nettverk
+Name[nso]=Kgokagano
+Name[oc]=Resèu
+Name[pa]=ਨੈੱਟਵਰਕ
+Name[pl]=Sieć
+Name[pt]=Rede
+Name[pt_BR]=Rede
+Name[ro]=Reţea
+Name[ru]=Сеть
+Name[rw]=Urusobe
+Name[se]=Fierbmi
+Name[sk]=Sieť
+Name[sl]=Omrežje
+Name[sq]=Rrjeta
+Name[sr]=Мрежа
+Name[sr@Latn]=Mreža
+Name[ss]=Luchungechunge
+Name[sv]=Nätverk
+Name[ta]=பிணையம்
+Name[te]=కలన జాలం
+Name[tg]=Шабака
+Name[th]=ระบบเครือข่าย
+Name[tr]=Ağ
+Name[tt]=Çeltär
+Name[uk]=Мережа
+Name[uz]=Tarmoq
+Name[uz@cyrillic]=Tarмоқ
+Name[ven]=Vhukwamani
+Name[vi]=mạng
+Name[wa]=Rantoele
+Name[xh]=Umsebenzi womnatha
+Name[zh_CN]=网络
+Name[zh_HK]=網絡
+Name[zh_TW]=網路
+Name[zu]=Umsebenzi wokuxhumana okusakazekile
+X-KDE-Library=kabc_net
+Type=Service
+ServiceTypes=KResources/Plugin
+X-KDE-ResourceFamily=contact
+X-KDE-ResourceType=net
diff --git a/kabc/plugins/net/resourcenet.cpp b/kabc/plugins/net/resourcenet.cpp
new file mode 100644
index 000000000..86d2f9bdc
--- /dev/null
+++ b/kabc/plugins/net/resourcenet.cpp
@@ -0,0 +1,390 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qfile.h>
+
+#include <kdebug.h>
+#include <kio/netaccess.h>
+#include <kio/scheduler.h>
+#include <klocale.h>
+#include <ksavefile.h>
+#include <ktempfile.h>
+#include <kurlrequester.h>
+
+#include "addressbook.h"
+#include "formatfactory.h"
+#include "resourcenetconfig.h"
+#include "stdaddressbook.h"
+
+#include "resourcenet.h"
+
+using namespace KABC;
+
+class ResourceNet::ResourceNetPrivate
+{
+ public:
+ KIO::Job *mLoadJob;
+ bool mIsLoading;
+
+ KIO::Job *mSaveJob;
+ bool mIsSaving;
+
+ QString mLastErrorString;
+};
+
+ResourceNet::ResourceNet( const KConfig *config )
+ : Resource( config ), mFormat( 0 ),
+ mTempFile( 0 ),
+ d( new ResourceNetPrivate )
+{
+ if ( config ) {
+ init( KURL( config->readPathEntry( "NetUrl" ) ), config->readEntry( "NetFormat" ) );
+ } else {
+ init( KURL(), "vcard" );
+ }
+}
+
+ResourceNet::ResourceNet( const KURL &url, const QString &format )
+ : Resource( 0 ), mFormat( 0 ),
+ mTempFile( 0 ),
+ d( new ResourceNetPrivate )
+{
+ init( url, format );
+}
+
+void ResourceNet::init( const KURL &url, const QString &format )
+{
+ d->mLoadJob = 0;
+ d->mIsLoading = false;
+ d->mSaveJob = 0;
+ d->mIsSaving = false;
+
+ mFormatName = format;
+
+ FormatFactory *factory = FormatFactory::self();
+ mFormat = factory->format( mFormatName );
+ if ( !mFormat ) {
+ mFormatName = "vcard";
+ mFormat = factory->format( mFormatName );
+ }
+
+ setUrl( url );
+}
+
+ResourceNet::~ResourceNet()
+{
+ if ( d->mIsLoading )
+ d->mLoadJob->kill();
+ if ( d->mIsSaving )
+ d->mSaveJob->kill();
+
+ delete d;
+ d = 0;
+
+ delete mFormat;
+ mFormat = 0;
+
+ deleteLocalTempFile();
+}
+
+void ResourceNet::writeConfig( KConfig *config )
+{
+ Resource::writeConfig( config );
+
+ config->writePathEntry( "NetUrl", mUrl.url() );
+ config->writeEntry( "NetFormat", mFormatName );
+}
+
+Ticket *ResourceNet::requestSaveTicket()
+{
+ kdDebug(5700) << "ResourceNet::requestSaveTicket()" << endl;
+
+ return createTicket( this );
+}
+
+void ResourceNet::releaseSaveTicket( Ticket *ticket )
+{
+ delete ticket;
+}
+
+bool ResourceNet::doOpen()
+{
+ return true;
+}
+
+void ResourceNet::doClose()
+{
+}
+
+bool ResourceNet::load()
+{
+ QString tempFile;
+
+ if ( !KIO::NetAccess::download( mUrl, tempFile, 0 ) ) {
+ addressBook()->error( i18n( "Unable to download file '%1'." ).arg( mUrl.prettyURL() ) );
+ return false;
+ }
+
+ QFile file( tempFile );
+ if ( !file.open( IO_ReadOnly ) ) {
+ addressBook()->error( i18n( "Unable to open file '%1'." ).arg( tempFile ) );
+ KIO::NetAccess::removeTempFile( tempFile );
+ return false;
+ }
+
+ bool result = clearAndLoad( &file );
+ if ( !result )
+ addressBook()->error( i18n( "Problems during parsing file '%1'." ).arg( tempFile ) );
+
+ KIO::NetAccess::removeTempFile( tempFile );
+
+ return result;
+}
+
+bool ResourceNet::clearAndLoad( QFile *file )
+{
+ clear();
+ return mFormat->loadAll( addressBook(), this, file );
+}
+
+bool ResourceNet::asyncLoad()
+{
+ if ( d->mIsLoading ) {
+ abortAsyncLoading();
+ }
+
+ if (d->mIsSaving) {
+ kdWarning(5700) << "Aborted asyncLoad() because we're still asyncSave()ing!" << endl;
+ return false;
+ }
+
+ bool ok = createLocalTempFile();
+ if ( ok )
+ ok = mTempFile->close();
+
+ if ( !ok ) {
+ emit loadingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile->name() ) );
+ deleteLocalTempFile();
+ return false;
+ }
+
+ KURL dest;
+ dest.setPath( mTempFile->name() );
+
+ KIO::Scheduler::checkSlaveOnHold( true );
+ d->mLoadJob = KIO::file_copy( mUrl, dest, -1, true, false, false );
+ d->mIsLoading = true;
+ connect( d->mLoadJob, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( downloadFinished( KIO::Job* ) ) );
+
+ return true;
+}
+
+void ResourceNet::abortAsyncLoading()
+{
+ kdDebug(5700) << "ResourceNet::abortAsyncLoading()" << endl;
+
+ if ( d->mLoadJob ) {
+ d->mLoadJob->kill(); // result not emitted
+ d->mLoadJob = 0;
+ }
+
+ deleteLocalTempFile();
+ d->mIsLoading = false;
+}
+
+void ResourceNet::abortAsyncSaving()
+{
+ kdDebug(5700) << "ResourceNet::abortAsyncSaving()" << endl;
+
+ if ( d->mSaveJob ) {
+ d->mSaveJob->kill(); // result not emitted
+ d->mSaveJob = 0;
+ }
+
+ deleteLocalTempFile();
+ d->mIsSaving = false;
+}
+
+bool ResourceNet::save( Ticket* )
+{
+ kdDebug(5700) << "ResourceNet::save()" << endl;
+
+ if (d->mIsSaving) {
+ abortAsyncSaving();
+ }
+
+ KTempFile tempFile;
+ tempFile.setAutoDelete( true );
+ bool ok = false;
+
+ if ( tempFile.status() == 0 && tempFile.file() ) {
+ saveToFile( tempFile.file() );
+ ok = tempFile.close();
+ }
+
+ if ( !ok ) {
+ addressBook()->error( i18n( "Unable to save file '%1'." ).arg( tempFile.name() ) );
+ return false;
+ }
+
+ ok = KIO::NetAccess::upload( tempFile.name(), mUrl, 0 );
+ if ( !ok )
+ addressBook()->error( i18n( "Unable to upload to '%1'." ).arg( mUrl.prettyURL() ) );
+
+ return ok;
+}
+
+bool ResourceNet::asyncSave( Ticket* )
+{
+ kdDebug(5700) << "ResourceNet::asyncSave()" << endl;
+
+ if (d->mIsSaving) {
+ abortAsyncSaving();
+ }
+
+ if (d->mIsLoading) {
+ kdWarning(5700) << "Aborted asyncSave() because we're still asyncLoad()ing!" << endl;
+ return false;
+ }
+
+ bool ok = createLocalTempFile();
+ if ( ok ) {
+ saveToFile( mTempFile->file() );
+ ok = mTempFile->close();
+ }
+
+ if ( !ok ) {
+ emit savingError( this, i18n( "Unable to save file '%1'." ).arg( mTempFile->name() ) );
+ deleteLocalTempFile();
+ return false;
+ }
+
+ KURL src;
+ src.setPath( mTempFile->name() );
+
+ KIO::Scheduler::checkSlaveOnHold( true );
+ d->mIsSaving = true;
+ d->mSaveJob = KIO::file_copy( src, mUrl, -1, true, false, false );
+ connect( d->mSaveJob, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( uploadFinished( KIO::Job* ) ) );
+
+ return true;
+}
+
+bool ResourceNet::createLocalTempFile()
+{
+ deleteStaleTempFile();
+ mTempFile = new KTempFile();
+ mTempFile->setAutoDelete( true );
+ return mTempFile->status() == 0;
+}
+
+void ResourceNet::deleteStaleTempFile()
+{
+ if ( hasTempFile() ) {
+ kdDebug(5700) << "stale temp file detected " << mTempFile->name() << endl;
+ deleteLocalTempFile();
+ }
+}
+
+void ResourceNet::deleteLocalTempFile()
+{
+ delete mTempFile;
+ mTempFile = 0;
+}
+
+void ResourceNet::saveToFile( QFile *file )
+{
+ mFormat->saveAll( addressBook(), this, file );
+}
+
+void ResourceNet::setUrl( const KURL &url )
+{
+ mUrl = url;
+}
+
+KURL ResourceNet::url() const
+{
+ return mUrl;
+}
+
+void ResourceNet::setFormat( const QString &name )
+{
+ mFormatName = name;
+ if ( mFormat )
+ delete mFormat;
+
+ FormatFactory *factory = FormatFactory::self();
+ mFormat = factory->format( mFormatName );
+}
+
+QString ResourceNet::format() const
+{
+ return mFormatName;
+}
+
+void ResourceNet::downloadFinished( KIO::Job* )
+{
+ kdDebug(5700) << "ResourceNet::downloadFinished()" << endl;
+
+ d->mIsLoading = false;
+
+ if ( !hasTempFile() || mTempFile->status() != 0 ) {
+ d->mLastErrorString = i18n( "Download failed in some way!" );
+ QTimer::singleShot( 0, this, SLOT( signalError() ) );
+ return;
+ }
+
+ QFile file( mTempFile->name() );
+ if ( file.open( IO_ReadOnly ) ) {
+ if ( clearAndLoad( &file ) )
+ emit loadingFinished( this );
+ else
+ emit loadingError( this, i18n( "Problems during parsing file '%1'." ).arg( mTempFile->name() ) );
+ }
+ else {
+ emit loadingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile->name() ) );
+ }
+
+ deleteLocalTempFile();
+}
+
+void ResourceNet::uploadFinished( KIO::Job *job )
+{
+ kdDebug(5700) << "ResourceFile::uploadFinished()" << endl;
+
+ d->mIsSaving = false;
+
+ if ( job->error() )
+ emit savingError( this, job->errorString() );
+ else
+ emit savingFinished( this );
+
+ deleteLocalTempFile();
+}
+
+void ResourceNet::signalError()
+{
+ emit loadingError( this, d->mLastErrorString );
+ d->mLastErrorString.truncate( 0 );
+}
+
+#include "resourcenet.moc"
diff --git a/kabc/plugins/net/resourcenet.h b/kabc/plugins/net/resourcenet.h
new file mode 100644
index 000000000..b315be6df
--- /dev/null
+++ b/kabc/plugins/net/resourcenet.h
@@ -0,0 +1,117 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_RESOURCENET_H
+#define KABC_RESOURCENET_H
+
+#include <kconfig.h>
+
+#include <sys/types.h>
+
+#include <kabc/resource.h>
+
+class QFile;
+class QTimer;
+class KTempFile;
+
+namespace KIO {
+class Job;
+}
+
+namespace KABC {
+
+class FormatPlugin;
+
+/**
+ @internal
+*/
+class KABC_EXPORT ResourceNet : public Resource
+{
+ Q_OBJECT
+
+ public:
+ ResourceNet( const KConfig* );
+ ResourceNet( const KURL &url, const QString &format );
+ ~ResourceNet();
+
+ virtual void writeConfig( KConfig* );
+
+ virtual bool doOpen();
+ virtual void doClose();
+
+ virtual Ticket *requestSaveTicket();
+ virtual void releaseSaveTicket( Ticket* );
+
+ virtual bool load();
+ virtual bool asyncLoad();
+ virtual bool save( Ticket* ticket );
+ virtual bool asyncSave( Ticket* ticket );
+
+ /**
+ Set url of directory to be used for saving.
+ */
+ void setUrl( const KURL & );
+
+ /**
+ Return url of directory used for loading and saving the address book.
+ */
+ KURL url() const;
+
+ /**
+ Sets a new format by name.
+ */
+ void setFormat( const QString &name );
+
+ /**
+ Returns the format name.
+ */
+ QString format() const;
+
+ protected:
+ void init( const KURL &url, const QString &format );
+
+ private slots:
+ void downloadFinished( KIO::Job* );
+ void uploadFinished( KIO::Job* );
+ void signalError();
+
+ private:
+ bool clearAndLoad( QFile *file );
+ void saveToFile( QFile *file );
+ bool hasTempFile() const { return mTempFile != 0; }
+ void abortAsyncLoading();
+ void abortAsyncSaving();
+ bool createLocalTempFile();
+ void deleteLocalTempFile();
+ void deleteStaleTempFile();
+
+ FormatPlugin *mFormat;
+ QString mFormatName;
+
+ KURL mUrl;
+ KTempFile *mTempFile;
+
+ class ResourceNetPrivate;
+ ResourceNetPrivate *d;
+};
+
+}
+
+#endif
diff --git a/kabc/plugins/net/resourcenetconfig.cpp b/kabc/plugins/net/resourcenetconfig.cpp
new file mode 100644
index 000000000..ef5bfdcb9
--- /dev/null
+++ b/kabc/plugins/net/resourcenetconfig.cpp
@@ -0,0 +1,102 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdialog.h>
+
+#include "formatfactory.h"
+#include "resourcenet.h"
+#include "stdaddressbook.h"
+
+#include "resourcenetconfig.h"
+
+using namespace KABC;
+
+ResourceNetConfig::ResourceNetConfig( QWidget* parent, const char* name )
+ : ConfigWidget( parent, name ), mInEditMode( false )
+{
+ QGridLayout *mainLayout = new QGridLayout( this, 2, 2, 0,
+ KDialog::spacingHint() );
+
+ QLabel *label = new QLabel( i18n( "Format:" ), this );
+ mFormatBox = new KComboBox( this );
+
+ mainLayout->addWidget( label, 0, 0 );
+ mainLayout->addWidget( mFormatBox, 0, 1 );
+
+ label = new QLabel( i18n( "Location:" ), this );
+ mUrlEdit = new KURLRequester( this );
+ mUrlEdit->setMode( KFile::File );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mUrlEdit, 1, 1 );
+
+ FormatFactory *factory = FormatFactory::self();
+ QStringList formats = factory->formats();
+ QStringList::Iterator it;
+ for ( it = formats.begin(); it != formats.end(); ++it ) {
+ FormatInfo *info = factory->info( *it );
+ if ( info ) {
+ mFormatTypes << (*it);
+ mFormatBox->insertItem( info->nameLabel );
+ }
+ }
+}
+
+void ResourceNetConfig::setEditMode( bool value )
+{
+ mFormatBox->setEnabled( !value );
+ mInEditMode = value;
+}
+
+void ResourceNetConfig::loadSettings( KRES::Resource *res )
+{
+ ResourceNet *resource = dynamic_cast<ResourceNet*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceNetConfig::loadSettings(): cast failed" << endl;
+ return;
+ }
+
+ mFormatBox->setCurrentItem( mFormatTypes.findIndex( resource->format() ) );
+
+ mUrlEdit->setURL( resource->url().url() );
+}
+
+void ResourceNetConfig::saveSettings( KRES::Resource *res )
+{
+ ResourceNet *resource = dynamic_cast<ResourceNet*>( res );
+
+ if ( !resource ) {
+ kdDebug(5700) << "ResourceNetConfig::saveSettings(): cast failed" << endl;
+ return;
+ }
+
+ if ( !mInEditMode )
+ resource->setFormat( mFormatTypes[ mFormatBox->currentItem() ] );
+
+ resource->setUrl( KURL( mUrlEdit->url() ) );
+}
+
+#include "resourcenetconfig.moc"
diff --git a/kabc/plugins/net/resourcenetconfig.h b/kabc/plugins/net/resourcenetconfig.h
new file mode 100644
index 000000000..e35c46c01
--- /dev/null
+++ b/kabc/plugins/net/resourcenetconfig.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCENETCONFIG_H
+#define RESOURCENETCONFIG_H
+
+#include <kcombobox.h>
+#include <kurlrequester.h>
+
+#include <kresources/configwidget.h>
+
+namespace KABC {
+
+class KABC_EXPORT ResourceNetConfig : public KRES::ConfigWidget
+{
+ Q_OBJECT
+
+ public:
+ ResourceNetConfig( QWidget* parent = 0, const char* name = 0 );
+
+ void setEditMode( bool value );
+
+ public slots:
+ void loadSettings( KRES::Resource *resource );
+ void saveSettings( KRES::Resource *resource );
+
+ private:
+ KComboBox* mFormatBox;
+ KURLRequester* mUrlEdit;
+
+ QStringList mFormatTypes;
+ bool mInEditMode;
+};
+
+}
+#endif
diff --git a/kabc/plugins/net/resourcenetplugin.cpp b/kabc/plugins/net/resourcenetplugin.cpp
new file mode 100644
index 000000000..189bab051
--- /dev/null
+++ b/kabc/plugins/net/resourcenetplugin.cpp
@@ -0,0 +1,32 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "resourcenet.h"
+#include "resourcenetconfig.h"
+
+using namespace KABC;
+
+extern "C"
+{
+ KDE_EXPORT void *init_kabc_net()
+ {
+ return new KRES::PluginFactory<ResourceNet, ResourceNetConfig>();
+ }
+}
diff --git a/kabc/plugins/sql/Makefile.am b/kabc/plugins/sql/Makefile.am
new file mode 100644
index 000000000..93c86f061
--- /dev/null
+++ b/kabc/plugins/sql/Makefile.am
@@ -0,0 +1,20 @@
+INCLUDES = -I$(top_srcdir)/kabc -I$(top_builddir)/kabc $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = resourcesql.h resourcesqlconfig.h
+
+kde_module_LTLIBRARIES = kabc_sql.la
+
+kabc_sql_la_SOURCES = resourcesql.cpp resourcesqlconfig.cpp
+
+kabc_sql_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kabc_sql_la_LIBADD = ../../libkabc.la ../../../kdeui/libkdeui.la
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kabc_sql.pot
+
+linkdir = $(kde_datadir)/kresources/contact
+link_DATA = sql.desktop
+EXTRA_DIST = $(link_DATA)
diff --git a/kabc/plugins/sql/resourcesql.cpp b/kabc/plugins/sql/resourcesql.cpp
new file mode 100644
index 000000000..2e6eb6902
--- /dev/null
+++ b/kabc/plugins/sql/resourcesql.cpp
@@ -0,0 +1,338 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qsqldatabase.h>
+#include <qsqlcursor.h>
+
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klineedit.h>
+#include <klocale.h>
+
+#include "resourcesql.h"
+#include "resourcesqlconfig.h"
+
+using namespace KABC;
+
+extern "C"
+{
+ KDE_EXPORT void *init_kabc_sql()
+ {
+ return new KRES::PluginFactory<ResourceSql,ResourceSqlConfig>();
+ }
+}
+
+ResourceSql::ResourceSql( AddressBook *ab, const KConfig *config )
+ : Resource( ab ), mDb( 0 )
+{
+ QString user, password, db, host;
+
+ user = config->readEntry( "SqlUser" );
+ password = cryptStr( config->readEntry( "SqlPassword " ) );
+ db = config->readEntry( "SqlName" );
+ host = config->readEntry( "SqlHost" );
+
+ init( user, password, db, host );
+}
+
+ResourceSql::ResourceSql( AddressBook *ab, const QString &user,
+ const QString &password, const QString &db, const QString &host )
+ : Resource( ab ), mDb( 0 )
+{
+ init( user, password, db, host );
+}
+
+void ResourceSql::init( const QString &user, const QString &password,
+ const QString &db, const QString &host )
+{
+ mUser = user;
+ mPassword = password;
+ mDbName = db;
+ mHost = host;
+}
+
+Ticket *ResourceSql::requestSaveTicket()
+{
+ if ( !addressBook() ) {
+ kdDebug(5700) << "no addressbook" << endl;
+ return 0;
+ }
+
+ return createTicket( this );
+}
+
+bool ResourceSql::open()
+{
+ QStringList drivers = QSqlDatabase::drivers();
+ for ( QStringList::Iterator it = drivers.begin(); it != drivers.end(); ++it ) {
+ kdDebug(5700) << "Driver: " << (*it) << endl;
+ }
+
+ mDb = QSqlDatabase::addDatabase( "QMYSQL3" );
+
+ if ( !mDb ) {
+ kdDebug(5700) << "Error. Unable to connect to database." << endl;
+ return false;
+ }
+
+ mDb->setDatabaseName( mDbName );
+ mDb->setUserName( mUser );
+ mDb->setPassword( mPassword );
+ mDb->setHostName( mHost );
+
+ if ( !mDb->open() ) {
+ kdDebug(5700) << "Error. Unable to open database '" << mDbName << "'." << endl;
+ return false;
+ }
+
+ return true;
+}
+
+void ResourceSql::close()
+{
+ mDb->close();
+}
+
+bool ResourceSql::load()
+{
+ QSqlQuery query( "select addressId, name, familyName, givenName, "
+ "additionalName, prefix, suffix, nickname, birthday, "
+ "mailer, timezone, geo_latitude, geo_longitude, title, "
+ "role, organization, note, productId, revision, "
+ "sortString, url from kaddressbook_main_" + mUser );
+
+ while ( query.next() ) {
+ QString addrId = query.value(0).toString();
+
+ Addressee addr;
+ addr.setResource( this );
+ addr.setUid( addrId );
+ addr.setName( query.value(1).toString() );
+ addr.setFamilyName( query.value(2).toString() );
+ addr.setGivenName( query.value(3).toString() );
+ addr.setAdditionalName( query.value(4).toString() );
+ addr.setPrefix( query.value(5).toString() );
+ addr.setSuffix( query.value(6).toString() );
+ addr.setNickName( query.value(7).toString() );
+ addr.setBirthday( query.value(8).toDateTime() );
+ addr.setMailer( query.value(9).toString() );
+ addr.setTimeZone( TimeZone( query.value(10).toInt() ) );
+ addr.setGeo( Geo( query.value(11).toDouble(), query.value(12).toDouble() ) );
+ addr.setTitle( query.value(13).toString() );
+ addr.setRole( query.value(14).toString() );
+ addr.setOrganization( query.value(15).toString() );
+ addr.setNote( query.value(16).toString() );
+ addr.setProductId( query.value(17).toString() );
+ addr.setRevision( query.value(18).toDateTime() );
+ addr.setSortString( query.value(19).toString() );
+ addr.setUrl( query.value(20).toString() );
+
+ // emails
+ {
+ QSqlQuery emailsQuery( "select email, preferred from kaddressbook_emails "
+ "where addressId = '" + addrId + "'" );
+ while ( emailsQuery.next() )
+ addr.insertEmail( emailsQuery.value( 0 ).toString(),
+ emailsQuery.value( 1 ).toInt() );
+ }
+
+ // phones
+ {
+ QSqlQuery phonesQuery( "select number, type from kaddressbook_phones "
+ "where addressId = '" + addrId + "'" );
+ while ( phonesQuery.next() )
+ addr.insertPhoneNumber( PhoneNumber( phonesQuery.value( 0 ).toString(),
+ phonesQuery.value( 1 ).toInt() ) );
+ }
+
+ // addresses
+ {
+ QSqlQuery addressesQuery( "select postOfficeBox, extended, street, "
+ "locality, region, postalCode, country, label, type "
+ "from kaddressbook_addresses where addressId = '" + addrId + "'" );
+ while ( addressesQuery.next() ) {
+ Address a;
+ a.setPostOfficeBox( addressesQuery.value(0).toString() );
+ a.setExtended( addressesQuery.value(1).toString() );
+ a.setStreet( addressesQuery.value(2).toString() );
+ a.setLocality( addressesQuery.value(3).toString() );
+ a.setRegion( addressesQuery.value(4).toString() );
+ a.setPostalCode( addressesQuery.value(5).toString() );
+ a.setCountry( addressesQuery.value(6).toString() );
+ a.setLabel( addressesQuery.value(7).toString() );
+ a.setType( addressesQuery.value(8).toInt() );
+
+ addr.insertAddress( a );
+ }
+ }
+
+ // categories
+ {
+ QSqlQuery categoriesQuery( "select category from kaddressbook_categories "
+ "where addressId = '" + addrId + "'" );
+ while ( categoriesQuery.next() )
+ addr.insertCategory( categoriesQuery.value( 0 ).toString() );
+ }
+
+ // customs
+ {
+ QSqlQuery customsQuery( "select app, name, value from kaddressbook_customs "
+ "where addressId = '" + addrId + "'" );
+ while ( customsQuery.next() )
+ addr.insertCustom( customsQuery.value( 0 ).toString(),
+ customsQuery.value( 1 ).toString(),
+ customsQuery.value( 2 ).toString());
+ }
+
+ addressBook()->insertAddressee( addr );
+ }
+
+ return true;
+}
+
+bool ResourceSql::save( Ticket * )
+{
+ // we have to delete all entries for this user and reinsert them
+ QSqlQuery query( "select addressId from kaddressbook_main_" + mUser );
+
+ while ( query.next() ) {
+ QString addrId = query.value( 0 ).toString();
+ QSqlQuery q;
+
+ q.exec( "DELETE FROM kaddressbook_emails WHERE addressId = '" + addrId + "'" );
+ q.exec( "DELETE FROM kaddressbook_phones WHERE addressId = '" + addrId + "'" );
+ q.exec( "DELETE FROM kaddressbook_addresses WHERE addressId = '" + addrId + "'" );
+ q.exec( "DELETE FROM kaddressbook_categories WHERE addressId = '" + addrId + "'" );
+ q.exec( "DELETE FROM kaddressbook_customs WHERE addressId = '" + addrId + "'" );
+
+ q.exec( "DELETE FROM kaddressbook_main_" + mUser + " WHERE addressId = '" + addrId + "'" );
+ }
+
+ // let's start...
+ AddressBook::Iterator it;
+ for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) {
+ if ( (*it).resource() != this && (*it).resource() != 0 ) // save only my and new entries
+ continue;
+
+ QString uid = (*it).uid();
+
+ query.exec( "INSERT INTO kaddressbook_main_" + mUser + " VALUES ('" +
+ (*it).uid() + "','" +
+ (*it).name() + "','" +
+ (*it).familyName() + "','" +
+ (*it).givenName() + "','" +
+ (*it).additionalName() + "','" +
+ (*it).prefix() + "','" +
+ (*it).suffix() + "','" +
+ (*it).nickName() + "','" +
+ (*it).birthday().toString( Qt::ISODate ) + "','" +
+ (*it).mailer() + "','" +
+ QString::number( (*it).timeZone().offset() ) + "','" +
+ QString::number( (*it).geo().latitude() ) + "','" +
+ QString::number( (*it).geo().longitude() ) + "','" +
+ (*it).title() + "','" +
+ (*it).role() + "','" +
+ (*it).organization() + "','" +
+ (*it).note() + "','" +
+ (*it).productId() + "','" +
+ (*it).revision().toString( Qt::ISODate ) + "','" +
+ (*it).sortString() + "','" +
+ (*it).url().url() + "')"
+ );
+
+ // emails
+ {
+ QStringList emails = (*it).emails();
+ QStringList::ConstIterator it;
+ bool preferred = true;
+ for( it = emails.begin(); it != emails.end(); ++it ) {
+ query.exec("INSERT INTO kaddressbook_emails VALUES ('" +
+ uid + "','" +
+ (*it) + "','" +
+ QString::number(preferred) + "')");
+ preferred = false;
+ }
+ }
+
+ // phonenumbers
+ {
+ PhoneNumber::List phoneNumberList = (*it).phoneNumbers();
+ PhoneNumber::List::ConstIterator it;
+ for( it = phoneNumberList.begin(); it != phoneNumberList.end(); ++it ) {
+ query.exec("INSERT INTO kaddressbook_phones VALUES ('" +
+ uid + "','" +
+ (*it).number() + "','" +
+ QString::number( (*it).type() ) + "')");
+ }
+ }
+
+ // postal addresses
+ {
+ Address::List addressList = (*it).addresses();
+ Address::List::ConstIterator it;
+ for( it = addressList.begin(); it != addressList.end(); ++it ) {
+ query.exec("INSERT INTO kaddressbook_addresses VALUES ('" +
+ uid + "','" +
+ (*it).postOfficeBox() + "','" +
+ (*it).extended() + "','" +
+ (*it).street() + "','" +
+ (*it).locality() + "','" +
+ (*it).region() + "','" +
+ (*it).postalCode() + "','" +
+ (*it).country() + "','" +
+ (*it).label() + "','" +
+ QString::number( (*it).type() ) + "')");
+ }
+ }
+
+ // categories
+ {
+ QStringList categories = (*it).categories();
+ QStringList::ConstIterator it;
+ for( it = categories.begin(); it != categories.end(); ++it )
+ query.exec("INSERT INTO kaddressbook_categories VALUES ('" +
+ uid + "','" +
+ (*it) + "')");
+ }
+
+ // customs
+ {
+ QStringList list = (*it).customs();
+ QStringList::ConstIterator it;
+ for( it = list.begin(); it != list.end(); ++it ) {
+ int dashPos = (*it).find( '-' );
+ int colonPos = (*it).find( ':' );
+ QString app = (*it).left( dashPos );
+ QString name = (*it).mid( dashPos + 1, colonPos - dashPos - 1 );
+ QString value = (*it).right( (*it).length() - colonPos - 1 );
+
+ query.exec("INSERT INTO kaddressbook_categories VALUES ('" +
+ uid + "','" + app + "','" + name + "','" + value + "')");
+ }
+ }
+ }
+
+ return true;
+}
+
+QString ResourceSql::identifier() const
+{
+ return mHost + "_" + mDbName;
+}
diff --git a/kabc/plugins/sql/resourcesql.h b/kabc/plugins/sql/resourcesql.h
new file mode 100644
index 000000000..c0b61b69b
--- /dev/null
+++ b/kabc/plugins/sql/resourcesql.h
@@ -0,0 +1,63 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KABC_RESOURCESQL_H
+#define KABC_RESOURCESQL_H
+
+#include <kconfig.h>
+
+#include "addressbook.h"
+#include "resource.h"
+
+class QSqlDatabase;
+
+namespace KABC {
+
+class ResourceSql : public Resource
+{
+public:
+ ResourceSql( AddressBook *ab, const QString &user, const QString &password,
+ const QString &db, const QString &host );
+ ResourceSql( AddressBook *ab, const KConfig * );
+
+ bool open();
+ void close();
+
+ Ticket *requestSaveTicket();
+
+ bool load();
+ bool save( Ticket * ticket );
+
+ QString identifier() const;
+
+private:
+ void init(const QString &user, const QString &password,
+ const QString &db, const QString &host );
+
+ QString mUser;
+ QString mPassword;
+ QString mDbName;
+ QString mHost;
+
+ QSqlDatabase *mDb;
+};
+
+}
+#endif
diff --git a/kabc/plugins/sql/resourcesqlconfig.cpp b/kabc/plugins/sql/resourcesqlconfig.cpp
new file mode 100644
index 000000000..d9abffa30
--- /dev/null
+++ b/kabc/plugins/sql/resourcesqlconfig.cpp
@@ -0,0 +1,95 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qspinbox.h>
+#include <qvbox.h>
+
+#include <klineedit.h>
+#include <klocale.h>
+
+#include "resource.h"
+#include "resourcesqlconfig.h"
+
+using namespace KABC;
+
+ResourceSqlConfig::ResourceSqlConfig( QWidget* parent, const char* name )
+ : ResourceConfigWidget( parent, name )
+{
+ resize( 290, 170 );
+
+ QGridLayout *mainLayout = new QGridLayout( this, 4, 2 );
+
+ QLabel *label = new QLabel( i18n( "Username:" ), this );
+ mUser = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 0, 0 );
+ mainLayout->addWidget( mUser, 0, 1 );
+
+ label = new QLabel( i18n( "Password:" ), this );
+ mPassword = new KLineEdit( this );
+ mPassword->setEchoMode( KLineEdit::Password );
+
+ mainLayout->addWidget( label, 1, 0 );
+ mainLayout->addWidget( mPassword, 1, 1 );
+
+ label = new QLabel( i18n( "Host:" ), this );
+ mHost = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 2, 0 );
+ mainLayout->addWidget( mHost, 2, 1 );
+
+ label = new QLabel( i18n( "Port:" ), this );
+ QVBox *box = new QVBox(this);
+ mPort = new QSpinBox(0, 65535, 1, box );
+ mPort->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred));
+ mPort->setValue(389);
+ new QWidget(box, "dummy");
+
+ mainLayout->addWidget( label, 3, 0 );
+ mainLayout->addWidget( box, 3, 1 );
+
+ label = new QLabel( i18n( "Database:" ), this );
+ mDbName = new KLineEdit( this );
+
+ mainLayout->addWidget( label, 4, 0 );
+ mainLayout->addWidget( mDbName, 4, 1 );
+}
+
+void ResourceSqlConfig::loadSettings( KConfig *config )
+{
+ mUser->setText( config->readEntry( "SqlUser" ) );
+ mPassword->setText( KABC::Resource::cryptStr( config->readEntry( "SqlPassword" ) ) );
+ mDbName->setText( config->readEntry( "SqlName" ) );
+ mHost->setText( config->readEntry( "SqlHost" ) );
+ mPort->setValue( config->readNumEntry( "SqlPort" ) );
+}
+
+void ResourceSqlConfig::saveSettings( KConfig *config )
+{
+ config->writeEntry( "SqlUser", mUser->text() );
+ config->writeEntry( "SqlPassword", KABC::Resource::cryptStr( mPassword->text() ) );
+ config->writeEntry( "SqlName", mDbName->text() );
+ config->writeEntry( "SqlHost", mHost->text() );
+ config->writeEntry( "SqlPort", mPort->value() );
+}
+
+#include "resourcesqlconfig.moc"
diff --git a/kabc/plugins/sql/resourcesqlconfig.h b/kabc/plugins/sql/resourcesqlconfig.h
new file mode 100644
index 000000000..d7230870e
--- /dev/null
+++ b/kabc/plugins/sql/resourcesqlconfig.h
@@ -0,0 +1,51 @@
+/*
+ This file is part of libkabc.
+ Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef RESOURCESQLCONFIG_H
+#define RESOURCESQLCONFIG_H
+
+#include "resourceconfigwidget.h"
+
+class KLineEdit;
+class QSpinBox;
+
+namespace KABC {
+
+class ResourceSqlConfig : public ResourceConfigWidget
+{
+ Q_OBJECT
+
+public:
+ ResourceSqlConfig( QWidget* parent = 0, const char* name = 0 );
+
+public slots:
+ void loadSettings( KConfig *config );
+ void saveSettings( KConfig *config );
+
+private:
+ KLineEdit* mUser;
+ KLineEdit* mPassword;
+ KLineEdit* mDbName;
+ KLineEdit* mHost;
+ QSpinBox* mPort;
+};
+
+}
+#endif
diff --git a/kabc/plugins/sql/sql.desktop b/kabc/plugins/sql/sql.desktop
new file mode 100644
index 000000000..69ca3e3a7
--- /dev/null
+++ b/kabc/plugins/sql/sql.desktop
@@ -0,0 +1,10 @@
+[Misc]
+Name=SQL
+Name[bn]=এস-কিউ-এল (SQL)
+Name[hi]=एसक्यूएल (SQL)
+Name[ss]=I-SQL
+Name[te]=ఏస్క్యుఎల్
+
+[Plugin]
+Type=sql
+X-KDE-Library=kabc_sql