Lots of bugfixes for korganizer caldav resource git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1132701 283d02a7-25f6-0310-bc7c-ecb5cbfe19dav3.5.13-sru
parent
f4a40d0495
commit
7ef3b0e2a5
@ -0,0 +1,35 @@
|
|||||||
|
INCLUDES = -I$(top_srcdir) $(all_includes)
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libkabc_carddav.la
|
||||||
|
|
||||||
|
libkabc_carddav_la_SOURCES = resource.cpp \
|
||||||
|
config.cpp \
|
||||||
|
configwidgets.cpp \
|
||||||
|
preferences.cpp \
|
||||||
|
job.cpp \
|
||||||
|
reader.cpp \
|
||||||
|
writer.cpp \
|
||||||
|
prefsskel.kcfgc
|
||||||
|
libkabc_carddav_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) \
|
||||||
|
-version-info 1:0:0 -no-undefined
|
||||||
|
libkabc_carddav_la_LIBADD = \
|
||||||
|
$(top_builddir)/libkdepim/libkdepim.la \
|
||||||
|
$(top_builddir)/libkcal/libkcal.la \
|
||||||
|
-lkabc \
|
||||||
|
-lcarddav
|
||||||
|
libkabc_carddav_la_COMPILE_FIRST = prefsskel.h
|
||||||
|
|
||||||
|
kde_module_LTLIBRARIES = kabc_carddav.la
|
||||||
|
|
||||||
|
kabc_carddav_la_SOURCES = plugin.cpp
|
||||||
|
kabc_carddav_la_LDFLAGS = $(all_libraries) -module -no-undefined $(KDE_PLUGIN)
|
||||||
|
kabc_carddav_la_LIBADD = libkabc_carddav.la
|
||||||
|
kabc_carddav_la_COMPILE_FIRST = prefsskel.h
|
||||||
|
|
||||||
|
kabc_servicedir = $(kde_servicesdir)/kresources/kabc
|
||||||
|
kabc_service_DATA = kabc_carddav.desktop
|
||||||
|
|
||||||
|
METASOURCES = AUTO
|
||||||
|
|
||||||
|
messages: rc.cpp
|
||||||
|
$(XGETTEXT) *.cpp -o $(podir)/kres_carddav.pot
|
@ -0,0 +1,161 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Configuration and properties dialog
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#include "resource.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "configwidgets.h"
|
||||||
|
|
||||||
|
#include <kcombobox.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
#include <kdialog.h>
|
||||||
|
#include <klocale.h>
|
||||||
|
#include <klineedit.h>
|
||||||
|
#include <klistview.h>
|
||||||
|
#include <kurlrequester.h>
|
||||||
|
|
||||||
|
#include <qlabel.h>
|
||||||
|
#include <qlayout.h>
|
||||||
|
#include <qcheckbox.h>
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| NAMESPACE
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
using namespace KABC;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CONSTANTS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| STATIC METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
ResourceCardDav* ResourceCardDavConfig::getCardDavResource(KRES::Resource* resource) {
|
||||||
|
ResourceCardDav *res = dynamic_cast<ResourceCardDav *>( resource );
|
||||||
|
if (!res) {
|
||||||
|
kdDebug() << "invalid resource type";
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardDavPrefs* ResourceCardDavConfig::getPrefs(ResourceCardDav* res) {
|
||||||
|
CardDavPrefs* p = NULL;
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
p = res->prefs();
|
||||||
|
if (!p) {
|
||||||
|
kdDebug() << "CardDAV: res->prefs() returned NULL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CONSTRUCTOR / DESTRUCTOR
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
ResourceCardDavConfig::ResourceCardDavConfig( QWidget *parent )
|
||||||
|
: KRES::ConfigWidget( parent )
|
||||||
|
{
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
void ResourceCardDavConfig::loadSettings( KRES::Resource *resource ) {
|
||||||
|
ResourceCardDav* res = getCardDavResource(resource);
|
||||||
|
CardDavPrefs* p = getPrefs(res);
|
||||||
|
if (NULL != p) {
|
||||||
|
mUrl->setText(p->url());
|
||||||
|
mUsername->setText(p->username());
|
||||||
|
mRememberPassword->setChecked(p->rememberPassword());
|
||||||
|
mPassword->setText(p->password());
|
||||||
|
|
||||||
|
mReloadConfig->loadSettings(res);
|
||||||
|
mSaveConfig->loadSettings(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDavConfig::saveSettings( KRES::Resource *resource ) {
|
||||||
|
ResourceCardDav* res = getCardDavResource(resource);
|
||||||
|
if (NULL != res) {
|
||||||
|
mReloadConfig->saveSettings(res);
|
||||||
|
mSaveConfig->saveSettings(res);
|
||||||
|
|
||||||
|
CardDavPrefs* p = getPrefs(res);
|
||||||
|
if (NULL != p) {
|
||||||
|
p->setUrl(mUrl->text());
|
||||||
|
p->setUsername(mUsername->text());
|
||||||
|
p->setRememberPassword(mRememberPassword->isChecked());
|
||||||
|
p->setPassword(mPassword->text());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDavConfig::setupUI() {
|
||||||
|
QVBoxLayout *vertical = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
QGridLayout *mainLayout = new QGridLayout( this );
|
||||||
|
|
||||||
|
// URL
|
||||||
|
QLabel *label = new QLabel( i18n( "URL:" ), this );
|
||||||
|
mUrl = new QLineEdit( this );
|
||||||
|
mainLayout->addWidget( label, 1, 0 );
|
||||||
|
mainLayout->addWidget( mUrl, 1, 1 );
|
||||||
|
|
||||||
|
// Username
|
||||||
|
label = new QLabel( i18n( "Username:" ), this );
|
||||||
|
mUsername = new QLineEdit( this );
|
||||||
|
mainLayout->addWidget( label, 2, 0 );
|
||||||
|
mainLayout->addWidget( mUsername, 2, 1 );
|
||||||
|
|
||||||
|
// Password
|
||||||
|
label = new QLabel( i18n( "Password:" ), this );
|
||||||
|
mPassword = new QLineEdit( this );
|
||||||
|
mPassword->setEchoMode( QLineEdit::Password );
|
||||||
|
mainLayout->addWidget( label, 3, 0 );
|
||||||
|
mainLayout->addWidget( mPassword, 3, 1 );
|
||||||
|
|
||||||
|
// Remember password checkbox
|
||||||
|
mRememberPassword = new QCheckBox( i18n("Remember password"), this );
|
||||||
|
mainLayout->addWidget(mRememberPassword, 4, 1);
|
||||||
|
|
||||||
|
// configs
|
||||||
|
QHBoxLayout* horizontal = new QHBoxLayout(this);
|
||||||
|
|
||||||
|
// Reload config
|
||||||
|
mReloadConfig = new CardDavReloadConfig(this);
|
||||||
|
horizontal->addWidget(mReloadConfig);
|
||||||
|
|
||||||
|
// Save config
|
||||||
|
mSaveConfig = new CardDavSaveConfig(this);
|
||||||
|
horizontal->addWidget(mSaveConfig);
|
||||||
|
|
||||||
|
// FIXME: This feature does not work; hide the UI elements for later use
|
||||||
|
mRememberPassword->hide();
|
||||||
|
label->hide();
|
||||||
|
mPassword->hide();
|
||||||
|
|
||||||
|
// combining layouts
|
||||||
|
vertical->addLayout(mainLayout);
|
||||||
|
vertical->addLayout(horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF ========================================================================
|
@ -0,0 +1,79 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Configuration and properties dialog
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#ifndef KABC_RESOURCECARDDAVCONFIG_H
|
||||||
|
#define KABC_RESOURCECARDDAVCONFIG_H
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
#include <kdemacros.h>
|
||||||
|
#include <kresources/configwidget.h>
|
||||||
|
|
||||||
|
class QLineEdit;
|
||||||
|
class QCheckBox;
|
||||||
|
|
||||||
|
namespace KABC {
|
||||||
|
|
||||||
|
class CardDavReloadConfig;
|
||||||
|
class CardDavSaveConfig;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CLASS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration widget for CardDAV resource.
|
||||||
|
*/
|
||||||
|
class KDE_EXPORT ResourceCardDavConfig : public KRES::ConfigWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ResourceCardDavConfig(QWidget *parent = 0);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
virtual void loadSettings(KRES::Resource *resource);
|
||||||
|
virtual void saveSettings(KRES::Resource *resource);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void setupUI();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QLineEdit *mUrl;
|
||||||
|
QLineEdit *mUsername;
|
||||||
|
QLineEdit *mPassword;
|
||||||
|
QCheckBox *mRememberPassword;
|
||||||
|
CardDavReloadConfig* mReloadConfig;
|
||||||
|
CardDavSaveConfig* mSaveConfig;
|
||||||
|
|
||||||
|
static ResourceCardDav* getCardDavResource(KRES::Resource* res);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns preferences of the given ResourceCardDav object.
|
||||||
|
* @param res resource object.
|
||||||
|
* @return if preferences object is obtained successfully, it's returned. Otherwise, NULL is returned.
|
||||||
|
*/
|
||||||
|
static CardDavPrefs* getPrefs(ResourceCardDav* res);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KABC
|
||||||
|
|
||||||
|
|
||||||
|
#endif // KABC_RESOURCECARDDAVCONFIG_H
|
||||||
|
|
@ -0,0 +1,255 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KABCDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Automatic Reload / Automatic Save configuration widgets.
|
||||||
|
| The code is mostly taken from resourcecachedconfig.h/cpp files from
|
||||||
|
| the kcal library and changed to meet our requirements.
|
||||||
|
| The original copyright is below.
|
||||||
|
========================================================================*/
|
||||||
|
/*
|
||||||
|
This file is part of the kcal library.
|
||||||
|
|
||||||
|
Copyright (c) 2004 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 "configwidgets.h"
|
||||||
|
|
||||||
|
#include <kabcresourcecached.h>
|
||||||
|
|
||||||
|
#include <klocale.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
|
||||||
|
#include <qlabel.h>
|
||||||
|
#include <qlayout.h>
|
||||||
|
#include <qcheckbox.h>
|
||||||
|
#include <qradiobutton.h>
|
||||||
|
#include <qspinbox.h>
|
||||||
|
#include <qbuttongroup.h>
|
||||||
|
#include <qgroupbox.h>
|
||||||
|
#include <qhbox.h>
|
||||||
|
|
||||||
|
using namespace KABC;
|
||||||
|
|
||||||
|
//@cond PRIVATE
|
||||||
|
class CardDavConfigPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CardDavConfigPrivate()
|
||||||
|
: mGroup( 0 ),
|
||||||
|
mIntervalSpin( 0 ) {}
|
||||||
|
|
||||||
|
QButtonGroup *mGroup;
|
||||||
|
QSpinBox *mIntervalSpin;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CardDavReloadConfig::Private
|
||||||
|
: public CardDavConfigPrivate
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class CardDavSaveConfig::Private
|
||||||
|
: public CardDavConfigPrivate
|
||||||
|
{
|
||||||
|
};
|
||||||
|
//@endcond
|
||||||
|
|
||||||
|
CardDavReloadConfig::CardDavReloadConfig( QWidget *parent )
|
||||||
|
: QWidget( parent ), d( new KABC::CardDavReloadConfig::Private() )
|
||||||
|
{
|
||||||
|
QBoxLayout *topLayout = new QVBoxLayout( this );
|
||||||
|
|
||||||
|
//QGroupBox *groupBox = new QGroupBox( i18nc( "@title:group", "Automatic Reload" ), this );
|
||||||
|
QGroupBox *groupBox = new QGroupBox( i18n( "Automatic Reload" ), this );
|
||||||
|
topLayout->addWidget( groupBox );
|
||||||
|
|
||||||
|
QRadioButton *noAutomaticReload =
|
||||||
|
new QRadioButton(
|
||||||
|
//i18nc( "@option:radio never reload the cache", "Never" ), groupBox );
|
||||||
|
i18n( "Never" ), groupBox );
|
||||||
|
QRadioButton *automaticReloadOnStartup =
|
||||||
|
new QRadioButton(
|
||||||
|
//i18nc( "@option:radio reload the cache on startup", "Only on startup" ), groupBox );
|
||||||
|
i18n( "Only on startup" ), groupBox );
|
||||||
|
QRadioButton *intervalRadio =
|
||||||
|
new QRadioButton(
|
||||||
|
// i18nc( "@option:radio reload the cache at regular intervals",
|
||||||
|
// "Regular interval" ), groupBox );
|
||||||
|
i18n( "Regular interval" ), groupBox );
|
||||||
|
|
||||||
|
d->mGroup = new QButtonGroup( this );
|
||||||
|
d->mGroup->hide();
|
||||||
|
d->mGroup->insert( intervalRadio, 2 );
|
||||||
|
d->mGroup->insert( automaticReloadOnStartup, 1 );
|
||||||
|
d->mGroup->insert( noAutomaticReload, 0 );
|
||||||
|
|
||||||
|
connect( intervalRadio, SIGNAL( toggled( bool ) ),
|
||||||
|
SLOT( slotIntervalToggled( bool ) ) );
|
||||||
|
|
||||||
|
QHBox *intervalBox = new QHBox( groupBox );
|
||||||
|
//new QLabel( i18nc( "@label:spinbox", "Interval in minutes:" ), intervalBox );
|
||||||
|
new QLabel( i18n( "Interval in minutes:" ), intervalBox );
|
||||||
|
d->mIntervalSpin = new QSpinBox( intervalBox );
|
||||||
|
d->mIntervalSpin->setRange( 1, 900 );
|
||||||
|
d->mIntervalSpin->setEnabled( false );
|
||||||
|
|
||||||
|
groupBox->setColumnLayout(1, Qt::Vertical);
|
||||||
|
QVBoxLayout *vbox = new QVBoxLayout(groupBox->layout());
|
||||||
|
vbox->addWidget(intervalRadio);
|
||||||
|
vbox->addWidget(intervalBox);
|
||||||
|
vbox->addWidget(automaticReloadOnStartup);
|
||||||
|
vbox->addWidget(noAutomaticReload);
|
||||||
|
vbox->addStretch(1);
|
||||||
|
|
||||||
|
// FIXME KABC
|
||||||
|
groupBox->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
CardDavReloadConfig::~CardDavReloadConfig()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavReloadConfig::loadSettings( ResourceCached *resource )
|
||||||
|
{
|
||||||
|
// FIXME KABC
|
||||||
|
//d->mIntervalSpin->setValue( resource->reloadInterval() );
|
||||||
|
//d->mGroup->setButton( resource->reloadPolicy() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavReloadConfig::saveSettings( ResourceCached *resource )
|
||||||
|
{
|
||||||
|
// FIXME KABC
|
||||||
|
//resource->setReloadInterval( d->mIntervalSpin->value() );
|
||||||
|
//resource->setReloadPolicy( d->mGroup->selectedId() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavReloadConfig::slotIntervalToggled( bool checked )
|
||||||
|
{
|
||||||
|
if ( checked ) {
|
||||||
|
d->mIntervalSpin->setEnabled( true );
|
||||||
|
} else {
|
||||||
|
d->mIntervalSpin->setEnabled( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CardDavSaveConfig::CardDavSaveConfig( QWidget *parent )
|
||||||
|
: QWidget( parent ), d( new KABC::CardDavSaveConfig::Private() )
|
||||||
|
{
|
||||||
|
QBoxLayout *topLayout = new QVBoxLayout( this );
|
||||||
|
|
||||||
|
//QGroupBox *groupBox = new QGroupBox( i18nc( "@title:group", "Automatic Save" ), this );
|
||||||
|
QGroupBox *groupBox = new QGroupBox( i18n( "Automatic Save" ), this );
|
||||||
|
d->mGroup = new QButtonGroup( this );
|
||||||
|
d->mGroup->hide();
|
||||||
|
topLayout->addWidget( groupBox );
|
||||||
|
|
||||||
|
QRadioButton *never =
|
||||||
|
new QRadioButton(
|
||||||
|
//i18nc( "@option:radio never save the cache automatically", "Never" ), groupBox );
|
||||||
|
i18n( "Never" ), groupBox );
|
||||||
|
QRadioButton *onExit =
|
||||||
|
new QRadioButton(
|
||||||
|
//i18nc( "@option:radio save the cache on exit", "Only on exit" ), groupBox );
|
||||||
|
i18n( "Only on exit" ), groupBox );
|
||||||
|
|
||||||
|
QRadioButton *intervalRadio =
|
||||||
|
new QRadioButton(
|
||||||
|
//i18nc( "@option:radio save the cache at regular intervals", "Regular interval" ), groupBox );
|
||||||
|
i18n( "Regular interval" ), groupBox );
|
||||||
|
|
||||||
|
d->mGroup = new QButtonGroup( this );
|
||||||
|
d->mGroup->hide();
|
||||||
|
d->mGroup->insert( never, 0 );
|
||||||
|
d->mGroup->insert( onExit, 1 );
|
||||||
|
d->mGroup->insert( intervalRadio, 2 );
|
||||||
|
|
||||||
|
connect( intervalRadio, SIGNAL( toggled( bool ) ),
|
||||||
|
SLOT( slotIntervalToggled( bool ) ) );
|
||||||
|
|
||||||
|
QHBox *intervalBox = new QHBox( groupBox );
|
||||||
|
//new QLabel( i18nc( "@label:spinbox", "Interval in minutes:" ), intervalBox );
|
||||||
|
new QLabel( i18n( "Interval in minutes:" ), intervalBox );
|
||||||
|
d->mIntervalSpin = new QSpinBox( intervalBox );
|
||||||
|
d->mIntervalSpin->setRange( 1, 900 );
|
||||||
|
d->mIntervalSpin->setEnabled( false );
|
||||||
|
|
||||||
|
QRadioButton *delay =
|
||||||
|
new QRadioButton(
|
||||||
|
// i18nc( "@option:radio save the cache after some delay",
|
||||||
|
// "Delayed after changes" ), groupBox );
|
||||||
|
i18n( "Delayed after changes" ), groupBox );
|
||||||
|
QRadioButton *every =
|
||||||
|
new QRadioButton(
|
||||||
|
// i18nc( "@option:radio save the cache after every modification",
|
||||||
|
// "Immediately after changes" ), groupBox );
|
||||||
|
i18n( "Immediately after changes" ), groupBox );
|
||||||
|
d->mGroup->insert( delay, 3 );
|
||||||
|
d->mGroup->insert( every, 4 );
|
||||||
|
|
||||||
|
// hide unwanted widgets. They may be useful in future, so don't delete them for now.
|
||||||
|
intervalRadio->hide();
|
||||||
|
intervalBox->hide();
|
||||||
|
|
||||||
|
groupBox->setColumnLayout(1, Qt::Vertical);
|
||||||
|
QVBoxLayout *vbox = new QVBoxLayout(groupBox->layout());
|
||||||
|
vbox->addWidget(delay);
|
||||||
|
vbox->addWidget(every);
|
||||||
|
vbox->addWidget(intervalRadio);
|
||||||
|
vbox->addWidget(intervalBox);
|
||||||
|
vbox->addWidget(onExit);
|
||||||
|
vbox->addWidget(never);
|
||||||
|
vbox->addStretch(1);
|
||||||
|
|
||||||
|
// FIXME KABC
|
||||||
|
groupBox->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
CardDavSaveConfig::~CardDavSaveConfig()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavSaveConfig::loadSettings( ResourceCached *resource )
|
||||||
|
{
|
||||||
|
// FIXME KABC
|
||||||
|
//d->mIntervalSpin->setValue( resource->saveInterval() );
|
||||||
|
//d->mGroup->setButton( resource->savePolicy() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavSaveConfig::saveSettings( ResourceCached *resource )
|
||||||
|
{
|
||||||
|
// FIXME KABC
|
||||||
|
//resource->setSaveInterval( d->mIntervalSpin->value() );
|
||||||
|
//resource->setSavePolicy( d->mGroup->selectedId() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavSaveConfig::slotIntervalToggled( bool checked )
|
||||||
|
{
|
||||||
|
if ( checked ) {
|
||||||
|
d->mIntervalSpin->setEnabled( true );
|
||||||
|
} else {
|
||||||
|
d->mIntervalSpin->setEnabled( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF ========================================================================
|
@ -0,0 +1,99 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KABCDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Automatic Reload / Automatic Save configuration widgets.
|
||||||
|
| The code is mostly taken from resourcecachedconfig.h/cpp files from
|
||||||
|
| the kcal library and changed to meet our requirements.
|
||||||
|
| The original copyright is below.
|
||||||
|
========================================================================*/
|
||||||
|
/*
|
||||||
|
This file is part of the kcal library.
|
||||||
|
|
||||||
|
Copyright (c) 2004 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 KCARDDAV_AUTOWIDGETS_H
|
||||||
|
#define KCARDDAV_AUTOWIDGETS_H
|
||||||
|
|
||||||
|
#include <qwidget.h>
|
||||||
|
#include <kdemacros.h>
|
||||||
|
|
||||||
|
namespace KABC {
|
||||||
|
|
||||||
|
class ResourceCached;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Configuration widget for reload policy
|
||||||
|
|
||||||
|
@see ResourceCached
|
||||||
|
*/
|
||||||
|
class KDE_EXPORT CardDavReloadConfig : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CardDavReloadConfig( QWidget *parent = 0 );
|
||||||
|
~CardDavReloadConfig();
|
||||||
|
public slots:
|
||||||
|
void loadSettings( ResourceCached *resource );
|
||||||
|
void saveSettings( ResourceCached *resource );
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void slotIntervalToggled( bool );
|
||||||
|
|
||||||
|
private:
|
||||||
|
//@cond PRIVATE
|
||||||
|
//Q_DISABLE_COPY( CardDavReloadConfig )
|
||||||
|
class Private;
|
||||||
|
Private *const d;
|
||||||
|
//@endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Configuration widget for save policy
|
||||||
|
|
||||||
|
@see ResourceCached
|
||||||
|
*/
|
||||||
|
class KDE_EXPORT CardDavSaveConfig : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CardDavSaveConfig( QWidget *parent = 0 );
|
||||||
|
~CardDavSaveConfig();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void loadSettings( ResourceCached *resource );
|
||||||
|
void saveSettings( ResourceCached *resource );
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void slotIntervalToggled( bool );
|
||||||
|
|
||||||
|
private:
|
||||||
|
//@cond PRIVATE
|
||||||
|
//Q_DISABLE_COPY( CardDavSaveConfig )
|
||||||
|
class Private;
|
||||||
|
Private *const d;
|
||||||
|
//@endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // KCARDDAV_AUTOWIDGETS_H
|
@ -0,0 +1,56 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCalDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
| (c) 2009 Kumaran Santhanam (initial KDE4 version)
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Some support macros.
|
||||||
|
| The code is mostly taken from KDE source files.
|
||||||
|
| The original copyright is below.
|
||||||
|
========================================================================*/
|
||||||
|
/* This file is part of the KDE project
|
||||||
|
Copyright (C) 2008 Jarosław Staniek <staniek@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 KRESOURCES_KDEPIM_EXPORT_H
|
||||||
|
#define KRESOURCES_KDEPIM_EXPORT_H
|
||||||
|
|
||||||
|
/** Exports a function returning kresources plugin factory, for resource class @a resourceclass,
|
||||||
|
* @a resourceconfigclass config class and @a catalog catalog.
|
||||||
|
*/
|
||||||
|
#define EXPORT_KRESOURCES_PLUGIN( resourceclass, resourceconfigclass, catalog ) \
|
||||||
|
typedef KRES::PluginFactory< resourceclass, resourceconfigclass > FactoryBase; \
|
||||||
|
class Factory : public FactoryBase { \
|
||||||
|
public: Factory() { KGlobal::locale()->insertCatalogue(catalog); } \
|
||||||
|
}; \
|
||||||
|
K_EXPORT_PLUGIN( Factory )
|
||||||
|
|
||||||
|
/** Like EXPORT_KRESOURCES_PLUGIN but allows to specify two catalogs.
|
||||||
|
*/
|
||||||
|
#define EXPORT_KRESOURCES_PLUGIN2( resourceclass, resourceconfigclass, catalog1, catalog2 ) \
|
||||||
|
typedef KRES::PluginFactory< resourceclass, resourceconfigclass > FactoryBase; \
|
||||||
|
class Factory : public FactoryBase { \
|
||||||
|
public: Factory() { KGlobal::locale()->insertCatalogue(catalog1); \
|
||||||
|
KGlobal::locale()->insertCatalogue(catalog2); } \
|
||||||
|
}; \
|
||||||
|
K_EXPORT_PLUGIN( Factory )
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,110 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Job class for accessing remote address books.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#include "job.h"
|
||||||
|
#include <kdebug.h>
|
||||||
|
#include <klocale.h>
|
||||||
|
|
||||||
|
#include <qmutex.h>
|
||||||
|
|
||||||
|
#define log(s) kdDebug() << s;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| NAMESPACE
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
using namespace KABC;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| STATIC
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CONSTRUCTOR AND DESTRUCTOR
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
CardDavJob::CardDavJob(const QString& url) {
|
||||||
|
cleanJob();
|
||||||
|
setUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardDavJob::~CardDavJob() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
void CardDavJob::enableCarddavDebug(runtime_info* rt) {
|
||||||
|
if (rt && rt->options) {
|
||||||
|
rt->options->debug = 0; // if debug = 1, it causes major CPU overhead
|
||||||
|
rt->options->verify_ssl_certificate = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavJob::setErrorString(const QString& err, const long number) {
|
||||||
|
mError = true;
|
||||||
|
mErrorString = err;
|
||||||
|
mErrorNumber = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavJob::processError(const carddav_error* err) {
|
||||||
|
QString error_string;
|
||||||
|
|
||||||
|
long code = err->code;
|
||||||
|
|
||||||
|
if (-401 == code) { // unauthorized
|
||||||
|
error_string = i18n("Unauthorized. Username or password incorrect.");
|
||||||
|
} else if (-599 <= code && code <= -300) {
|
||||||
|
error_string = i18n("HTTP error %1. Maybe, URL is not a CardDAV resource.").arg(-code);
|
||||||
|
} else {
|
||||||
|
error_string = err->str;
|
||||||
|
}
|
||||||
|
|
||||||
|
setErrorString(error_string, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CardDavJob::run() {
|
||||||
|
log("cleaning job");
|
||||||
|
cleanJob();
|
||||||
|
|
||||||
|
int res = OK;
|
||||||
|
|
||||||
|
runtime_info* carddav_runtime = carddav_get_runtime_info();
|
||||||
|
|
||||||
|
#ifdef KABCDAV_DEBUG
|
||||||
|
log("setting debug carddav options");
|
||||||
|
enableCarddavDebug(carddav_runtime);
|
||||||
|
#endif // KABCDAV_DEBUG
|
||||||
|
|
||||||
|
log("running job");
|
||||||
|
res = runJob(carddav_runtime);
|
||||||
|
|
||||||
|
if (OK != res) {
|
||||||
|
log("job failed");
|
||||||
|
processError(carddav_runtime->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
carddav_free_runtime_info(&carddav_runtime);
|
||||||
|
|
||||||
|
// Signal done
|
||||||
|
// 1000 is read, 1001 is write
|
||||||
|
if (type() == 0) QApplication::postEvent ( parent(), new QEvent( static_cast<QEvent::Type>(1000) ) );
|
||||||
|
if (type() == 1) QApplication::postEvent ( parent(), new QEvent( static_cast<QEvent::Type>(1001) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF ========================================================================
|
@ -0,0 +1,161 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Job class for accessing remote address books.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#ifndef KABCDAV_JOB_H
|
||||||
|
#define KABCDAV_JOB_H
|
||||||
|
|
||||||
|
#include <qthread.h>
|
||||||
|
#include <qstring.h>
|
||||||
|
#include <qdatetime.h>
|
||||||
|
#include <qapplication.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <libcarddav/carddav.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace KABC {
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CLASS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calendar job.
|
||||||
|
*/
|
||||||
|
class CardDavJob : public QThread {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param url URL to load.
|
||||||
|
*/
|
||||||
|
CardDavJob(const QString& url = QString());
|
||||||
|
|
||||||
|
virtual ~CardDavJob();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new URL to load.
|
||||||
|
*/
|
||||||
|
virtual void setUrl(const QString& s) {
|
||||||
|
mUrl = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the parent qobject.
|
||||||
|
*/
|
||||||
|
virtual void setParent(QObject *s) {
|
||||||
|
mParent = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type (0==read, 1==write)
|
||||||
|
*/
|
||||||
|
virtual void setType(int s) {
|
||||||
|
mType = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return URL to load.
|
||||||
|
*/
|
||||||
|
virtual QString url() const {
|
||||||
|
return mUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return parent object
|
||||||
|
*/
|
||||||
|
virtual QObject *parent() {
|
||||||
|
return mParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return type
|
||||||
|
*/
|
||||||
|
virtual int type() {
|
||||||
|
return mType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if downloading process failed.
|
||||||
|
*/
|
||||||
|
virtual bool error() const {
|
||||||
|
return mError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an error string.
|
||||||
|
*/
|
||||||
|
virtual QString errorString() const {
|
||||||
|
return mErrorString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an error number.
|
||||||
|
*/
|
||||||
|
virtual long errorNumber() const {
|
||||||
|
return mErrorNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void run();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main run method for jobs. Jobs should not override run() method.
|
||||||
|
* Instead of this they should override this one.
|
||||||
|
* @param carddavRuntime specific libcarddav runtime information. This pointer should not be saved for the usage
|
||||||
|
* outside of runJob.
|
||||||
|
* @return libcarddav response code (see CARDDAV_RESPONSE)
|
||||||
|
*/
|
||||||
|
virtual int runJob(runtime_info* carddavRuntime) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some cleaning. Jobs may (and usually should) override this method.
|
||||||
|
*/
|
||||||
|
virtual void cleanJob() {
|
||||||
|
mError = false;
|
||||||
|
mErrorString = "";
|
||||||
|
mErrorNumber = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an error string to @p err. Also sets an error flag.
|
||||||
|
*/
|
||||||
|
void setErrorString(const QString& str, const long number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process an error.
|
||||||
|
* Subclasses can overwrite this method, if some special error message handling
|
||||||
|
* should be done. Call setErrorString() to set the error after processing is done.
|
||||||
|
* @param err error structure.
|
||||||
|
*/
|
||||||
|
virtual void processError(const carddav_error* err);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString mUrl;
|
||||||
|
bool mError;
|
||||||
|
QString mErrorString;
|
||||||
|
long mErrorNumber;
|
||||||
|
QObject *mParent;
|
||||||
|
int mType;
|
||||||
|
|
||||||
|
void enableCarddavDebug(runtime_info*);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KABC
|
||||||
|
|
||||||
|
#endif // KABCDAV_JOB_H
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=CardDAV Server (e.g. Zimbra Contacts)
|
||||||
|
Name[af]=CardDAV bediener (bv. Zimbra Contacts)
|
||||||
|
Name[bg]=Сървър CardDAV (e.g. Zimbra Contacts)
|
||||||
|
Name[br]=Servijer CardDAV (e.g. Zimbra Contacts)
|
||||||
|
Name[ca]=Servidor CardDAV (p.ex. Zimbra Contacts)
|
||||||
|
Name[cs]=CardDAV server (např. Zimbra Contacts)
|
||||||
|
Name[da]=CardDAV-server (f.eks. Zimbra Contacts)
|
||||||
|
Name[de]=CardDAV-Server (z. B. Zimbra Contacts)
|
||||||
|
Name[el]=Εξυπηρετητής CardDAV (π.χ. Zimbra Contacts)
|
||||||
|
Name[es]=Servidor CardDAV (por ejemplo, Zimbra Contacts)
|
||||||
|
Name[et]=CardDAV server (nt. Zimbra Contacts)
|
||||||
|
Name[eu]=CardDAV zerbitzaria (adib. Zimbra Contacts)
|
||||||
|
Name[fa]=کارساز CardDAV (مثلاً Zimbra Contacts)
|
||||||
|
Name[fi]=CardDAV-palvelin (esim. Zimbra Contacts)
|
||||||
|
Name[fr]=CardDAV Serveur (ex. Zimbra Contacts)
|
||||||
|
Name[fy]=CardDAV-tsjinner (Zimbra Contacts)
|
||||||
|
Name[ga]=Freastalaí CardDAV (m.sh. Zimbra Contacts)
|
||||||
|
Name[gl]=Servidor CardDAV (e.g. Zimbra Contacts)
|
||||||
|
Name[hu]=CardDAV-kiszolgáló (pl. Zimbra Contacts)
|
||||||
|
Name[is]=CardDAV þjónn (t.d. Zimbra Contacts)
|
||||||
|
Name[it]=Server CardDAV (per es. Zimbra Contacts)
|
||||||
|
Name[ja]=CardDAV サーバ (例 Zimbra Contacts)
|
||||||
|
Name[ka]=სერვერი CardDAV (მაგ., Zimbra Contacts)
|
||||||
|
Name[kk]=CardDAV сервері (мысалы Zimbra Contacts)
|
||||||
|
Name[km]=ម៉ាស៊ីនបម្រើ CardDAV (ឧ. Zimbra Contacts)
|
||||||
|
Name[lt]=CardDAV serveris (pvz.: Zimbra Contacts)
|
||||||
|
Name[ms]=Pelayan CardDAV (misalnya Zimbra Contacts)
|
||||||
|
Name[nb]=CardDAV-tjener (f.eks. Zimbra Contacts)
|
||||||
|
Name[nds]=CardDAV-Server (t.B. Zimbra Contacts)
|
||||||
|
Name[ne]=समूह DAV सर्भर (जस्तै: खुला ग्रुपवेयर)
|
||||||
|
Name[nl]=CardDAV-server (Zimbra Contacts)
|
||||||
|
Name[nn]=CardDAV-tenar (t.d. Zimbra Contacts)
|
||||||
|
Name[pl]=Serwer CardDAV (np. Zimbra Contacts)
|
||||||
|
Name[pt]=Servidor CardDAV (por exemplo Zimbra Contacts)
|
||||||
|
Name[pt_BR]=Servidor GroupDav (p. ex. Zimbra Contacts)
|
||||||
|
Name[ru]=Сервер CardDAV (например, Zimbra Contacts)
|
||||||
|
Name[sk]=CardDAV Server (napr. Zimbra Contacts)
|
||||||
|
Name[sl]=Strežnik CardDAV (npr. Zimbra Contacts)
|
||||||
|
Name[sr]=CardDAV сервер (нпр. Zimbra Contacts)
|
||||||
|
Name[sr@Latn]=CardDAV server (npr. Zimbra Contacts)
|
||||||
|
Name[sv]=CardDAV-server (t.ex. Zimbra Contacts)
|
||||||
|
Name[ta]=CardDAV சேவகன் (e.g. Zimbra Contacts)
|
||||||
|
Name[tr]=CardDAV Sunucusu (ör. Zimbra Contacts)
|
||||||
|
Name[uk]=Сервер CardDAV (напр., Zimbra Contacts)
|
||||||
|
Name[zh_CN]=CardDAV 服务器(如 Zimbra Contacts)
|
||||||
|
Name[zh_TW]=CardDAV 伺服器 (如: Zimbra Contacts)
|
||||||
|
X-KDE-Library=kabc_carddav
|
||||||
|
Type=Service
|
||||||
|
ServiceTypes=KResources/Plugin
|
||||||
|
X-KDE-ResourceFamily=contact
|
||||||
|
X-KDE-ResourceType=carddav
|
@ -0,0 +1,47 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| CardDAV resource factory.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#include "resource.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "export.h"
|
||||||
|
|
||||||
|
#include <kglobal.h>
|
||||||
|
#include <klocale.h>
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| NAMESPACE
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
using namespace KABC;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CLASS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
// Creates the resource factory.
|
||||||
|
|
||||||
|
typedef KRES::PluginFactory<ResourceCardDav, ResourceCardDavConfig> CardDavFactory;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
void *init_kabc_carddav()
|
||||||
|
{
|
||||||
|
KGlobal::locale()->insertCatalogue( "kdepimresources" );
|
||||||
|
KGlobal::locale()->insertCatalogue( "kres_caldav" );
|
||||||
|
return new CardDavFactory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF ========================================================================
|
@ -0,0 +1,235 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KABCDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| CardDAV resource preferences class.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#include "preferences.h"
|
||||||
|
|
||||||
|
#include <kwallet.h>
|
||||||
|
#include <qstring.h>
|
||||||
|
#include <qurl.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| NAMESPACES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
using namespace KABC;
|
||||||
|
using namespace KWallet;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CONSTANTS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
const QString CardDavPrefs::NO_PASSWORD = "";
|
||||||
|
const QString CardDavPrefs::WALLET_FOLDER = "CardDAV resource";
|
||||||
|
const QString CardDavPrefs::WALLET_PWD_SUFFIX = ":carddav_password";
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
bool CardDavPrefs::setWalletFolder(const QString& folder) {
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
if (!mNoWallet && NULL != mWallet) {
|
||||||
|
if (!mWallet->hasFolder(folder)) {
|
||||||
|
if (!mWallet->createFolder(folder)) {
|
||||||
|
ret = false;
|
||||||
|
kdWarning() << "can't create the wallet folder for CardDAV passwords";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!mWallet->setFolder(folder)) {
|
||||||
|
ret = false;
|
||||||
|
kdWarning() << "can't set the wallet folder for CardDAV passwords";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// the wallet is inaccessible or not configured
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Wallet* CardDavPrefs::getWallet() {
|
||||||
|
Wallet* ret = NULL;
|
||||||
|
|
||||||
|
if (!mNoWallet) {
|
||||||
|
// the wallet is not marked as inaccessible
|
||||||
|
|
||||||
|
if (NULL == mWallet) {
|
||||||
|
kdDebug() << "creating wallet for " + mPrefix;
|
||||||
|
|
||||||
|
mWallet = Wallet::openWallet(Wallet::NetworkWallet(), 0);
|
||||||
|
if (NULL == mWallet) {
|
||||||
|
mNoWallet = true; // can't open the wallet, mark it inaccessible
|
||||||
|
kdWarning() << "can't create a wallet for CardDAV passwords";
|
||||||
|
} else {
|
||||||
|
if (setWalletFolder(WALLET_FOLDER)) {
|
||||||
|
// reserved
|
||||||
|
} else {
|
||||||
|
// can't set the wallet folder, remove the wallet and mark it inaccessible
|
||||||
|
kdWarning() << "can't set the walet folder for CardDAV passwords";
|
||||||
|
removeWallet(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mWallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavPrefs::removeWallet(bool noWallet) {
|
||||||
|
delete mWallet;
|
||||||
|
mWallet = NULL;
|
||||||
|
mNoWallet = noWallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavPrefs::addPrefix(const QString& prefix) {
|
||||||
|
KConfigSkeletonItem::List itemList = items();
|
||||||
|
KConfigSkeletonItem::List::Iterator it;
|
||||||
|
|
||||||
|
for ( it = itemList.begin(); it != itemList.end(); ++it ) {
|
||||||
|
(*it)->setGroup( prefix + ':' + (*it)->group() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardDavPrefs::writePasswordToWallet(const QString& password) {
|
||||||
|
|
||||||
|
Wallet* w = getWallet();
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
if (NULL != w) {
|
||||||
|
int rc = w->writePassword(mPrefix + WALLET_PWD_SUFFIX, password);
|
||||||
|
if (0 != rc) {
|
||||||
|
kdWarning() << "CardDAV: can't write password to the wallet";
|
||||||
|
} else {
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardDavPrefs::readPasswordFromWallet(QString& password) {
|
||||||
|
Wallet* w = getWallet();
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
if (NULL != w) {
|
||||||
|
QString p;
|
||||||
|
int rc = w->readPassword(mPrefix + WALLET_PWD_SUFFIX, p);
|
||||||
|
if (0 == rc) {
|
||||||
|
//CardDavPrefsSkel::setPassword(p);
|
||||||
|
password = p;
|
||||||
|
ret = true;
|
||||||
|
} else {
|
||||||
|
kdWarning() << "CardDAV: can't read password from the wallet";
|
||||||
|
password = NO_PASSWORD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CardDavPrefs::removePasswordFromWallet() {
|
||||||
|
|
||||||
|
Wallet* w = getWallet();
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
if (NULL != w) {
|
||||||
|
int rc = w->removeEntry(mPrefix + WALLET_PWD_SUFFIX);
|
||||||
|
if (0 == rc) {
|
||||||
|
ret = true;
|
||||||
|
} else {
|
||||||
|
kdWarning() << "CardDAV: can't remove password from the wallet";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavPrefs::setPassword(const QString& p) {
|
||||||
|
|
||||||
|
mPassword = p;
|
||||||
|
|
||||||
|
if (rememberPassword()) {
|
||||||
|
writePasswordToWallet(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CardDavPrefs::password() {
|
||||||
|
if (NO_PASSWORD == mPassword) {
|
||||||
|
readPasswordFromWallet(mPassword);
|
||||||
|
}
|
||||||
|
return mPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CardDavPrefs::getusername() {
|
||||||
|
return username();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavPrefs::setRememberPassword(bool v) {
|
||||||
|
kdDebug() << "remember: " << v;
|
||||||
|
|
||||||
|
CardDavPrefsSkel::setRememberPassword(v);
|
||||||
|
|
||||||
|
if (!v) {
|
||||||
|
// we should not remember password. If there is one already stored, it must be removed.
|
||||||
|
kdDebug() << "removing password from wallet";
|
||||||
|
removePasswordFromWallet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavPrefs::writeConfig() {
|
||||||
|
CardDavPrefsSkel::writeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDavPrefs::readConfig() {
|
||||||
|
|
||||||
|
CardDavPrefsSkel::readConfig();
|
||||||
|
|
||||||
|
// the password is not in config file, try to restore it from the wallet.
|
||||||
|
/*if (rememberPassword()) {
|
||||||
|
readPasswordFromWallet();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CardDavPrefs::getFullUrl() {
|
||||||
|
|
||||||
|
QUrl t(url());
|
||||||
|
QString safeURL;
|
||||||
|
int firstAt;
|
||||||
|
|
||||||
|
t.setUser(username());
|
||||||
|
t.setPassword(password());
|
||||||
|
|
||||||
|
safeURL = t.toString();
|
||||||
|
|
||||||
|
firstAt = safeURL.find("@") + 1;
|
||||||
|
while (safeURL.find("@", firstAt) != -1) {
|
||||||
|
safeURL.replace(safeURL.find("@", firstAt), 1, "%40");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unencode the username, as Zimbra stupidly rejects the %40
|
||||||
|
safeURL.replace("%40", "@");
|
||||||
|
|
||||||
|
// Encode any spaces, as libcarddav stupidly fails otherwise
|
||||||
|
safeURL.replace(" ", "%20");
|
||||||
|
|
||||||
|
return safeURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF ========================================================================
|
||||||
|
|
@ -0,0 +1,153 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| CardDAV resource preferences class.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#ifndef KABC_CARDDAVPREFS_H
|
||||||
|
#define KABC_CARDDAVPREFS_H
|
||||||
|
|
||||||
|
#include "prefsskel.h"
|
||||||
|
|
||||||
|
#include <kwallet.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
namespace KABC {
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CLASS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides access to ResourceCardDav preferences.
|
||||||
|
* It inherits auto-generated CardDavPrefsSkel class to add password-handling code.
|
||||||
|
* KWallet is used for storing passwords.
|
||||||
|
* It also adds code to allow multiple CardDAV resources to store settings in the same
|
||||||
|
* config file.
|
||||||
|
*/
|
||||||
|
class CardDavPrefs : public CardDavPrefsSkel {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param prefix Unique prefix of the resource instance (use identifier() method).
|
||||||
|
*/
|
||||||
|
CardDavPrefs(const QString& prefix)
|
||||||
|
: mWallet(NULL)
|
||||||
|
, mNoWallet(false)
|
||||||
|
, mPrefix(prefix)
|
||||||
|
, mPassword(NO_PASSWORD)
|
||||||
|
{
|
||||||
|
addPrefix(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~CardDavPrefs() {
|
||||||
|
kdDebug() << "removing wallet";
|
||||||
|
removeWallet();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void writeConfig();
|
||||||
|
virtual void readConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new password. Also, if remember password flag is true,
|
||||||
|
* remembers the password in the wallet. So, if you want the password
|
||||||
|
* to be properly saved, call this method after ensuring the remember flag
|
||||||
|
* is set.
|
||||||
|
*/
|
||||||
|
void setPassword(const QString& p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns password. The password is taken from the wallet.
|
||||||
|
* May return an empty string, if there is no password available.
|
||||||
|
*/
|
||||||
|
QString password();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the username.
|
||||||
|
*/
|
||||||
|
QString getusername();
|
||||||
|
|
||||||
|
void setRememberPassword(bool v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A full URL to connect to CardDAV server (including username and password).
|
||||||
|
*/
|
||||||
|
QString getFullUrl();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an unique prefix to KConfigGroup, so that different instances of the resource
|
||||||
|
* can use the same config file.
|
||||||
|
* @param prefix Unique prefix of the resource instance.
|
||||||
|
*/
|
||||||
|
void addPrefix(const QString& prefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the wallet or NULL, if the wallet can't be obtained.
|
||||||
|
*/
|
||||||
|
KWallet::Wallet* getWallet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to set a working folder for the wallet. If the wallet is not configured yet, does nothing.
|
||||||
|
* @param folder the wallet working folder
|
||||||
|
* @return true, if the folder has been set, and false otherwise.
|
||||||
|
*/
|
||||||
|
bool setWalletFolder(const QString& folder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the wallet. If @p noWallet is set, the wallet has been marked inaccessible, so that subsequent
|
||||||
|
* getWallet calls will not try to recreate it.
|
||||||
|
*/
|
||||||
|
void removeWallet(bool noWallet = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrire password to the wallet.
|
||||||
|
* @param password password to write
|
||||||
|
* @return true on success, false on failure
|
||||||
|
*/
|
||||||
|
bool writePasswordToWallet(const QString& password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts password from the wallet.
|
||||||
|
* @param password a variable to save read password to.
|
||||||
|
* @return true on success, false on failure
|
||||||
|
*/
|
||||||
|
bool readPasswordFromWallet(QString& password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears password in the wallet.
|
||||||
|
* @return true on success, false on failure
|
||||||
|
*/
|
||||||
|
bool removePasswordFromWallet();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static const QString NO_PASSWORD;
|
||||||
|
static const QString WALLET_FOLDER;
|
||||||
|
static const QString WALLET_PWD_SUFFIX;
|
||||||
|
|
||||||
|
KWallet::Wallet* mWallet;
|
||||||
|
bool mNoWallet;
|
||||||
|
|
||||||
|
QString mPrefix;
|
||||||
|
QString mPassword;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KABC
|
||||||
|
|
||||||
|
#endif // KABC_CARDDAVPREFS_H
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||||
|
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||||
|
<kcfgfile name="kresources_caldavrc" />
|
||||||
|
<group name="General" >
|
||||||
|
|
||||||
|
<entry key="Url" type="String" >
|
||||||
|
<label>URL</label>
|
||||||
|
</entry>
|
||||||
|
|
||||||
|
<entry key="Username" type="String">
|
||||||
|
<label>User Name</label>
|
||||||
|
</entry>
|
||||||
|
|
||||||
|
<!-- <entry key="Password" type="String" >
|
||||||
|
<label>Password</label>
|
||||||
|
</entry>-->
|
||||||
|
|
||||||
|
<entry key="RememberPassword" type="Bool" >
|
||||||
|
<label>Remember password</label>
|
||||||
|
</entry>
|
||||||
|
|
||||||
|
</group>
|
||||||
|
</kcfg>
|
@ -0,0 +1,7 @@
|
|||||||
|
# Code generation options for kconfig_compiler
|
||||||
|
File=prefsskel.kcfg
|
||||||
|
ClassName=CardDavPrefsSkel
|
||||||
|
NameSpace=KABC
|
||||||
|
Singleton=false
|
||||||
|
Mutators=true
|
||||||
|
GlobalEnums=true
|
@ -0,0 +1,65 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KABCDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Remote address book loading.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#include "reader.h"
|
||||||
|
#include <kdebug.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| NAMESPACE
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
using namespace KABC;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
void CardDavReader::cleanJob() {
|
||||||
|
CardDavJob::cleanJob();
|
||||||
|
mData = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int CardDavReader::runJob(runtime_info* RT) {
|
||||||
|
kdDebug() << "reader::run, url: " << url();
|
||||||
|
|
||||||
|
response* result = carddav_get_response();
|
||||||
|
CARDDAV_RESPONSE res = OK;
|
||||||
|
|
||||||
|
if (mGetAll) {
|
||||||
|
kdDebug() << "getting all objects";
|
||||||
|
res = carddav_getall_object(result, std::string(url().ascii()).c_str(), RT);
|
||||||
|
} else {
|
||||||
|
kdDebug() << "getting object from the specified time range";
|
||||||
|
res = carddav_get_object(result, mTimeStart.toTime_t(), mTimeEnd.toTime_t(), std::string(url().ascii()).c_str(), RT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OK == res) {
|
||||||
|
kdDebug() << "success";
|
||||||
|
if (result->msg) {
|
||||||
|
mData = result->msg;
|
||||||
|
} else {
|
||||||
|
kdDebug() << "empty collection";
|
||||||
|
// empty collection
|
||||||
|
mData = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
carddav_free_response(&result);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF ========================================================================
|
@ -0,0 +1,91 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KABCDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Remote address book loading class.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#ifndef KABCDAV_LOADER_H
|
||||||
|
#define KABCDAV_LOADER_H
|
||||||
|
|
||||||
|
#include "job.h"
|
||||||
|
|
||||||
|
#include <qstring.h>
|
||||||
|
#include <qdatetime.h>
|
||||||
|
|
||||||
|
namespace KABC {
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CLASS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calendar Reader.
|
||||||
|
*/
|
||||||
|
class CardDavReader : public CardDavJob {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param url URL to load.
|
||||||
|
*/
|
||||||
|
CardDavReader(const QString& url = QString()) :
|
||||||
|
CardDavJob(url)
|
||||||
|
, mGetAll(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a time range. Only event between @p start and @p end will be loaded.
|
||||||
|
* This method call disables the effect of setGetAll() call.
|
||||||
|
* setGetAll() call disables the effect of this method.
|
||||||
|
*/
|
||||||
|
void setRange(const QDateTime& start, const QDateTime& end) {
|
||||||
|
mGetAll = false;
|
||||||
|
mTimeStart = start;
|
||||||
|
mTimeEnd = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the flag to load all events from the remote calendar.
|
||||||
|
* This method call disables the effect of setRange() call.
|
||||||
|
* setGetAll() call disables the effect of this method.
|
||||||
|
*/
|
||||||
|
void setGetAll() {
|
||||||
|
mGetAll = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return downloaded calendar data in iCal format.
|
||||||
|
*/
|
||||||
|
QString data() const {
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual int runJob(runtime_info* caldavRuntime);
|
||||||
|
|
||||||
|
virtual void cleanJob();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString mData;
|
||||||
|
bool mGetAll;
|
||||||
|
QDateTime mTimeStart;
|
||||||
|
QDateTime mTimeEnd;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KABC
|
||||||
|
|
||||||
|
#endif // KABCDAV_LOADER_H
|
||||||
|
|
@ -0,0 +1,635 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Main interface to the KResource system.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <qurl.h>
|
||||||
|
#include <qmessagebox.h>
|
||||||
|
#include <qapplication.h>
|
||||||
|
#include <qeventloop.h>
|
||||||
|
|
||||||
|
#include <kabc/addressee.h>
|
||||||
|
#include <kabc/vcardconverter.h>
|
||||||
|
|
||||||
|
#include <klocale.h>
|
||||||
|
#include <kpassdlg.h>
|
||||||
|
|
||||||
|
#include <qdatetime.h>
|
||||||
|
#include <qmutex.h>
|
||||||
|
#include <qthread.h>
|
||||||
|
#include <qtimer.h>
|
||||||
|
|
||||||
|
#ifdef KCARDDAV_DEBUG
|
||||||
|
#include <qfile.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "resource.h"
|
||||||
|
#include "reader.h"
|
||||||
|
#include "writer.h"
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| NAMESPACE
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
using namespace KABC;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CONSTANTS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
const unsigned long ResourceCardDav::TERMINATION_WAITING_TIME = 3 * 1000; // 3 seconds
|
||||||
|
const int ResourceCardDav::CACHE_DAYS = 90;
|
||||||
|
|
||||||
|
const int ResourceCardDav::DEFAULT_RELOAD_INTERVAL = 10;
|
||||||
|
const int ResourceCardDav::DEFAULT_SAVE_INTERVAL = 10;
|
||||||
|
//const int ResourceCardDav::DEFAULT_RELOAD_POLICY = ResourceCached::ReloadInterval;
|
||||||
|
//const int ResourceCardDav::DEFAULT_SAVE_POLICY = ResourceCached::SaveDelayed;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| UTILITY
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#define log(s) kdDebug() << identifier() << ": " << (s);
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CONSTRUCTOR / DESTRUCTOR
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
ResourceCardDav::ResourceCardDav( const KConfig *config ) :
|
||||||
|
ResourceCached(config)
|
||||||
|
, mLock(true)
|
||||||
|
, mPrefs(NULL)
|
||||||
|
, mLoader(NULL)
|
||||||
|
, mWriter(NULL)
|
||||||
|
, mProgress(NULL)
|
||||||
|
, mLoadingQueueReady(true)
|
||||||
|
, mWritingQueueReady(true)
|
||||||
|
{
|
||||||
|
log("ResourceCardDav(config)");
|
||||||
|
init();
|
||||||
|
|
||||||
|
if ( config ) {
|
||||||
|
readConfig( config );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceCardDav::~ResourceCardDav() {
|
||||||
|
log("jobs termination");
|
||||||
|
|
||||||
|
// This must save the users data before termination below to prevent data loss...
|
||||||
|
doSave();
|
||||||
|
while ((mWriter->running() == true) || (mWritingQueue.isEmpty() == false) || !mWritingQueueReady) {
|
||||||
|
sleep(1);
|
||||||
|
qApp->processEvents(QEventLoop::ExcludeUserInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mLoader) {
|
||||||
|
mLoader->terminate();
|
||||||
|
}
|
||||||
|
if (mWriter) {
|
||||||
|
mWriter->terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
log("waiting for jobs terminated");
|
||||||
|
|
||||||
|
if (mLoader) {
|
||||||
|
mLoader->wait(TERMINATION_WAITING_TIME);
|
||||||
|
}
|
||||||
|
if (mWriter) {
|
||||||
|
mWriter->wait(TERMINATION_WAITING_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
log("deleting jobs");
|
||||||
|
|
||||||
|
delete mLoader;
|
||||||
|
delete mWriter;
|
||||||
|
|
||||||
|
log("deleting preferences");
|
||||||
|
|
||||||
|
delete mPrefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| GENERAL METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
bool ResourceCardDav::load() {
|
||||||
|
bool syncCache = true;
|
||||||
|
|
||||||
|
if ((mLoadingQueueReady == false) || (mLoadingQueue.isEmpty() == false) || (mLoader->running() == true)) {
|
||||||
|
return true; // Silently fail; the user has obviously not responded to a dialog and we don't need to pop up more of them!
|
||||||
|
}
|
||||||
|
|
||||||
|
log(QString("doLoad(%1)").arg(syncCache));
|
||||||
|
|
||||||
|
//clearCache();
|
||||||
|
|
||||||
|
log("loading from cache");
|
||||||
|
//disableChangeNotification();
|
||||||
|
loadCache();
|
||||||
|
//enableChangeNotification();
|
||||||
|
clearChanges();
|
||||||
|
addressBook()->emitAddressBookChanged();
|
||||||
|
emit loadingFinished( this );
|
||||||
|
|
||||||
|
log("starting download job");
|
||||||
|
startLoading(mPrefs->getFullUrl());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceCardDav::doSave() {
|
||||||
|
bool syncCache = true;
|
||||||
|
|
||||||
|
log(QString("doSave(%1)").arg(syncCache));
|
||||||
|
|
||||||
|
if (!hasChanges()) {
|
||||||
|
log("no changes");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("saving cache");
|
||||||
|
saveCache();
|
||||||
|
|
||||||
|
// Delete any queued read jobs
|
||||||
|
mLoadingQueue.clear();
|
||||||
|
|
||||||
|
// See if there is a running read thread and terminate it
|
||||||
|
if (mLoader->running() == true) {
|
||||||
|
mLoader->terminate();
|
||||||
|
mLoader->wait(TERMINATION_WAITING_TIME);
|
||||||
|
mLoadingQueueReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("start writing job");
|
||||||
|
if (startWriting(mPrefs->getFullUrl()) == true) {
|
||||||
|
log("clearing changes");
|
||||||
|
// FIXME: Calling clearChanges() here is not the ideal way since the
|
||||||
|
// upload might fail, but there is no other place to call it...
|
||||||
|
clearChanges();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else return true; // We do not need to alert the user to this transient failure; a timer has been started to retry the save
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ResourceCardDav::save( Ticket* ticket ) {
|
||||||
|
// To suppress warning about doSave() method hides ResourceCached::doSave(Ticket)
|
||||||
|
//return ResourceCached::doSave();
|
||||||
|
return doSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
KABC::Lock* ResourceCardDav::lock() {
|
||||||
|
log("lock()");
|
||||||
|
return &mLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::readConfig( const KConfig *config ) {
|
||||||
|
log("readConfig");
|
||||||
|
mPrefs->readConfig();
|
||||||
|
// FIXME KABC
|
||||||
|
//ResourceCached::readConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::writeConfig( KConfig *config ) {
|
||||||
|
log("writeConfig()");
|
||||||
|
Resource::writeConfig(config);
|
||||||
|
mPrefs->writeConfig();
|
||||||
|
ResourceCached::writeConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
CardDavPrefs* ResourceCardDav::createPrefs() const {
|
||||||
|
log("createPrefs()");
|
||||||
|
CardDavPrefs* p = new CardDavPrefs(identifier());
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::init() {
|
||||||
|
// default settings
|
||||||
|
// setReloadInterval(DEFAULT_RELOAD_INTERVAL);
|
||||||
|
// setReloadPolicy(DEFAULT_RELOAD_POLICY);
|
||||||
|
// setSaveInterval(DEFAULT_SAVE_INTERVAL);
|
||||||
|
// setSavePolicy(DEFAULT_SAVE_POLICY);
|
||||||
|
|
||||||
|
// creating preferences
|
||||||
|
mPrefs = createPrefs();
|
||||||
|
|
||||||
|
// creating reader/writer instances
|
||||||
|
mLoader = new CardDavReader;
|
||||||
|
mWriter = new CardDavWriter;
|
||||||
|
|
||||||
|
// creating jobs
|
||||||
|
// Qt4 handles this quite differently, as shown below,
|
||||||
|
// whereas Qt3 needs events (see ::event())
|
||||||
|
// connect(mLoader, SIGNAL(finished()), this, SLOT(loadFinished()));
|
||||||
|
// connect(mWriter, SIGNAL(finished()), this, SLOT(writingFinished()));
|
||||||
|
|
||||||
|
setType("ResourceCardDav");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::ensureReadOnlyFlagHonored() {
|
||||||
|
//disableChangeNotification();
|
||||||
|
|
||||||
|
// FIXME KABC
|
||||||
|
//Incidence::List inc( rawIncidences() );
|
||||||
|
//setIncidencesReadOnly(inc, readOnly());
|
||||||
|
|
||||||
|
//enableChangeNotification();
|
||||||
|
|
||||||
|
addressBook()->emitAddressBookChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::setReadOnly(bool v) {
|
||||||
|
KRES::Resource::setReadOnly(v);
|
||||||
|
log("ensuring read only flag honored");
|
||||||
|
ensureReadOnlyFlagHonored();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| READING METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
void ResourceCardDav::loadingQueuePush(const LoadingTask *task) {
|
||||||
|
if ((mLoadingQueue.isEmpty() == true) && (mLoader->running() == false)) {
|
||||||
|
mLoadingQueue.enqueue(task);
|
||||||
|
loadingQueuePop();
|
||||||
|
if (mProgress == NULL) {
|
||||||
|
mProgress = KPIM::ProgressManager::createProgressItem(KPIM::ProgressManager::getUniqueID(), i18n("Downloading Calendar") );
|
||||||
|
mProgress->setProgress( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::loadingQueuePop() {
|
||||||
|
if (!mLoadingQueueReady || mLoadingQueue.isEmpty() || (mWritingQueue.isEmpty() == false) || (mWriter->running() == true) || !mWritingQueueReady) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mLoader) {
|
||||||
|
log("loader == NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loading queue and mLoadingQueueReady flag are not shared resources, i.e. only one thread has an access to them.
|
||||||
|
// That's why no mutexes are required.
|
||||||
|
LoadingTask *t = mLoadingQueue.head();
|
||||||
|
|
||||||
|
mLoader->setUrl(t->url);
|
||||||
|
mLoader->setParent(this);
|
||||||
|
mLoader->setType(0);
|
||||||
|
|
||||||
|
//QDateTime dt(QDate::currentDate());
|
||||||
|
//mLoader->setRange(dt.addDays(-CACHE_DAYS), dt.addDays(CACHE_DAYS));
|
||||||
|
//mLoader->setGetAll();
|
||||||
|
|
||||||
|
mLoadingQueueReady = false;
|
||||||
|
|
||||||
|
log("starting actual download job");
|
||||||
|
mLoader->start(QThread::LowestPriority);
|
||||||
|
|
||||||
|
// if all ok, removing the task from the queue
|
||||||
|
mLoadingQueue.dequeue();
|
||||||
|
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::startLoading(const QString& url) {
|
||||||
|
LoadingTask *t = new LoadingTask;
|
||||||
|
t->url = url;
|
||||||
|
loadingQueuePush(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::loadFinished() {
|
||||||
|
CardDavReader* loader = mLoader;
|
||||||
|
|
||||||
|
log("load finished");
|
||||||
|
|
||||||
|
if ( mProgress != NULL) {
|
||||||
|
mProgress->setComplete();
|
||||||
|
mProgress = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loader) {
|
||||||
|
log("loader is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loader->error()) {
|
||||||
|
if (loader->errorNumber() == -401) {
|
||||||
|
if (NULL != mPrefs) {
|
||||||
|
QCString newpass;
|
||||||
|
if (KPasswordDialog::getPassword (newpass, QString("<b>") + i18n("Remote authorization required") + QString("</b><p>") + i18n("Please input the password for") + QString(" ") + mPrefs->getusername(), NULL) != 1) {
|
||||||
|
log("load error: " + loader->errorString() );
|
||||||
|
addressBook()->error(QString("[%1] ").arg(abs(loader->errorNumber())) + loader->errorString());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Set new password and try again
|
||||||
|
mPrefs->setPassword(QString(newpass));
|
||||||
|
startLoading(mPrefs->getFullUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log("load error: " + loader->errorString() );
|
||||||
|
addressBook()->error(QString("[%1] ").arg(abs(loader->errorNumber())) + loader->errorString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log("load error: " + loader->errorString() );
|
||||||
|
addressBook()->error(QString("[%1] ").arg(abs(loader->errorNumber())) + loader->errorString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log("successful load");
|
||||||
|
QString data = loader->data();
|
||||||
|
|
||||||
|
if (!data.isNull() && !data.isEmpty()) {
|
||||||
|
// TODO: I don't know why, but some schedules on http://carddav-test.ioda.net/ (I used it for testing)
|
||||||
|
// have some lines separated by single \r rather than \n or \r\n.
|
||||||
|
// ICalFormat fails to parse that.
|
||||||
|
data.replace("\r\n", "\n"); // to avoid \r\n becomes \n\n after the next line
|
||||||
|
data.replace('\r', '\n');
|
||||||
|
|
||||||
|
log("trying to parse...");
|
||||||
|
//printf("PARSING:\n\r%s\n\r", data.ascii());
|
||||||
|
if (parseData(data)) {
|
||||||
|
// FIXME: The agenda view can crash when a change is
|
||||||
|
// made on a remote server and a reload is requested!
|
||||||
|
log("... parsing is ok");
|
||||||
|
log("clearing changes");
|
||||||
|
//enableChangeNotification();
|
||||||
|
clearChanges();
|
||||||
|
addressBook()->emitAddressBookChanged();
|
||||||
|
emit loadingFinished( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loading queue and mLoadingQueueReady flag are not shared resources, i.e. only one thread has an access to them.
|
||||||
|
// That's why no mutexes are required.
|
||||||
|
mLoadingQueueReady = true;
|
||||||
|
loadingQueuePop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceCardDav::checkData(const QString& data) {
|
||||||
|
log("checking the data");
|
||||||
|
|
||||||
|
KABC::VCardConverter converter;
|
||||||
|
bool ret = true;
|
||||||
|
KABC::VCardConverter conv;
|
||||||
|
Addressee::List addressees = conv.parseVCards( data );
|
||||||
|
if (addressees.isEmpty() == true) {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceCardDav::parseData(const QString& data) {
|
||||||
|
log("parseData()");
|
||||||
|
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
// check if the data is OK
|
||||||
|
// May be it's not efficient (parsing is done twice), but it should be safe
|
||||||
|
if (!checkData(data)) {
|
||||||
|
addressBook()->error(i18n("Parsing calendar data failed."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME KABC
|
||||||
|
//log("clearing cache");
|
||||||
|
//clearCache();
|
||||||
|
|
||||||
|
//disableChangeNotification();
|
||||||
|
|
||||||
|
log("actually parsing the data");
|
||||||
|
|
||||||
|
KABC::VCardConverter conv;
|
||||||
|
Addressee::List addressees = conv.parseVCards( data );
|
||||||
|
Addressee::List::ConstIterator it;
|
||||||
|
for( it = addressees.begin(); it != addressees.end(); ++it ) {
|
||||||
|
KABC::Addressee addr = *it;
|
||||||
|
if ( !addr.isEmpty() ) {
|
||||||
|
addr.setResource( this );
|
||||||
|
|
||||||
|
insertAddressee( addr );
|
||||||
|
clearChange( addr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// debug code here -------------------------------------------------------
|
||||||
|
#ifdef KCARDDAV_DEBUG
|
||||||
|
const QString fout_path = "/tmp/kcarddav_download_" + identifier() + ".tmp";
|
||||||
|
|
||||||
|
QFile fout(fout_path);
|
||||||
|
if (fout.open(IO_WriteOnly | IO_Append)) {
|
||||||
|
QTextStream sout(&fout);
|
||||||
|
sout << "---------- " << resourceName() << ": --------------------------------\n";
|
||||||
|
sout << data << "\n";
|
||||||
|
fout.close();
|
||||||
|
} else {
|
||||||
|
addressBook()->error(i18n("can't open file"));
|
||||||
|
}
|
||||||
|
#endif // KCARDDAV_DEBUG
|
||||||
|
// end of debug code ----------------------------------------------------
|
||||||
|
|
||||||
|
//enableChangeNotification();
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
log("parsing is ok");
|
||||||
|
//if ( !noReadOnlyOnLoad() && readOnly() ) {
|
||||||
|
if ( readOnly() ) {
|
||||||
|
log("ensuring read only flag honored");
|
||||||
|
ensureReadOnlyFlagHonored();
|
||||||
|
}
|
||||||
|
log("saving to cache");
|
||||||
|
saveCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| WRITING METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
Ticket *ResourceCardDav::requestSaveTicket()
|
||||||
|
{
|
||||||
|
if ( !addressBook() ) {
|
||||||
|
kdDebug(5700) << "no addressbook" << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return createTicket( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::releaseSaveTicket( Ticket *ticket )
|
||||||
|
{
|
||||||
|
delete ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::writingQueuePush(const WritingTask *task) {
|
||||||
|
// printf("task->added: %s\n\r", task->added.ascii());
|
||||||
|
// printf("task->deleted: %s\n\r", task->deleted.ascii());
|
||||||
|
// printf("task->changed: %s\n\r", task->changed.ascii());
|
||||||
|
mWritingQueue.enqueue(task);
|
||||||
|
writingQueuePop();
|
||||||
|
if (mProgress == NULL) {
|
||||||
|
mProgress = KPIM::ProgressManager::createProgressItem(KPIM::ProgressManager::getUniqueID(), i18n("Saving Calendar") );
|
||||||
|
mProgress->setProgress( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::writingQueuePop() {
|
||||||
|
if (!mWritingQueueReady || mWritingQueue.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mWriter) {
|
||||||
|
log("writer == NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writing queue and mWritingQueueReady flag are not shared resources, i.e. only one thread has an access to them.
|
||||||
|
// That's why no mutexes are required.
|
||||||
|
WritingTask *t = mWritingQueue.head();
|
||||||
|
|
||||||
|
log("writingQueuePop: url = " + t->url);
|
||||||
|
|
||||||
|
mWriter->setUrl(t->url);
|
||||||
|
mWriter->setParent(this);
|
||||||
|
mWriter->setType(1);
|
||||||
|
|
||||||
|
#ifdef KCARDDAV_DEBUG
|
||||||
|
const QString fout_path = "/tmp/kcarddav_upload_" + identifier() + ".tmp";
|
||||||
|
|
||||||
|
QFile fout(fout_path);
|
||||||
|
if (fout.open(IO_WriteOnly | IO_Append)) {
|
||||||
|
QTextStream sout(&fout);
|
||||||
|
sout << "---------- " << resourceName() << ": --------------------------------\n";
|
||||||
|
sout << "================== Added:\n" << t->added << "\n";
|
||||||
|
sout << "================== Changed:\n" << t->changed << "\n";
|
||||||
|
sout << "================== Deleted:\n" << t->deleted << "\n";
|
||||||
|
fout.close();
|
||||||
|
} else {
|
||||||
|
addressBook()->error(i18n("can't open file"));
|
||||||
|
}
|
||||||
|
#endif // debug
|
||||||
|
|
||||||
|
mWriter->setAddedObjects(t->added);
|
||||||
|
mWriter->setChangedObjects(t->changed);
|
||||||
|
mWriter->setDeletedObjects(t->deleted);
|
||||||
|
|
||||||
|
mWritingQueueReady = false;
|
||||||
|
|
||||||
|
log("starting actual write job");
|
||||||
|
mWriter->start(QThread::LowestPriority);
|
||||||
|
|
||||||
|
// if all ok, remove the task from the queue
|
||||||
|
mWritingQueue.dequeue();
|
||||||
|
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceCardDav::event ( QEvent * e ) {
|
||||||
|
if (e->type() == 1000) {
|
||||||
|
// Read done
|
||||||
|
loadFinished();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (e->type() == 1001) {
|
||||||
|
// Write done
|
||||||
|
writingFinished();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceCardDav::startWriting(const QString& url) {
|
||||||
|
log("startWriting: url = " + url);
|
||||||
|
|
||||||
|
WritingTask *t = new WritingTask;
|
||||||
|
KABC::VCardConverter converter;
|
||||||
|
|
||||||
|
// WARNING: This will segfault if a separate read or write thread
|
||||||
|
// modifies the calendar with clearChanges() or similar
|
||||||
|
// Before these calls are made any existing read (and maybe write) threads should be finished
|
||||||
|
if ((mLoader->running() == true) || (mLoadingQueue.isEmpty() == false) || (mWriter->running() == true) || (mWritingQueue.isEmpty() == false)) {
|
||||||
|
QTimer::singleShot( 100, this, SLOT(doSave()) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
KABC::Addressee::List added = addedAddressees();
|
||||||
|
KABC::Addressee::List changed = changedAddressees();
|
||||||
|
KABC::Addressee::List deleted = deletedAddressees();
|
||||||
|
|
||||||
|
t->url = url;
|
||||||
|
// FIXME KABC
|
||||||
|
t->added = converter.createVCards(added); // This crashes when an event is added from the remote server and save() is subsequently called
|
||||||
|
t->changed = converter.createVCards(changed);
|
||||||
|
t->deleted = converter.createVCards(deleted);
|
||||||
|
|
||||||
|
writingQueuePush(t);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCardDav::writingFinished() {
|
||||||
|
log("writing finished");
|
||||||
|
|
||||||
|
if ( mProgress != NULL) {
|
||||||
|
mProgress->setComplete();
|
||||||
|
mProgress = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mWriter) {
|
||||||
|
log("mWriter is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWriter->error() && (abs(mWriter->errorNumber()) != 207)) {
|
||||||
|
if (mWriter->errorNumber() == -401) {
|
||||||
|
if (NULL != mPrefs) {
|
||||||
|
QCString newpass;
|
||||||
|
if (KPasswordDialog::getPassword (newpass, QString("<b>") + i18n("Remote authorization required") + QString("</b><p>") + i18n("Please input the password for") + QString(" ") + mPrefs->getusername(), NULL) != 1) {
|
||||||
|
log("write error: " + mWriter->errorString());
|
||||||
|
addressBook()->error(QString("[%1] ").arg(abs(mWriter->errorNumber())) + mWriter->errorString());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Set new password and try again
|
||||||
|
mPrefs->setPassword(QString(newpass));
|
||||||
|
startWriting(mPrefs->getFullUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log("write error: " + mWriter->errorString());
|
||||||
|
addressBook()->error(QString("[%1] ").arg(abs(mWriter->errorNumber())) + mWriter->errorString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log("write error: " + mWriter->errorString());
|
||||||
|
addressBook()->error(QString("[%1] ").arg(abs(mWriter->errorNumber())) + mWriter->errorString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log("success");
|
||||||
|
// is there something to do here?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writing queue and mWritingQueueReady flag are not shared resources, i.e. only one thread has an access to them.
|
||||||
|
// That's why no mutexes are required.
|
||||||
|
mWritingQueueReady = true;
|
||||||
|
writingQueuePop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF ========================================================================
|
@ -0,0 +1,214 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Main interface to the KResource system.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#ifndef KABC_RESOURCECARDDAV_H
|
||||||
|
#define KABC_RESOURCECARDDAV_H
|
||||||
|
|
||||||
|
#include "preferences.h"
|
||||||
|
#include <qthread.h>
|
||||||
|
#include <qptrqueue.h>
|
||||||
|
|
||||||
|
#include <kabcresourcecached.h>
|
||||||
|
#include <libkdepim/progressmanager.h>
|
||||||
|
|
||||||
|
#include <kabc/locknull.h>
|
||||||
|
|
||||||
|
#include <kdepimmacros.h>
|
||||||
|
#include <kconfig.h>
|
||||||
|
|
||||||
|
namespace KABC {
|
||||||
|
|
||||||
|
class CardDavReader;
|
||||||
|
class CardDavWriter;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CLASS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides a resource for accessing calendars via CardDAV protocol.
|
||||||
|
*/
|
||||||
|
class KDE_EXPORT ResourceCardDav : public ResourceCached
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit ResourceCardDav( const KConfig *config );
|
||||||
|
virtual ~ResourceCardDav();
|
||||||
|
|
||||||
|
void readConfig( const KConfig *config );
|
||||||
|
void writeConfig( KConfig *config );
|
||||||
|
|
||||||
|
virtual Ticket *requestSaveTicket();
|
||||||
|
virtual void releaseSaveTicket( Ticket* );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return This resource preferences.
|
||||||
|
*/
|
||||||
|
CardDavPrefs* prefs() {
|
||||||
|
return mPrefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return This resource preferences.
|
||||||
|
*/
|
||||||
|
const CardDavPrefs* prefs() const {
|
||||||
|
return mPrefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setReadOnly(bool v);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
|
||||||
|
void loadFinished();
|
||||||
|
|
||||||
|
virtual bool doSave();
|
||||||
|
|
||||||
|
void writingFinished();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
struct LoadingTask {
|
||||||
|
QString url;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WritingTask {
|
||||||
|
QString url;
|
||||||
|
QString added;
|
||||||
|
QString changed;
|
||||||
|
QString deleted;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// virtual bool doLoad( bool syncCache );
|
||||||
|
// virtual bool doSave( bool syncCache );
|
||||||
|
|
||||||
|
virtual bool load();
|
||||||
|
|
||||||
|
virtual bool save( Ticket* ticket );
|
||||||
|
|
||||||
|
virtual KABC::Lock* lock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates prefs and configures them.
|
||||||
|
* @return a newly created preferences object. It should be removed by the caller.
|
||||||
|
*/
|
||||||
|
CardDavPrefs* createPrefs() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes internal state.
|
||||||
|
* Particulary, sets save and reload policies to default values,
|
||||||
|
* creates writing and reading jobs and preferences objects.
|
||||||
|
*/
|
||||||
|
void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates calendar loading process.
|
||||||
|
* @param url URL to load calendar data from.
|
||||||
|
*/
|
||||||
|
void startLoading(const QString& url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the data is correct and can be parsed.
|
||||||
|
* @param data ical string to check.
|
||||||
|
* @return true if the data is correct, false otherwise.
|
||||||
|
*/
|
||||||
|
bool checkData(const QString& data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the data and adds events to the calendar.
|
||||||
|
* @param data calendar data.
|
||||||
|
* @return true on success, false on fail.
|
||||||
|
*/
|
||||||
|
bool parseData(const QString& data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates calendar writing process.
|
||||||
|
* @param url URL to save calendar data to.
|
||||||
|
* @return true if write was queued successfully, false if not
|
||||||
|
*/
|
||||||
|
bool startWriting(const QString& url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures incidences' read-only states are the same as the calendar's read-only state.
|
||||||
|
*/
|
||||||
|
void ensureReadOnlyFlagHonored();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the loading queue is empty or the loader is not ready, does nothing.
|
||||||
|
* Otherwise, pops a head element and starts a loading process for it.
|
||||||
|
*/
|
||||||
|
void loadingQueuePop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes the given loading task to the loading queue.
|
||||||
|
* Then calls loadingQueuePop.
|
||||||
|
*/
|
||||||
|
void loadingQueuePush(const LoadingTask *task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the writing queue is empty or the writer is not ready, does nothing.
|
||||||
|
* Otherwise, pops a head element and starts a writing process for it.
|
||||||
|
*/
|
||||||
|
void writingQueuePop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes the given writing task to the writing queue.
|
||||||
|
* Then calls writingQueuePop.
|
||||||
|
*/
|
||||||
|
void writingQueuePush(const WritingTask *task);
|
||||||
|
|
||||||
|
virtual bool event ( QEvent * e );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// constants: =============================================================
|
||||||
|
|
||||||
|
/// Termination waiting time in milliseconds. Used to terminate job threads.
|
||||||
|
static const unsigned long TERMINATION_WAITING_TIME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource caches only events which are from the interval [-CACHE_DAYS, CACHE_DAYS].
|
||||||
|
*/
|
||||||
|
static const int CACHE_DAYS;
|
||||||
|
|
||||||
|
static const int DEFAULT_RELOAD_INTERVAL;
|
||||||
|
static const int DEFAULT_SAVE_INTERVAL;
|
||||||
|
static const int DEFAULT_RELOAD_POLICY;
|
||||||
|
static const int DEFAULT_SAVE_POLICY;
|
||||||
|
|
||||||
|
// members: ===============================================================
|
||||||
|
|
||||||
|
KABC::LockNull mLock;
|
||||||
|
CardDavPrefs* mPrefs;
|
||||||
|
CardDavReader* mLoader;
|
||||||
|
CardDavWriter* mWriter;
|
||||||
|
KPIM::ProgressItem *mProgress;
|
||||||
|
|
||||||
|
bool mLoadingQueueReady;
|
||||||
|
QPtrQueue<LoadingTask> mLoadingQueue;
|
||||||
|
|
||||||
|
bool mWritingQueueReady;
|
||||||
|
QPtrQueue<WritingTask> mWritingQueue;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace KABC
|
||||||
|
|
||||||
|
#endif // KABC_RESOURCECARDDAV_H
|
||||||
|
|
@ -0,0 +1,2 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Hidden=true
|
@ -0,0 +1,81 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KABCDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Remote address book writing class.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#include "writer.h"
|
||||||
|
#include <kdebug.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| DEFINES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
// Use carddav_modify_object() function.
|
||||||
|
// If it's not set, a pair of carddav_delete_object/carddav_add_object
|
||||||
|
// is used for modifying objects.
|
||||||
|
// It's done, because, for some reason, SOGo server returns an error
|
||||||
|
// on carddav_modify_object. DAViCAL works fine both ways.
|
||||||
|
#define USE_CARDDAV_MODIFY
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| NAMESPACE
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
using namespace KABC;
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| METHODS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
void CardDavWriter::cleanJob() {
|
||||||
|
CardDavJob::cleanJob();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CardDavWriter::runJob(runtime_info* RT) {
|
||||||
|
kdDebug() << "writer::run, url: " << url() << "\n";
|
||||||
|
|
||||||
|
int res = OK;
|
||||||
|
|
||||||
|
kdDebug() << "pushing added objects";
|
||||||
|
res = pushObjects(mAdded, carddav_add_object, OK, RT);
|
||||||
|
if (OK == res) {
|
||||||
|
#ifdef USE_CARDDAV_MODIFY
|
||||||
|
kdDebug() << "pushing changed objects";
|
||||||
|
res = pushObjects(mChanged, carddav_modify_object, OK, RT);
|
||||||
|
if (OK == res) {
|
||||||
|
kdDebug() << "pushing deleted objects";
|
||||||
|
res = pushObjects(mDeleted, carddav_delete_object, OK, RT);
|
||||||
|
}
|
||||||
|
#else // if USE_CARDDAV_MODIFY
|
||||||
|
kdDebug() << "pushing changed objects (delete)";
|
||||||
|
res = pushObjects(mChanged, carddav_delete_object, OK, RT);
|
||||||
|
if (OK == res) {
|
||||||
|
kdDebug() << "pushing changed objects (add)";
|
||||||
|
res = pushObjects(mChanged, carddav_add_object, OK, RT);
|
||||||
|
if (OK == res) {
|
||||||
|
kdDebug() << "pushing deleted objects";
|
||||||
|
res = pushObjects(mDeleted, carddav_delete_object, OK, RT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // if USE_CARDDAV_MODIFY
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OK != res) {
|
||||||
|
clearObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF ========================================================================
|
@ -0,0 +1,109 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
| KCardDAV
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| (c) 2010 Timothy Pearson
|
||||||
|
|
|
||||||
|
| This project is released under the GNU General Public License.
|
||||||
|
| Please see the file COPYING for more details.
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Remote address book writing class.
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| INCLUDES
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
#ifndef KCARDDAV_WRITER_H
|
||||||
|
#define KCARDDAV_WRITER_H
|
||||||
|
|
||||||
|
#include "job.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <qstring.h>
|
||||||
|
#include <qdatetime.h>
|
||||||
|
|
||||||
|
namespace KABC {
|
||||||
|
|
||||||
|
/*=========================================================================
|
||||||
|
| CLASS
|
||||||
|
========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calendar writer.
|
||||||
|
*/
|
||||||
|
class CardDavWriter : public CardDavJob {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param url URL to load.
|
||||||
|
*/
|
||||||
|
CardDavWriter(const QString& url = QString()) :
|
||||||
|
CardDavJob(url)
|
||||||
|
{
|
||||||
|
clearObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the information about added incidences writer should send to server.
|
||||||
|
* @param s icalendar-formatted string consists of all added incidences plus necessary calendar info.
|
||||||
|
* May be an empty string, which means there is no added incidences to send.
|
||||||
|
*/
|
||||||
|
void setAddedObjects(const QString& s) {
|
||||||
|
mAdded = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the information about changed incidences writer should send to server.
|
||||||
|
* @param s icalendar-formatted string consists of all changed incidences plus necessary calendar info.
|
||||||
|
* May be an empty string, which means there is no changed incidences to send.
|
||||||
|
*/
|
||||||
|
void setChangedObjects(const QString& s) {
|
||||||
|
mChanged = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the information about deleted incidences writer should send to server.
|
||||||
|
* @param s icalendar-formatted string consists of all deleted incidences plus necessary calendar info.
|
||||||
|
* May be an empty string, which means there is no deleted incidences to send.
|
||||||
|
*/
|
||||||
|
void setDeletedObjects(const QString& s) {
|
||||||
|
mDeleted = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all the information previously set.
|
||||||
|
*/
|
||||||
|
void clearObjects() {
|
||||||
|
setAddedObjects("");
|
||||||
|
setChangedObjects("");
|
||||||
|
setDeletedObjects("");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual int runJob(runtime_info* caldavRuntime);
|
||||||
|
|
||||||
|
virtual void cleanJob();
|
||||||
|
|
||||||
|
/// Just a wrapper above libcaldav functions.
|
||||||
|
template<typename Operation>
|
||||||
|
int pushObjects(const QString& data, Operation op, int okCode, runtime_info* RT) {
|
||||||
|
int r = okCode;
|
||||||
|
if (!data.isNull() && !data.isEmpty()) {
|
||||||
|
r = op(std::string(data.ascii()).c_str(), std::string(url().ascii()).c_str(), RT);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString mAdded;
|
||||||
|
QString mChanged;
|
||||||
|
QString mDeleted;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KABC
|
||||||
|
|
||||||
|
#endif // KCARDDAV_WRITER_H
|
||||||
|
|
Loading…
Reference in new issue