From cc29364f06178f8f6b457384f2ec37a042bd9d43 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 1 Sep 2010 00:37:02 +0000 Subject: * Massive set of changes to bring in all fixes and enhancements from the Enterprise PIM branch * Ensured that the Trinity changes were applied on top of those enhancements, and any redundancy removed * Added journal read support to the CalDAV resource * Fixed CalDAV resource to use events URL for tasks and journals when separate URL checkbox unchecked git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1170461 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kresources/caldav/config.cpp | 38 +++++++--- kresources/caldav/config.h | 3 + kresources/caldav/job.cpp | 31 +++++++++ kresources/caldav/job.h | 64 +++++++++++++++++ kresources/caldav/preferences.cpp | 29 +++++++- kresources/caldav/preferences.h | 5 ++ kresources/caldav/prefsskel.kcfg | 10 +++ kresources/caldav/reader.cpp | 39 +++++++++++ kresources/caldav/reader.h | 10 +++ kresources/caldav/resource.cpp | 142 ++++++++++++++++++++++++++++++++++++-- kresources/caldav/resource.h | 23 ++++-- kresources/caldav/writer.cpp | 37 ++++++++++ kresources/caldav/writer.h | 46 ++++++++++++ 13 files changed, 457 insertions(+), 20 deletions(-) (limited to 'kresources/caldav') diff --git a/kresources/caldav/config.cpp b/kresources/caldav/config.cpp index 550e00c97..84a4798c6 100644 --- a/kresources/caldav/config.cpp +++ b/kresources/caldav/config.cpp @@ -89,7 +89,9 @@ void ResourceCalDavConfig::loadSettings( KRES::Resource *resource ) { mRememberPassword->setChecked(p->rememberPassword()); mPassword->setText(p->password()); mTasksUrl->setText(p->tasksUrl()); + mJournalsUrl->setText(p->journalsUrl()); mUseSTasks->setChecked(p->useSTasks()); + mUseSJournals->setChecked(p->useSJournals()); mReloadConfig->loadSettings(res); mSaveConfig->loadSettings(res); @@ -110,6 +112,8 @@ void ResourceCalDavConfig::saveSettings( KRES::Resource *resource ) { p->setPassword(mPassword->text()); p->setTasksUrl(mTasksUrl->text()); p->setUseSTasks(mUseSTasks->isChecked()); + p->setJournalsUrl(mJournalsUrl->text()); + p->setUseSJournals(mUseSJournals->isChecked()); } } } @@ -128,34 +132,48 @@ void ResourceCalDavConfig::setupUI() { // Tasks URL TQLabel *tlabel = new TQLabel( i18n( "Tasks URL:" ), this ); mTasksUrl = new TQLineEdit( this ); - mainLayout->addWidget( tlabel, 2, 0 ); - mainLayout->addWidget( mTasksUrl, 2, 1 ); + mainLayout->addWidget( tlabel, 3, 0 ); + mainLayout->addWidget( mTasksUrl, 3, 1 ); // Use Task URL checkbox mUseSTasks = new TQCheckBox( i18n("Use separate Tasks URL"), this ); - mainLayout->addWidget(mUseSTasks, 3, 0 ); + mainLayout->addWidget(mUseSTasks, 2, 0 ); + + // Journals URL + TQLabel *jlabel = new TQLabel( i18n( "Journals URL:" ), this ); + mJournalsUrl = new TQLineEdit( this ); + mainLayout->addWidget( jlabel, 5, 0 ); + mainLayout->addWidget( mJournalsUrl, 5, 1 ); + + // Use Journal URL checkbox + mUseSJournals = new TQCheckBox( i18n("Use separate Journals URL"), this ); + mainLayout->addWidget(mUseSJournals, 4, 0 ); // Username label = new TQLabel( i18n( "Username:" ), this ); mUsername = new TQLineEdit( this ); - mainLayout->addWidget( label, 4, 0 ); - mainLayout->addWidget( mUsername, 4, 1 ); + mainLayout->addWidget( label, 6, 0 ); + mainLayout->addWidget( mUsername, 6, 1 ); // Password label = new TQLabel( i18n( "Password:" ), this ); mPassword = new TQLineEdit( this ); mPassword->setEchoMode( TQLineEdit::Password ); - mainLayout->addWidget( label, 5, 0 ); - mainLayout->addWidget( mPassword, 5, 1 ); + mainLayout->addWidget( label, 7, 0 ); + mainLayout->addWidget( mPassword, 7, 1 ); // Remember password checkbox mRememberPassword = new TQCheckBox( i18n("Remember password"), this ); - mainLayout->addWidget(mRememberPassword, 6, 1); + mainLayout->addWidget(mRememberPassword, 8, 1); mTasksUrl->setEnabled(mUseSTasks->isChecked()); connect( mUseSTasks, TQT_SIGNAL( toggled( bool ) ), TQT_SLOT( slotSTasksToggled( bool ) ) ); + mJournalsUrl->setEnabled(mUseSJournals->isChecked()); + connect( mUseSJournals, TQT_SIGNAL( toggled( bool ) ), + TQT_SLOT( slotSJournalsToggled( bool ) ) ); + // configs TQHBoxLayout* horizontal = new TQHBoxLayout(this); @@ -181,4 +199,8 @@ void ResourceCalDavConfig::slotSTasksToggled( bool enabled ) { mTasksUrl->setEnabled(enabled); } +void ResourceCalDavConfig::slotSJournalsToggled( bool enabled ) { + mJournalsUrl->setEnabled(enabled); +} + // EOF ======================================================================== diff --git a/kresources/caldav/config.h b/kresources/caldav/config.h index 746c87aca..780674281 100644 --- a/kresources/caldav/config.h +++ b/kresources/caldav/config.h @@ -51,6 +51,7 @@ public slots: virtual void saveSettings(KRES::Resource *resource); void slotSTasksToggled( bool ); + void slotSJournalsToggled( bool ); protected: @@ -60,9 +61,11 @@ private: TQLineEdit *mUrl; TQLineEdit *mTasksUrl; + TQLineEdit *mJournalsUrl; TQLineEdit *mUsername; TQLineEdit *mPassword; TQCheckBox *mUseSTasks; + TQCheckBox *mUseSJournals; TQCheckBox *mRememberPassword; CalDavReloadConfig* mReloadConfig; CalDavSaveConfig* mSaveConfig; diff --git a/kresources/caldav/job.cpp b/kresources/caldav/job.cpp index 6edfbbfe8..8e49041f6 100644 --- a/kresources/caldav/job.cpp +++ b/kresources/caldav/job.cpp @@ -68,6 +68,12 @@ void CalDavJob::setTasksErrorString(const TQString& err, const long number) { mTasksErrorNumber = number; } +void CalDavJob::setJournalsErrorString(const TQString& err, const long number) { + mJournalsError = true; + mJournalsErrorString = err; + mJournalsErrorNumber = number; +} + void CalDavJob::processError(const caldav_error* err) { TQString error_string; @@ -100,6 +106,22 @@ void CalDavJob::processTasksError(const caldav_error* err) { setTasksErrorString(error_string, code); } +void CalDavJob::processJournalsError(const caldav_error* err) { + TQString 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. Please ensure that the URL is a valid CalDAV resource.").arg(-code); + } else { + error_string = err->str; + } + + setJournalsErrorString(error_string, code); +} + void CalDavJob::run() { log("cleaning job"); @@ -107,6 +129,7 @@ void CalDavJob::run() { int res = OK; int tasksres = OK; + int journalsres = OK; runtime_info* caldav_runtime = caldav_get_runtime_info(); @@ -131,6 +154,14 @@ void CalDavJob::run() { processTasksError(caldav_runtime->error); } + log("running journals job"); + journalsres = runJournalsJob(caldav_runtime); + + if (OK != journalsres) { + log("journals job failed"); + processJournalsError(caldav_runtime->error); + } + caldav_free_runtime_info(&caldav_runtime); // Signal done diff --git a/kresources/caldav/job.h b/kresources/caldav/job.h index bad00c98d..928e38143 100644 --- a/kresources/caldav/job.h +++ b/kresources/caldav/job.h @@ -60,6 +60,13 @@ public: mTasksUrl = s; } + /** + * Sets a new Journals URL to load. + */ + virtual void setJournalsUrl(const TQString& s) { + mJournalsUrl = s; + } + /** * Sets the parent qobject. */ @@ -88,6 +95,13 @@ public: return mTasksUrl; } + /** + * @return Journals URL to load. + */ + virtual TQString journalsUrl() const { + return mJournalsUrl; + } + /** * @return parent object */ @@ -116,6 +130,13 @@ public: return mTasksError; } + /** + * @return true if journals downloading process failed. + */ + virtual bool journalsError() const { + return mJournalsError; + } + /** * @return an event error string. */ @@ -130,6 +151,13 @@ public: return mTasksErrorString; } + /** + * @return a journal error string. + */ + virtual TQString journalsErrorString() const { + return mJournalsErrorString; + } + /** * @return an event error number. */ @@ -144,6 +172,13 @@ public: return mTasksErrorNumber; } + /** + * @return a journal error number. + */ + virtual long journalsErrorNumber() const { + return mJournalsErrorNumber; + } + protected: virtual void run(); @@ -166,6 +201,15 @@ protected: */ virtual int runTasksJob(runtime_info* caldavRuntime) = 0; + /** + * Main run method for journal jobs. Jobs should not override run() method. + * Instead of this they should override this one. + * @param caldavRuntime specific libcaldav runtime information. This pointer should not be saved for the usage + * outside of runJob. + * @return libcaldav response code (see CALDAV_RESPONSE) + */ + virtual int runJournalsJob(runtime_info* caldavRuntime) = 0; + /** * Some cleaning. Jobs may (and usually should) override this method. */ @@ -176,6 +220,9 @@ protected: mTasksError = false; mTasksErrorString = ""; mTasksErrorNumber = 0; + mJournalsError = false; + mJournalsErrorString = ""; + mJournalsErrorNumber = 0; } /** @@ -188,6 +235,11 @@ protected: */ void setTasksErrorString(const TQString& str, const long number); + /** + * Sets a journal error string to @p err. Also sets an error flag. + */ + void setJournalsErrorString(const TQString& str, const long number); + /** * Process an event error. * Subclasses can overwrite this method, if some special error message handling @@ -204,16 +256,28 @@ protected: */ virtual void processTasksError(const caldav_error* err); + /** + * Process a journal 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 processJournalsError(const caldav_error* err); + private: TQString mUrl; TQString mTasksUrl; + TQString mJournalsUrl; bool mError; bool mTasksError; + bool mJournalsError; TQString mErrorString; TQString mTasksErrorString; + TQString mJournalsErrorString; long mErrorNumber; long mTasksErrorNumber; + long mJournalsErrorNumber; TQObject *mParent; int mType; diff --git a/kresources/caldav/preferences.cpp b/kresources/caldav/preferences.cpp index d70a35193..6eb87e450 100644 --- a/kresources/caldav/preferences.cpp +++ b/kresources/caldav/preferences.cpp @@ -234,7 +234,7 @@ TQString CalDavPrefs::getFullUrl() { TQString CalDavPrefs::getFullTasksUrl() { if (useSTasks() == 0) - return TQString(); + return getFullUrl(); TQUrl t(tasksUrl()); TQString safeURL; @@ -259,5 +259,32 @@ TQString CalDavPrefs::getFullTasksUrl() { return safeURL; } +TQString CalDavPrefs::getFullJournalsUrl() { + if (useSJournals() == 0) + return getFullUrl(); + + TQUrl t(journalsUrl()); + TQString 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 libcaldav stupidly fails otherwise + safeURL.replace(" ", "%20"); + + return safeURL; +} + // EOF ======================================================================== diff --git a/kresources/caldav/preferences.h b/kresources/caldav/preferences.h index 666b8ccf1..98245e6bb 100644 --- a/kresources/caldav/preferences.h +++ b/kresources/caldav/preferences.h @@ -92,6 +92,11 @@ public: */ TQString getFullTasksUrl(); + /** + * @return A full URL to connect to CalDAV Journals server (including username and password). + */ + TQString getFullJournalsUrl(); + protected: /** diff --git a/kresources/caldav/prefsskel.kcfg b/kresources/caldav/prefsskel.kcfg index bb05a75f6..7a72dd6b5 100644 --- a/kresources/caldav/prefsskel.kcfg +++ b/kresources/caldav/prefsskel.kcfg @@ -14,8 +14,18 @@ + + + + + false + + + + + false diff --git a/kresources/caldav/reader.cpp b/kresources/caldav/reader.cpp index a7956fe62..892b490c6 100644 --- a/kresources/caldav/reader.cpp +++ b/kresources/caldav/reader.cpp @@ -38,6 +38,11 @@ void CalDavReader::cleanTasksJob() { mTasksData = ""; } +void CalDavReader::cleanJournalsJob() { + CalDavJob::cleanJob(); + mJournalsData = ""; +} + int CalDavReader::runJob(runtime_info* RT) { kdDebug() << "reader::run, url: " << url(); @@ -104,4 +109,38 @@ int CalDavReader::runTasksJob(runtime_info* RT) { return tasksres; } +int CalDavReader::runJournalsJob(runtime_info* RT) { + kdDebug() << "reader::run, journalsUrl: " << journalsUrl(); + + response* result = caldav_get_response(); + CALDAV_RESPONSE journalsres = OK; + + if ((OK == journalsres) && (journalsUrl() != "")) { + kdDebug() << "reader::run, url: " << journalsUrl(); + + if (mGetAll) { + kdDebug() << "getting all objects"; + journalsres = caldav_tasks_getall_object(result, std::string(journalsUrl().ascii()).c_str(), RT); + } else { + kdDebug() << "getting object from the specified time range"; + journalsres = caldav_tasks_get_object(result, mTimeStart.toTime_t(), mTimeEnd.toTime_t(), std::string(journalsUrl().ascii()).c_str(), RT); + } + + if (OK == journalsres) { + kdDebug() << "success"; + if (result->msg) { + mJournalsData = result->msg; + } else { + kdDebug() << "empty collection"; + // empty collection + mJournalsData = ""; + } + } + + caldav_free_response(&result); + } + + return journalsres; +} + // EOF ======================================================================== diff --git a/kresources/caldav/reader.h b/kresources/caldav/reader.h index b62a5931b..9bcc8c87a 100644 --- a/kresources/caldav/reader.h +++ b/kresources/caldav/reader.h @@ -78,18 +78,28 @@ public: return mTasksData; } + /** + * @return downloaded journal data in iCal format. + */ + TQString journalsData() const { + return mJournalsData; + } + protected: virtual int runJob(runtime_info* caldavRuntime); virtual int runTasksJob(runtime_info* caldavRuntime); + virtual int runJournalsJob(runtime_info* caldavRuntime); virtual void cleanJob(); virtual void cleanTasksJob(); + virtual void cleanJournalsJob(); private: TQString mData; TQString mTasksData; + TQString mJournalsData; bool mGetAll; TQDateTime mTimeStart; TQDateTime mTimeEnd; diff --git a/kresources/caldav/resource.cpp b/kresources/caldav/resource.cpp index c0bbf1159..003633a40 100644 --- a/kresources/caldav/resource.cpp +++ b/kresources/caldav/resource.cpp @@ -160,7 +160,7 @@ bool ResourceCalDav::doLoad() { emit resourceLoaded(this); log("starting download job"); - startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl()); + startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl()); return true; } @@ -189,7 +189,7 @@ bool ResourceCalDav::doSave() { } log("start writing job"); - if (startWriting(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl()) == true) { + if (startWriting(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl()) == 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... @@ -334,6 +334,7 @@ void ResourceCalDav::loadingQueuePop() { mLoader->setUrl(t->url); mLoader->setTasksUrl(t->tasksUrl); + mLoader->setJournalsUrl(t->journalsUrl); mLoader->setParent(this); mLoader->setType(0); @@ -353,10 +354,11 @@ void ResourceCalDav::loadingQueuePop() { delete t; } -void ResourceCalDav::startLoading(const TQString& url, const TQString& tasksUrl) { +void ResourceCalDav::startLoading(const TQString& url, const TQString& tasksUrl, const TQString& journalsUrl) { LoadingTask *t = new LoadingTask; t->url = url; t->tasksUrl = tasksUrl; + t->journalsUrl = journalsUrl; loadingQueuePush(t); } @@ -381,7 +383,7 @@ void ResourceCalDav::loadFinished() { else { // Set new password and try again mPrefs->setPassword(TQString(newpass)); - startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl()); + startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl()); } } else { @@ -429,7 +431,7 @@ void ResourceCalDav::loadFinished() { // else { // // Set new password and try again // mPrefs->setPassword(TQString(newpass)); -// startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl()); +// startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl()); // } } else { @@ -466,6 +468,54 @@ void ResourceCalDav::loadFinished() { } } + if (loader->journalsError()) { + if (loader->journalsErrorNumber() == -401) { + if (NULL != mPrefs) { +// TQCString newpass; +// if (KPasswordDialog::getPassword (newpass, TQString("") + i18n("Remote authorization required") + TQString("

") + i18n("Please input the password for") + TQString(" ") + mPrefs->getusername(), NULL) != 1) { +// log("load error: " + loader->journalsErrorString() ); +// loadError(TQString("[%1] ").arg(abs(loader->journalsErrorNumber())) + loader->journalsErrorString()); +// } +// else { +// // Set new password and try again +// mPrefs->setPassword(TQString(newpass)); +// startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl()); +// } + } + else { + log("load error: " + loader->journalsErrorString() ); + loadError(TQString("[%1] ").arg(abs(loader->journalsErrorNumber())) + loader->journalsErrorString()); + } + } + else { + log("load error: " + loader->journalsErrorString() ); + loadError(TQString("[%1] ").arg(abs(loader->journalsErrorNumber())) + loader->journalsErrorString()); + } + } else { + log("successful journals load"); + TQString journalsData = loader->journalsData(); + + if (!journalsData.isNull() && !journalsData.isEmpty()) { + // TODO: I don't know why, but some schedules on http://caldav-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. + journalsData.replace("\r\n", "\n"); // to avoid \r\n becomes \n\n after the next line + journalsData.replace('\r', '\n'); + + log("trying to parse..."); + if (parseJournalsData(journalsData)) { + // 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(); + emit resourceChanged(this); + emit resourceLoaded(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. mLoader->terminate(); @@ -602,6 +652,63 @@ bool ResourceCalDav::parseTasksData(const TQString& data) { return ret; } +bool ResourceCalDav::parseJournalsData(const TQString& data) { + log("parseJournalsData()"); + + 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)) { + loadError(i18n("Parsing calendar data failed.")); + return false; + } + + log("clearing cache"); + clearJournalsCache(); + + disableChangeNotification(); + + log("actually parsing the data"); + + ICalFormat ical; + if ( !ical.fromString( &mCalendar, data ) ) { + // this should never happen, but... + ret = false; + } + + // debug code here ------------------------------------------------------- +#ifdef KCALDAV_DEBUG + const TQString fout_path = "/tmp/kcaldav_download_" + identifier() + ".tmp"; + + TQFile fout(fout_path); + if (fout.open(IO_WriteOnly | IO_Append)) { + TQTextStream sout(&fout); + sout << "---------- " << resourceName() << ": --------------------------------\n"; + sout << data << "\n"; + fout.close(); + } else { + loadError(i18n("can't open file")); + } +#endif // KCALDAV_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 ========================================================================*/ @@ -662,6 +769,7 @@ void ResourceCalDav::writingQueuePop() { mWriter->setUrl(t->url); mWriter->setTasksUrl(t->tasksUrl); + mWriter->setJournalsUrl(t->journalsUrl); mWriter->setParent(this); mWriter->setType(1); @@ -689,6 +797,10 @@ void ResourceCalDav::writingQueuePop() { mWriter->setChangedTasksObjects(t->tasksChanged); mWriter->setDeletedTasksObjects(t->tasksDeleted); + mWriter->setAddedJournalsObjects(t->journalsAdded); + mWriter->setChangedJournalsObjects(t->journalsChanged); + mWriter->setDeletedJournalsObjects(t->journalsDeleted); + mWritingQueueReady = false; log("starting actual write job"); @@ -719,7 +831,7 @@ void ResourceCalDav::releaseReadLockout() { readLockout = false; } -bool ResourceCalDav::startWriting(const TQString& url, const TQString& tasksUrl) { +bool ResourceCalDav::startWriting(const TQString& url, const TQString& tasksUrl, const TQString& journalsUrl) { log("startWriting: url = " + url); // WARNING: This will segfault if a separate read or write thread @@ -757,16 +869,22 @@ bool ResourceCalDav::startWriting(const TQString& url, const TQString& tasksUrl) t->url = url; t->tasksUrl = tasksUrl; + t->journalsUrl = journalsUrl; t->added = ""; t->changed = ""; t->deleted = ""; t->tasksAdded = ""; t->tasksChanged = ""; t->tasksDeleted = ""; + t->journalsAdded = ""; + t->journalsChanged = ""; + t->journalsDeleted = ""; if (getICalString(currentIncidence).contains("BEGIN:VEVENT") > 0) t->added = getICalString(currentIncidence); else if (getICalString(currentIncidence).contains("BEGIN:VTODO") > 0) t->tasksAdded = getICalString(currentIncidence); + else if (getICalString(currentIncidence).contains("BEGIN:VJOURNAL") > 0) + t->journalsAdded = getICalString(currentIncidence); writingQueuePush(t); } @@ -785,11 +903,16 @@ bool ResourceCalDav::startWriting(const TQString& url, const TQString& tasksUrl) t->tasksAdded = ""; t->tasksChanged = ""; t->tasksDeleted = ""; + t->journalsAdded = ""; + t->journalsChanged = ""; + t->journalsDeleted = ""; if (getICalString(currentIncidence).contains("BEGIN:VEVENT") > 0) t->changed = getICalString(currentIncidence); else if (getICalString(currentIncidence).contains("BEGIN:VTODO") > 0) t->tasksChanged = getICalString(currentIncidence); + else if (getICalString(currentIncidence).contains("BEGIN:VJOURNAL") > 0) + t->journalsChanged = getICalString(currentIncidence); writingQueuePush(t); } @@ -808,11 +931,16 @@ bool ResourceCalDav::startWriting(const TQString& url, const TQString& tasksUrl) t->tasksAdded = ""; t->tasksChanged = ""; t->tasksDeleted = ""; + t->journalsAdded = ""; + t->journalsChanged = ""; + t->journalsDeleted = ""; if (getICalString(currentIncidence).contains("BEGIN:VEVENT") > 0) t->deleted = getICalString(currentIncidence); else if (getICalString(currentIncidence).contains("BEGIN:VTODO") > 0) t->tasksDeleted = getICalString(currentIncidence); + else if (getICalString(currentIncidence).contains("BEGIN:VJOURNALS") > 0) + t->journalsDeleted = getICalString(currentIncidence); writingQueuePush(t); } @@ -839,7 +967,7 @@ void ResourceCalDav::writingFinished() { else { // Set new password and try again mPrefs->setPassword(TQString(newpass)); - startWriting(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl()); + startWriting(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl()); } } else { diff --git a/kresources/caldav/resource.h b/kresources/caldav/resource.h index bb69807be..033a19ce4 100644 --- a/kresources/caldav/resource.h +++ b/kresources/caldav/resource.h @@ -86,11 +86,13 @@ protected: struct LoadingTask { TQString url; TQString tasksUrl; + TQString journalsUrl; }; struct WritingTask { TQString url; TQString tasksUrl; + TQString journalsUrl; TQString added; TQString changed; @@ -99,6 +101,10 @@ protected: TQString tasksAdded; TQString tasksChanged; TQString tasksDeleted; + + TQString journalsAdded; + TQString journalsChanged; + TQString journalsDeleted; }; @@ -129,8 +135,9 @@ protected: * Initiates calendar loading process. * @param url URL to load calendar data from. * @param tasksUrl URL to load task data from. + * @param journalsUrl URL to load journal data from. */ - void startLoading(const TQString& url, const TQString& tasksUrl); + void startLoading(const TQString& url, const TQString& tasksUrl, const TQString& journalsUrl); /** * Checks if the data is correct and can be parsed. @@ -148,18 +155,26 @@ protected: /** * Parses the data and adds tasks to the calendar. - * Unlike @ref parseData, this function does NOT clear the cache. * @param data calendar data. * @return true on success, false on fail. */ bool parseTasksData(const TQString& data); + /** + * Parses the data and adds journals to the calendar. + * @param data calendar data. + * @return true on success, false on fail. + */ + bool parseJournalsData(const TQString& data); + /** * Initiates calendar writing process. - * @param url URL to save calendar data to. + * @param url URL to save event data to. + * @param tasksUrl URL to save task data to. + * @param journalsUrl URL to save journal data to. * @return true if write was queued successfully, false if not */ - bool startWriting(const TQString& url, const TQString& tasksUrl); + bool startWriting(const TQString& url, const TQString& tasksUrl, const TQString& journalsUrl); /** * Returns a list of incidences as a valid iCalendar string. diff --git a/kresources/caldav/writer.cpp b/kresources/caldav/writer.cpp index e939f3d9c..a466322eb 100644 --- a/kresources/caldav/writer.cpp +++ b/kresources/caldav/writer.cpp @@ -103,6 +103,34 @@ int CalDavWriter::runJob(runtime_info* RT) { } } + int journalsres = OK; + + if ((OK == journalsres) && (tasksUrl() != "")) { + kdDebug() << "pushing added tasks objects"; + journalsres = pushJournalsObjects(mJournalsAdded, caldav_add_object, OK, RT); + if (OK == journalsres) { +#ifdef USE_CALDAV_TASKS_MODIFY + kdDebug() << "pushing changed objects"; + journalsres = pushJournalsObjects(mJournalsChanged, caldav_tasks_modify_object, OK, RT); + if (OK == journalsres) { + kdDebug() << "pushing deleted objects"; + journalsres = pushJournalsObjects(mJournalsDeleted, caldav_tasks_delete_object, OK, RT); + } +#else // if USE_CALDAV_TASKS_MODIFY + kdDebug() << "pushing changed objects (delete)"; + journalsres = pushJournalsObjects(mJournalsChanged, caldav_tasks_delete_object, OK, RT); + if (OK == journalsres) { + kdDebug() << "pushing changed objects (add)"; + journalsres = pushJournalsObjects(mJournalsChanged, caldav_add_object, OK, RT); + if (OK == journalsres) { + kdDebug() << "pushing deleted objects"; + journalsres = pushJournalsObjects(mJournalsDeleted, caldav_tasks_delete_object, OK, RT); + } + } +#endif // if USE_CALDAV_TASKS_MODIFY + } + } + if ((OK != res) || (OK != tasksres)) { clearObjects(); } @@ -122,4 +150,13 @@ void CalDavWriter::cleanTasksJob() { // Stub function as there is no reason to split the writing jobs like the reading jobs } +int CalDavWriter::runJournalsJob(runtime_info* RT) { + // Stub function as there is no reason to split the writing jobs like the reading jobs + return OK; +} + +void CalDavWriter::cleanJournalsJob() { + // Stub function as there is no reason to split the writing jobs like the reading jobs +} + // EOF ======================================================================== diff --git a/kresources/caldav/writer.h b/kresources/caldav/writer.h index 3b8f82a81..437eeed0e 100644 --- a/kresources/caldav/writer.h +++ b/kresources/caldav/writer.h @@ -81,6 +81,15 @@ public: mTasksAdded = s; } + /** + * Sets the information about added journals writer should send to server. + * @param s icalendar-formatted string consists of all added journals plus necessary calendar info. + * May be an empty string, which means there are no added journals to send. + */ + void setAddedJournalsObjects(const TQString& s) { + mJournalsAdded = s; + } + /** * Sets the information about changed tasks writer should send to server. * @param s icalendar-formatted string consists of all changed tasks plus necessary calendar info. @@ -90,6 +99,15 @@ public: mTasksChanged = s; } + /** + * Sets the information about changed journals writer should send to server. + * @param s icalendar-formatted string consists of all changed journals plus necessary calendar info. + * May be an empty string, which means there are no changed journals to send. + */ + void setChangedJournalsObjects(const TQString& s) { + mJournalsChanged = s; + } + /** * Sets the information about deleted tasks writer should send to server. * @param s icalendar-formatted string consists of all deleted tasks plus necessary calendar info. @@ -99,6 +117,15 @@ public: mTasksDeleted = s; } + /** + * Sets the information about deleted journals writer should send to server. + * @param s icalendar-formatted string consists of all deleted journals plus necessary calendar info. + * May be an empty string, which means there are no deleted journals to send. + */ + void setDeletedJournalsObjects(const TQString& s) { + mJournalsDeleted = s; + } + /** * Clear all the information previously set. */ @@ -109,15 +136,20 @@ public: setAddedTasksObjects(""); setChangedTasksObjects(""); setDeletedTasksObjects(""); + setAddedJournalsObjects(""); + setChangedJournalsObjects(""); + setDeletedJournalsObjects(""); } protected: virtual int runJob(runtime_info* caldavRuntime); virtual int runTasksJob(runtime_info* caldavRuntime); + virtual int runJournalsJob(runtime_info* caldavRuntime); virtual void cleanJob(); virtual void cleanTasksJob(); + virtual void cleanJournalsJob(); /// Just a wrapper above libcaldav event writing functions. template @@ -139,6 +171,16 @@ protected: return r; } + /// Just a wrapper above libcaldav journal writing functions. + template + int pushJournalsObjects(const TQString& 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(journalsUrl().ascii()).c_str(), RT); +// } + return r; + } + private: TQString mAdded; @@ -148,6 +190,10 @@ private: TQString mTasksAdded; TQString mTasksChanged; TQString mTasksDeleted; + + TQString mJournalsAdded; + TQString mJournalsChanged; + TQString mJournalsDeleted; }; } // namespace KCal -- cgit v1.2.1