From b4d7e65ac0fe08b3b408bd3a0209d0fcd4c084fd Mon Sep 17 00:00:00 2001
From: tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>
Date: Mon, 31 May 2010 21:22:53 +0000
Subject: Multi-save on exit fix

git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1133001 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
---
 kresources/caldav/resource.cpp  | 25 +++++++++++++++++++------
 kresources/caldav/resource.h    |  5 +++++
 kresources/carddav/resource.cpp | 28 +++++++++++++++++++++-------
 kresources/carddav/resource.h   |  7 +++++++
 4 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/kresources/caldav/resource.cpp b/kresources/caldav/resource.cpp
index 3ab1d358..2562a837 100644
--- a/kresources/caldav/resource.cpp
+++ b/kresources/caldav/resource.cpp
@@ -70,6 +70,7 @@ const int ResourceCalDav::DEFAULT_SAVE_POLICY       = ResourceCached::SaveDelaye
 ResourceCalDav::ResourceCalDav( const KConfig *config ) :
     ResourceCached(config)
     , readLockout(false)
+    , mAllWritesComplete(false)
     , mLock(true)
     , mPrefs(NULL)
     , mLoader(NULL)
@@ -77,6 +78,7 @@ ResourceCalDav::ResourceCalDav( const KConfig *config ) :
     , mProgress(NULL)
     , mLoadingQueueReady(true)
     , mWritingQueueReady(true)
