From 672beaaffcce643b8ab17a191327caa771641a7e Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 23 Jun 2010 02:32:10 +0000 Subject: [PATCH] Major KAddressbook carddav fixes and improvements (should now work with Zimbra once Zimbra fixes a standards compliance issue with contact creation mimetypes) Fixed handling of close events and save interaction with Kontact and Korganizer git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1141613 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- .../plugins/korganizer/korganizerplugin.cpp | 6 ++++ kontact/plugins/korganizer/korganizerplugin.h | 3 ++ kontact/src/main.cpp | 2 +- kontact/src/mainwindow.cpp | 3 +- korganizer/korganizeriface.h | 1 + korganizer/korganizerifaceimpl.cpp | 5 +++ korganizer/korganizerifaceimpl.h | 1 + kresources/carddav/config.cpp | 5 +++ kresources/carddav/config.h | 1 + kresources/carddav/job.cpp | 2 +- kresources/carddav/job.h | 15 +++++++++ kresources/carddav/preferences.cpp | 4 +++ kresources/carddav/preferences.h | 2 ++ kresources/carddav/prefsskel.kcfg | 4 +++ kresources/carddav/reader.cpp | 12 +++---- kresources/carddav/resource.cpp | 13 ++++---- kresources/carddav/writer.cpp | 31 ++++++++++++++----- 17 files changed, 86 insertions(+), 24 deletions(-) diff --git a/kontact/plugins/korganizer/korganizerplugin.cpp b/kontact/plugins/korganizer/korganizerplugin.cpp index 7aef2e6e..f219661d 100644 --- a/kontact/plugins/korganizer/korganizerplugin.cpp +++ b/kontact/plugins/korganizer/korganizerplugin.cpp @@ -212,6 +212,12 @@ void KOrganizerPlugin::processDropEvent( QDropEvent *event ) .arg( event->format() ) ); } +bool KOrganizerPlugin::queryClose() const { + KOrganizerIface_stub stub( kapp->dcopClient(), "korganizer", "KOrganizerIface" ); + bool canClose=stub.canQueryClose(); + return canClose; +} + void KOrganizerPlugin::loadProfile( const QString& directory ) { DCOPRef ref( "korganizer", "KOrganizerIface" ); diff --git a/kontact/plugins/korganizer/korganizerplugin.h b/kontact/plugins/korganizer/korganizerplugin.h index df825996..7d74c830 100644 --- a/kontact/plugins/korganizer/korganizerplugin.h +++ b/kontact/plugins/korganizer/korganizerplugin.h @@ -29,6 +29,7 @@ #include #include "kcalendariface_stub.h" +#include "korganizeriface_stub.h" #include "plugin.h" #include "uniqueapphandler.h" @@ -44,6 +45,8 @@ class KOrganizerPlugin : public Kontact::Plugin virtual bool isRunningStandalone(); int weight() const { return 400; } + virtual bool queryClose() const; + bool canDecodeDrag( QMimeSource * ); void processDropEvent( QDropEvent * ); diff --git a/kontact/src/main.cpp b/kontact/src/main.cpp index d3fce17c..ee29ce9d 100644 --- a/kontact/src/main.cpp +++ b/kontact/src/main.cpp @@ -123,7 +123,7 @@ int KontactApp::newInstance() int main( int argc, char **argv ) { KAboutData about( "kontact", I18N_NOOP( "Kontact" ), version, description, - KAboutData::License_GPL, I18N_NOOP("(C) 2001-2008 The Kontact developers"), 0, "http://kontact.org" ); + KAboutData::License_GPL, I18N_NOOP("(C) 2008-2010 The Trinity Desktop Project\n(C) 2001-2008 The Kontact developers"), 0, "http://trinity.pearsoncomputing.net" ); about.addAuthor( "Daniel Molkentin", 0, "molkentin@kde.org" ); about.addAuthor( "Don Sanders", 0, "sanders@kde.org" ); about.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" ); diff --git a/kontact/src/mainwindow.cpp b/kontact/src/mainwindow.cpp index de4eb2df..a9608528 100644 --- a/kontact/src/mainwindow.cpp +++ b/kontact/src/mainwindow.cpp @@ -1026,7 +1026,8 @@ void MainWindow::saveProperties( KConfig *config ) bool MainWindow::queryClose() { - if ( kapp->sessionSaving() || mReallyClose ) + //if ( kapp->sessionSaving() || mReallyClose ) + if ( kapp->sessionSaving() ) return true; bool localClose = true; diff --git a/korganizer/korganizeriface.h b/korganizer/korganizeriface.h index dac62e2b..5a8c7bde 100644 --- a/korganizer/korganizeriface.h +++ b/korganizer/korganizeriface.h @@ -31,6 +31,7 @@ class KOrganizerIface : virtual public DCOPObject virtual bool mergeURL(const QString &url) = 0; virtual void closeURL() = 0; virtual bool saveURL() = 0; + virtual bool canQueryClose() = 0; virtual bool saveAsURL(const QString &url) = 0; virtual QString getCurrentURLasString() const = 0; virtual bool editIncidence(const QString &uid) = 0; diff --git a/korganizer/korganizerifaceimpl.cpp b/korganizer/korganizerifaceimpl.cpp index 31103432..5605d7a8 100644 --- a/korganizer/korganizerifaceimpl.cpp +++ b/korganizer/korganizerifaceimpl.cpp @@ -90,6 +90,11 @@ bool KOrganizerIfaceImpl::addIncidence( const QString &ical ) return mActionManager->addIncidence( ical ); } +bool KOrganizerIfaceImpl::canQueryClose() +{ + return mActionManager->queryClose(); +} + void KOrganizerIfaceImpl::loadProfile( const QString& path ) { mActionManager->loadProfile( path ); diff --git a/korganizer/korganizerifaceimpl.h b/korganizer/korganizerifaceimpl.h index 228f1b4f..b27cd660 100644 --- a/korganizer/korganizerifaceimpl.h +++ b/korganizer/korganizerifaceimpl.h @@ -49,6 +49,7 @@ public: bool mergeURL( const QString &url ); void closeURL(); bool saveURL(); + bool canQueryClose(); bool saveAsURL( const QString &url ); QString getCurrentURLasString() const; diff --git a/kresources/carddav/config.cpp b/kresources/carddav/config.cpp index 8408184c..2fd58383 100644 --- a/kresources/carddav/config.cpp +++ b/kresources/carddav/config.cpp @@ -87,6 +87,7 @@ void ResourceCardDavConfig::loadSettings( KRES::Resource *resource ) { mUsername->setText(p->username()); mRememberPassword->setChecked(p->rememberPassword()); mPassword->setText(p->password()); + mUseUriNotUID->setChecked(p->useURI()); mReloadConfig->loadSettings(res); mSaveConfig->loadSettings(res); @@ -105,6 +106,7 @@ void ResourceCardDavConfig::saveSettings( KRES::Resource *resource ) { p->setUsername(mUsername->text()); p->setRememberPassword(mRememberPassword->isChecked()); p->setPassword(mPassword->text()); + p->setUseURI(mUseUriNotUID->isChecked()); } } } @@ -137,6 +139,9 @@ void ResourceCardDavConfig::setupUI() { mRememberPassword = new QCheckBox( i18n("Remember password"), this ); mainLayout->addWidget(mRememberPassword, 4, 1); + mUseUriNotUID = new QCheckBox( i18n( "Use URI instead of UID when modifying existing contacts" ), this ); + mainLayout->addWidget( mUseUriNotUID, 5, 1 ); + // configs QHBoxLayout* horizontal = new QHBoxLayout(this); diff --git a/kresources/carddav/config.h b/kresources/carddav/config.h index c71d55a5..f74cb07f 100644 --- a/kresources/carddav/config.h +++ b/kresources/carddav/config.h @@ -59,6 +59,7 @@ private: QLineEdit *mUsername; QLineEdit *mPassword; QCheckBox *mRememberPassword; + QCheckBox *mUseUriNotUID; CardDavReloadConfig* mReloadConfig; CardDavSaveConfig* mSaveConfig; diff --git a/kresources/carddav/job.cpp b/kresources/carddav/job.cpp index e82645f2..ce5141f0 100644 --- a/kresources/carddav/job.cpp +++ b/kresources/carddav/job.cpp @@ -35,7 +35,7 @@ using namespace KABC; | CONSTRUCTOR AND DESTRUCTOR ========================================================================*/ -CardDavJob::CardDavJob(const QString& url) { +CardDavJob::CardDavJob(const QString& url) : mUseURI(false) { cleanJob(); setUrl(url); } diff --git a/kresources/carddav/job.h b/kresources/carddav/job.h index 6d6f8a8a..79e12f82 100644 --- a/kresources/carddav/job.h +++ b/kresources/carddav/job.h @@ -52,6 +52,13 @@ public: mUrl = s; } + /** + * Sets whether to use UID (false) or URI (true) as an object's unique identifier + */ + virtual void setUseURI(bool b) { + mUseURI = b; + } + /** * Sets the parent qobject. */ @@ -73,6 +80,13 @@ public: return mUrl; } + /** + * @return whether to use UID (false) or URI (true) as an object's unique identifier + */ + virtual bool getUseURI() { + return mUseURI; + } + /** * @return parent object */ @@ -151,6 +165,7 @@ private: long mErrorNumber; QObject *mParent; int mType; + bool mUseURI; void enableCarddavDebug(runtime_info*); }; diff --git a/kresources/carddav/preferences.cpp b/kresources/carddav/preferences.cpp index 69c0db9c..e9504119 100644 --- a/kresources/carddav/preferences.cpp +++ b/kresources/carddav/preferences.cpp @@ -206,6 +206,10 @@ void CardDavPrefs::readConfig() { }*/ } +bool CardDavPrefs::getUseURI() { + return useURI(); +} + QString CardDavPrefs::getFullUrl() { QUrl t(url()); diff --git a/kresources/carddav/preferences.h b/kresources/carddav/preferences.h index c3f31ed2..6035efe2 100644 --- a/kresources/carddav/preferences.h +++ b/kresources/carddav/preferences.h @@ -86,6 +86,8 @@ public: */ QString getFullUrl(); + bool getUseURI(); + protected: /** diff --git a/kresources/carddav/prefsskel.kcfg b/kresources/carddav/prefsskel.kcfg index 39b79b85..9012e9ba 100644 --- a/kresources/carddav/prefsskel.kcfg +++ b/kresources/carddav/prefsskel.kcfg @@ -22,5 +22,9 @@ + + + + diff --git a/kresources/carddav/reader.cpp b/kresources/carddav/reader.cpp index 57375e9f..d71d5236 100644 --- a/kresources/carddav/reader.cpp +++ b/kresources/carddav/reader.cpp @@ -38,13 +38,11 @@ int CardDavReader::runJob(runtime_info* RT) { 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); - } + kdDebug() << "getting all objects"; + if (getUseURI() == false) + res = carddav_getall_object(result, std::string(url().ascii()).c_str(), RT); + else + res = carddav_getall_object_by_uri(result, std::string(url().ascii()).c_str(), RT); if (OK == res) { kdDebug() << "success"; diff --git a/kresources/carddav/resource.cpp b/kresources/carddav/resource.cpp index 77a0e688..d8d4508d 100644 --- a/kresources/carddav/resource.cpp +++ b/kresources/carddav/resource.cpp @@ -333,6 +333,7 @@ void ResourceCardDav::loadingQueuePop() { mLoader->setUrl(t->url); mLoader->setParent(this); mLoader->setType(0); + mLoader->setUseURI(mPrefs->getUseURI()); //QDateTime dt(QDate::currentDate()); //mLoader->setRange(dt.addDays(-CACHE_DAYS), dt.addDays(CACHE_DAYS)); @@ -394,17 +395,11 @@ void ResourceCardDav::loadFinished() { 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(); @@ -550,6 +545,7 @@ void ResourceCardDav::writingQueuePop() { mWriter->setUrl(t->url); mWriter->setParent(this); mWriter->setType(1); + mWriter->setUseURI(mPrefs->getUseURI()); #ifdef KCARDDAV_DEBUG const QString fout_path = "/tmp/kcarddav_upload_" + identifier() + ".tmp"; @@ -673,6 +669,11 @@ void ResourceCardDav::writingFinished() { mWritingQueueReady = true; updateProgressBar(1); writingQueuePop(); + + // If a URI is required we will need to retrieve it from the server after the new record is committed... + if (mPrefs->getUseURI() == true) { + startLoading(mPrefs->getFullUrl()); + } } // EOF ======================================================================== diff --git a/kresources/carddav/writer.cpp b/kresources/carddav/writer.cpp index 479120d4..2216fb06 100644 --- a/kresources/carddav/writer.cpp +++ b/kresources/carddav/writer.cpp @@ -24,9 +24,9 @@ // 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 +// It's done, because, for some reason, Zimbra returns an error +// on carddav_modify_object. +//#define USE_CARDDAV_MODIFY /*========================================================================= | NAMESPACE @@ -52,20 +52,35 @@ int CardDavWriter::runJob(runtime_info* RT) { if (OK == res) { #ifdef USE_CARDDAV_MODIFY kdDebug() << "pushing changed objects"; - res = pushObjects(mChanged, carddav_modify_object, OK, RT); + if (getUseURI() == false) + res = pushObjects(mChanged, carddav_modify_object, OK, RT); + else + res = pushObjects(mChanged, carddav_modify_object_by_uri, OK, RT); if (OK == res) { kdDebug() << "pushing deleted objects"; - res = pushObjects(mDeleted, carddav_delete_object, OK, RT); + if (getUseURI() == false) + res = pushObjects(mDeleted, carddav_delete_object, OK, RT); + else + res = pushObjects(mDeleted, carddav_delete_object_by_uri, OK, RT); } #else // if USE_CARDDAV_MODIFY kdDebug() << "pushing changed objects (delete)"; - res = pushObjects(mChanged, carddav_delete_object, OK, RT); + if (getUseURI() == false) + res = pushObjects(mChanged, carddav_delete_object, OK, RT); + else + res = pushObjects(mChanged, carddav_delete_object_by_uri, OK, RT); if (OK == res) { kdDebug() << "pushing changed objects (add)"; - res = pushObjects(mChanged, carddav_add_object, OK, RT); + if (getUseURI() == false) + res = pushObjects(mChanged, carddav_add_object, OK, RT); + else + res = pushObjects(mChanged, carddav_add_object, OK, RT); if (OK == res) { kdDebug() << "pushing deleted objects"; - res = pushObjects(mDeleted, carddav_delete_object, OK, RT); + if (getUseURI() == false) + res = pushObjects(mDeleted, carddav_delete_object, OK, RT); + else + res = pushObjects(mDeleted, carddav_delete_object_by_uri, OK, RT); } } #endif // if USE_CARDDAV_MODIFY