+    , mWriteRetryTimer(NULL)
 {
     log("ResourceCalDav(config)");
     init();
@@ -89,11 +91,14 @@ ResourceCalDav::ResourceCalDav( const KConfig *config ) :
 ResourceCalDav::~ResourceCalDav() {
     log("jobs termination");
 
-    // This must save the users data before termination below to prevent data loss...
-    doSave();
+    if (mWriteRetryTimer != NULL) {
+        mWriteRetryTimer->stop();	// Unfortunately we cannot do anything at this point; if this timer is still running something is seriously wrong
+    }
+
     while ((mWriter->running() == true) || (mWritingQueue.isEmpty() == false) || !mWritingQueueReady) {
-         sleep(1);
-         qApp->processEvents(QEventLoop::ExcludeUserInput);
+        readLockout = true;
+        sleep(1);
+        qApp->processEvents(QEventLoop::ExcludeUserInput);
     }
 
     if (mLoader) {
@@ -122,6 +127,10 @@ ResourceCalDav::~ResourceCalDav() {
     delete mPrefs;
 }
 
+bool ResourceCalDav::isSaving() {
+    return (((mWriteRetryTimer != NULL) ? mWriteRetryTimer->isActive() : 0) || (mWriter->running() == true) || (mWritingQueue.isEmpty() == false) || !mWritingQueueReady);
+}
+
 /*=========================================================================
 | GENERAL METHODS
  ========================================================================*/
@@ -129,7 +138,7 @@ ResourceCalDav::~ResourceCalDav() {
 bool ResourceCalDav::doLoad() {
     bool syncCache = true;
 
-    if ((mLoadingQueueReady == false) || (mLoadingQueue.isEmpty() == false) || (mLoader->running() == true)) {
+    if ((mLoadingQueueReady == false) || (mLoadingQueue.isEmpty() == false) || (mLoader->running() == true) || (readLockout == 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!
     }
 
@@ -587,7 +596,11 @@ bool ResourceCalDav::startWriting(const QString& url) {
     // 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()) );
+        if (mWriteRetryTimer == NULL) {
+            mWriteRetryTimer = new QTimer(this);
+            connect( mWriteRetryTimer, SIGNAL(timeout()), SLOT(doSave()) );
+        }
+        mWriteRetryTimer->start(1000, TRUE);
         return false;
     }
 
diff --git a/kresources/caldav/resource.h b/kresources/caldav/resource.h
index a93bf05b..b81e555c 100644
--- a/kresources/caldav/resource.h
+++ b/kresources/caldav/resource.h
@@ -69,6 +69,8 @@ public:
 
     virtual void setReadOnly(bool v);
 
+    bool isSaving();
+
 protected slots:
 
     void loadFinished();
@@ -211,6 +213,7 @@ private:
     static const int DEFAULT_SAVE_POLICY;
 
     bool readLockout;
+    bool mAllWritesComplete;
 
     // members: ===============================================================
 
@@ -226,6 +229,8 @@ private:
     bool mWritingQueueReady;
     QPtrQueue<WritingTask> mWritingQueue;
 
+    QTimer *mWriteRetryTimer;
+
 };
 
 
diff --git a/kresources/carddav/resource.cpp b/kresources/carddav/resource.cpp
index 29a9efb1..59c4ade3 100644
--- a/kresources/carddav/resource.cpp
+++ b/kresources/carddav/resource.cpp
@@ -70,12 +70,15 @@ const int ResourceCardDav::DEFAULT_SAVE_INTERVAL     = 10;
 ResourceCardDav::ResourceCardDav( const KConfig *config ) :
     ResourceCached(config)
     , mLock(true)
+    , readLockout(false)
+    , mAllWritesComplete(false)
     , mPrefs(NULL)
     , mLoader(NULL)
     , mWriter(NULL)
     , mProgress(NULL)
     , mLoadingQueueReady(true)
     , mWritingQueueReady(true)
+    , mWriteRetryTimer(NULL)
 {
     log("ResourceCardDav(config)");
     init();
@@ -88,11 +91,14 @@ ResourceCardDav::ResourceCardDav( const KConfig *config ) :
 ResourceCardDav::~ResourceCardDav() {
     log("jobs termination");
 
-    // This must save the users data before termination below to prevent data loss...
-    doSave();
+    if (mWriteRetryTimer != NULL) {
+        mWriteRetryTimer->stop();	// Unfortunately we cannot do anything at this point; if this timer is still running something is seriously wrong
+    }
+
     while ((mWriter->running() == true) || (mWritingQueue.isEmpty() == false) || !mWritingQueueReady) {
-         sleep(1);
-         qApp->processEvents(QEventLoop::ExcludeUserInput);
+        readLockout = true;
+        sleep(1);
+        qApp->processEvents(QEventLoop::ExcludeUserInput);
     }
 
     if (mLoader) {
@@ -121,6 +127,10 @@ ResourceCardDav::~ResourceCardDav() {
     delete mPrefs;
 }
 
+bool ResourceCardDav::isSaving() {
+    return (((mWriteRetryTimer != NULL) ? mWriteRetryTimer->isActive() : 0) || (mWriter->running() == true) || (mWritingQueue.isEmpty() == false) || !mWritingQueueReady);
+}
+
 /*=========================================================================
 | GENERAL METHODS
  ========================================================================*/
@@ -128,7 +138,7 @@ ResourceCardDav::~ResourceCardDav() {
 bool ResourceCardDav::load() {
     bool syncCache = true;
 
-    if ((mLoadingQueueReady == false) || (mLoadingQueue.isEmpty() == false) || (mLoader->running() == true)) {
+    if ((mLoadingQueueReady == false) || (mLoadingQueue.isEmpty() == false) || (mLoader->running() == true) || (readLockout == 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!
     }
 
@@ -361,7 +371,7 @@ void ResourceCardDav::loadFinished() {
             data.replace('\r', '\n');
 
             log("trying to parse...");
-            //printf("PARSING:\n\r%s\n\r", data.ascii());
+            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!
@@ -566,7 +576,11 @@ bool ResourceCardDav::startWriting(const QString& url) {
     // 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()) );
+        if (mWriteRetryTimer == NULL) {
+            mWriteRetryTimer = new QTimer(this);
+            connect( mWriteRetryTimer, SIGNAL(timeout()), SLOT(doSave()) );
+        }
+        mWriteRetryTimer->start(1000, TRUE);
         return false;
     }
 
diff --git a/kresources/carddav/resource.h b/kresources/carddav/resource.h
index 8df126e2..e117daf3 100644
--- a/kresources/carddav/resource.h
+++ b/kresources/carddav/resource.h
@@ -71,6 +71,8 @@ public:
 
     virtual void setReadOnly(bool v);
 
+    bool isSaving();
+
 protected slots:
 
     void loadFinished();
@@ -190,6 +192,9 @@ private:
     static const int DEFAULT_RELOAD_POLICY;
     static const int DEFAULT_SAVE_POLICY;
 
+    bool readLockout;
+    bool mAllWritesComplete;
+
     // members: ===============================================================
 
     KABC::LockNull mLock;
@@ -204,6 +209,8 @@ private:
     bool mWritingQueueReady;
     QPtrQueue<WritingTask> mWritingQueue;
 
+    QTimer *mWriteRetryTimer;
+
 };
 
 
-- 
cgit v1.2.3

