summaryrefslogtreecommitdiffstats
path: root/kresources
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-09-01 00:37:02 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-09-01 00:37:02 +0000
commitcc29364f06178f8f6b457384f2ec37a042bd9d43 (patch)
tree7c77a3184c698bbf9d98cef09fb1ba8124daceba /kresources
parent4f6c584bacc8c3c694228f36ada3de77a76614a6 (diff)
downloadtdepim-cc29364f06178f8f6b457384f2ec37a042bd9d43.tar.gz
tdepim-cc29364f06178f8f6b457384f2ec37a042bd9d43.zip
* 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
Diffstat (limited to 'kresources')
-rw-r--r--kresources/Makefile.am2
-rw-r--r--kresources/birthdays/kabc.desktop1
-rw-r--r--kresources/birthdays/resourcekabc.cpp60
-rw-r--r--kresources/birthdays/resourcekabc.h10
-rw-r--r--kresources/blogging/blogging.desktop1
-rw-r--r--kresources/blogging/kcal_resourceblogging.cpp6
-rw-r--r--kresources/caldav/config.cpp38
-rw-r--r--kresources/caldav/config.h3
-rw-r--r--kresources/caldav/job.cpp31
-rw-r--r--kresources/caldav/job.h64
-rw-r--r--kresources/caldav/preferences.cpp29
-rw-r--r--kresources/caldav/preferences.h5
-rw-r--r--kresources/caldav/prefsskel.kcfg10
-rw-r--r--kresources/caldav/reader.cpp39
-rw-r--r--kresources/caldav/reader.h10
-rw-r--r--kresources/caldav/resource.cpp142
-rw-r--r--kresources/caldav/resource.h23
-rw-r--r--kresources/caldav/writer.cpp37
-rw-r--r--kresources/caldav/writer.h46
-rw-r--r--kresources/egroupware/kabc_resourcexmlrpc.cpp5
-rw-r--r--kresources/egroupware/kabc_xmlrpc.desktop1
-rw-r--r--kresources/egroupware/kcal_resourcexmlrpc.cpp5
-rw-r--r--kresources/egroupware/kcal_xmlrpc.desktop1
-rw-r--r--kresources/egroupware/knotes_resourcexmlrpc.cpp5
-rw-r--r--kresources/egroupware/knotes_xmlrpc.desktop1
-rw-r--r--kresources/exchange/exchange.desktop1
-rw-r--r--kresources/exchange/exchange_deprecated.desktop1
-rw-r--r--kresources/exchange/resourceexchange.cpp36
-rw-r--r--kresources/exchange/resourceexchange.h10
-rw-r--r--kresources/groupware/kabc_groupware.desktop1
-rw-r--r--kresources/groupware/kabc_resourcegroupware.cpp2
-rw-r--r--kresources/groupware/kcal_groupware.desktop1
-rw-r--r--kresources/groupware/kcal_resourcegroupware.cpp6
-rw-r--r--kresources/kolab/kabc/contact.cpp72
-rw-r--r--kresources/kolab/kabc/contact.h7
-rw-r--r--kresources/kolab/kabc/kolab.desktop1
-rw-r--r--kresources/kolab/kabc/resourcekolab.cpp64
-rw-r--r--kresources/kolab/kabc/resourcekolab.h3
-rw-r--r--kresources/kolab/kcal/event.cpp7
-rw-r--r--kresources/kolab/kcal/incidence.cpp248
-rw-r--r--kresources/kolab/kcal/incidence.h9
-rw-r--r--kresources/kolab/kcal/kolab.desktop1
-rw-r--r--kresources/kolab/kcal/resourcekolab.cpp437
-rw-r--r--kresources/kolab/kcal/resourcekolab.h64
-rw-r--r--kresources/kolab/kcal/task.cpp171
-rw-r--r--kresources/kolab/kcal/task.h16
-rw-r--r--kresources/kolab/knotes/kolabresource.desktop1
-rw-r--r--kresources/kolab/knotes/note.cpp41
-rw-r--r--kresources/kolab/knotes/resourcekolab.cpp92
-rw-r--r--kresources/kolab/knotes/resourcekolab.h3
-rw-r--r--kresources/kolab/shared/kmailconnection.cpp40
-rw-r--r--kresources/kolab/shared/kolabbase.cpp19
-rw-r--r--kresources/kolab/shared/resourcekolabbase.cpp38
-rw-r--r--kresources/kolab/shared/resourcekolabbase.h12
-rw-r--r--kresources/lib/addressbookadaptor.cpp16
-rw-r--r--kresources/lib/folderselectdialog.cpp7
-rw-r--r--kresources/lib/folderselectdialog.h1
-rw-r--r--kresources/lib/kcal_resourcegroupwarebase.cpp40
-rw-r--r--kresources/newexchange/exchangeconvertercontact.cpp122
-rw-r--r--kresources/newexchange/kabc_newexchange.desktop1
-rw-r--r--kresources/newexchange/kabc_newexchange_final.desktop1
-rw-r--r--kresources/newexchange/kabc_resourceexchange.cpp8
-rw-r--r--kresources/newexchange/kcal_newexchange.desktop1
-rw-r--r--kresources/newexchange/kcal_newexchange_final.desktop1
-rw-r--r--kresources/newexchange/kcal_resourceexchange.cpp7
-rw-r--r--kresources/remote/remote.desktop1
-rw-r--r--kresources/remote/resourceremote.cpp2
-rw-r--r--kresources/scalix/kcal/resourcescalix.cpp18
-rw-r--r--kresources/scalix/kcal/resourcescalix.h3
-rw-r--r--kresources/slox/kabc_ox.desktop1
-rw-r--r--kresources/slox/kabc_slox.desktop1
-rw-r--r--kresources/slox/kabcresourceslox.cpp11
-rw-r--r--kresources/slox/kcal_ox.desktop1
-rw-r--r--kresources/slox/kcal_slox.desktop1
-rw-r--r--kresources/slox/kcalresourceslox.cpp2
75 files changed, 1760 insertions, 465 deletions
diff --git a/kresources/Makefile.am b/kresources/Makefile.am
index eb217869..1ae15a7d 100644
--- a/kresources/Makefile.am
+++ b/kresources/Makefile.am
@@ -1,5 +1,5 @@
if include_exchange_SUBDIR
-EXCHANGE_SUBDIR=exchange
+EXCHANGE_SUBDIR=exchange
endif
SUBDIRS = lib remote egroupware $(EXCHANGE_SUBDIR) kolab slox groupwise featureplan groupdav birthdays newexchange scalix caldav carddav
diff --git a/kresources/birthdays/kabc.desktop b/kresources/birthdays/kabc.desktop
index aec8d565..cea676fa 100644
--- a/kresources/birthdays/kabc.desktop
+++ b/kresources/birthdays/kabc.desktop
@@ -28,7 +28,6 @@ Name[hu]=Születésnapok a KAddressBookból
Name[is]=Afmælisdagar úr KAddressBook
Name[it]=Compleanni da KAddessBook
Name[ja]=アドレス帳の誕生日
-Name[ka]=დაბადების დღეები KDE წიგნაკიდან
Name[kk]=KAddressBook-тағы туған күндер
Name[km]=ថ្ងៃ​ខួប​កំណើត​ពី KAddressBook
Name[lt]=Gimtadieniai iš KAddressBook
diff --git a/kresources/birthdays/resourcekabc.cpp b/kresources/birthdays/resourcekabc.cpp
index dc902c5b..65830782 100644
--- a/kresources/birthdays/resourcekabc.cpp
+++ b/kresources/birthdays/resourcekabc.cpp
@@ -46,6 +46,8 @@
#include "libkcal/filestorage.h"
#include "libkcal/alarm.h"
+#include <libemailfunctions/email.h>
+
#include <kresources/configwidget.h>
#include "resourcekabcconfig.h"
@@ -70,6 +72,8 @@ ResourceKABC::ResourceKABC( const KConfig* config )
{
if ( config ) {
readConfig( config );
+ } else {
+ setResourceName( i18n( "Birthdays" ) );
}
init();
@@ -227,7 +231,8 @@ bool ResourceKABC::doLoad()
bool found = false;
for ( addrIt = anniversaries.begin(); addrIt != anniversaries.end(); ++addrIt ) {
if ( name == (*addrIt).realName() ) {
- TQDateTime spouseAnniversary = TQDate::fromString( (*addrIt).custom( "KADDRESSBOOK", "X-Anniversary" ), Qt::ISODate );
+ TQDate spouseAnniversary =
+ TQDate::fromString( (*addrIt).custom( "KADDRESSBOOK", "X-Anniversary" ), Qt::ISODate );
if ( anniversary == spouseAnniversary ) {
found = true;
break;
@@ -255,22 +260,30 @@ bool ResourceKABC::doLoad()
TQString spouseName = (*addrIt).custom( "KADDRESSBOOK", "X-SpousesName" );
TQString name_2,email_2,uid_2;
if ( !spouseName.isEmpty() ) {
- //TODO: find a KABC:Addressee of the spouse
- // Probably easiest would be to use a TQMap (as the spouse's entry was already searched above!
+ TQString tname, temail;
+ KPIM::getNameAndMail( spouseName, tname, temail );
+ tname = KPIM::quoteNameIfNecessary( tname );
+ if ( ( tname[0] == '"' ) && ( tname[tname.length() - 1] == '"' ) ) {
+ tname.remove( 0, 1 );
+ tname.truncate( tname.length() - 1 );
+ }
KABC::Addressee spouse;
- spouse.setNameFromString( spouseName );
+ spouse.setNameFromString( tname );
+ name_2 = spouse.nickName();
uid_2 = spouse.uid();
email_2 = spouse.fullEmail();
- name_2 = spouse.nickName();
- if ( name_2.isEmpty() )
- name_2 = spouse.givenName();
- summary = i18n("insert names of both spouses", "%1's & %2's anniversary").arg( name_1 ).arg( name_2 );
+ if ( name_2.isEmpty() ) {
+ name_2 = spouse.realName();
+ }
+ summary = i18n("insert names of both spouses",
+ "%1's & %2's anniversary").arg( name_1 ).arg( name_2 );
} else {
- summary = i18n("only one spouse in addressbook, insert the name", "%1's anniversary").arg( name_1 );
+ summary = i18n("only one spouse in addressbook, insert the name",
+ "%1's anniversary").arg( name_1 );
}
Event *ev = new Event();
- ev->setUid( uid_1+"_KABC_Anniversary" );
+ ev->setUid( uid_1+"_KABC_Anniversary" );
ev->setDtStart(anniversary);
ev->setDtEnd(anniversary);
@@ -378,12 +391,17 @@ KABC::Lock *ResourceKABC::lock()
}
-bool ResourceKABC::addEvent(Event*)
+bool ResourceKABC::addEvent( Event * )
+{
+ return false;
+}
+
+bool ResourceKABC::addEvent( Event *, const TQString & )
{
return false;
}
-bool ResourceKABC::deleteEvent(Event*)
+bool ResourceKABC::deleteEvent( Event * )
{
return false;
}
@@ -417,12 +435,17 @@ Event::List ResourceKABC::rawEvents( EventSortField sortField, SortDirection sor
return mCalendar.rawEvents( sortField, sortDirection );
}
-bool ResourceKABC::addTodo(Todo*)
+bool ResourceKABC::addTodo( Todo * )
{
return false;
}
-bool ResourceKABC::deleteTodo(Todo*)
+bool ResourceKABC::addTodo( Todo *, const TQString & )
+{
+ return false;
+}
+
+bool ResourceKABC::deleteTodo( Todo * )
{
return false;
}
@@ -444,12 +467,17 @@ Todo::List ResourceKABC::rawTodosForDate( const TQDate &date )
}
-bool ResourceKABC::addJournal(Journal*)
+bool ResourceKABC::addJournal( Journal * )
+{
+ return false;
+}
+
+bool ResourceKABC::addJournal( Journal *, const TQString & )
{
return false;
}
-bool ResourceKABC::deleteJournal(Journal*)
+bool ResourceKABC::deleteJournal( Journal * )
{
return false;
}
diff --git a/kresources/birthdays/resourcekabc.h b/kresources/birthdays/resourcekabc.h
index eebe087e..9dedd0ab 100644
--- a/kresources/birthdays/resourcekabc.h
+++ b/kresources/birthdays/resourcekabc.h
@@ -76,7 +76,8 @@ class KDE_EXPORT ResourceKABC : public ResourceCalendar
KABC::Lock *lock();
/** Add Event to calendar. */
- bool addEvent(Event *anEvent);
+ KDE_DEPRECATED bool addEvent(Event *event);
+ bool addEvent( Event *event, const TQString &subresource );
/** deletes an event from this calendar. */
bool deleteEvent(Event *);
@@ -107,7 +108,8 @@ class KDE_EXPORT ResourceKABC : public ResourceCalendar
/**
Add a todo to the todolist.
*/
- bool addTodo( Todo *todo );
+ KDE_DEPRECATED bool addTodo( Todo *todo );
+ bool addTodo( Todo *todo, const TQString &subresource );
/**
Remove a todo from the todolist.
*/
@@ -126,7 +128,9 @@ class KDE_EXPORT ResourceKABC : public ResourceCalendar
*/
Todo::List rawTodosForDate( const TQDate &date );
/** Add a Journal entry to calendar */
- virtual bool addJournal(Journal *);
+ KDE_DEPRECATED bool addJournal( Journal *journal );
+ bool addJournal( Journal *journal, const TQString &subresource );
+
/** Remove journal from the calendar. */
bool deleteJournal( Journal * );
/** Return Journal with given UID */
diff --git a/kresources/blogging/blogging.desktop b/kresources/blogging/blogging.desktop
index 061b0634..23b367a9 100644
--- a/kresources/blogging/blogging.desktop
+++ b/kresources/blogging/blogging.desktop
@@ -19,7 +19,6 @@ Name[hu]=Naplók blogként tárolása a kiszolgálón
Name[is]=Dagbækur sem blogg á þjóni
Name[it]=Diari come blog su un server
Name[ja]=サーバ上のブログとしてのジャーナル
-Name[ka]=ბლოგისმაგვარი ჟურნალები სერვერზე
Name[kk]=Сервердегі күнделік блог ретінде
Name[km]=ទិនានុប្បវត្តិ​ជា​កំណត់ហេតុ​បណ្ដាញ​នៅ​លើ​ម៉ាស៊ីន​បម្រើ
Name[lt]=Dienynai kaip Blog'ai serveryje
diff --git a/kresources/blogging/kcal_resourceblogging.cpp b/kresources/blogging/kcal_resourceblogging.cpp
index 6f7ed46e..07d097db 100644
--- a/kresources/blogging/kcal_resourceblogging.cpp
+++ b/kresources/blogging/kcal_resourceblogging.cpp
@@ -38,7 +38,11 @@ ResourceBlogging::ResourceBlogging( const KConfig *config )
: ResourceGroupwareBase( config )
{
init();
- if ( config ) readConfig( config );
+ if ( config ) {
+ readConfig( config );
+ } else {
+ setResourceName( i18n( "Blogs" ) );
+ }
}
void ResourceBlogging::init()
diff --git a/kresources/caldav/config.cpp b/kresources/caldav/config.cpp
index 550e00c9..84a4798c 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 746c87ac..78067428 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 6edfbbfe..8e49041f 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 bad00c98..928e3814 100644
--- a/kresources/caldav/job.h
+++ b/kresources/caldav/job.h
@@ -61,6 +61,13 @@ public:
}
/**
+ * Sets a new Journals URL to load.
+ */
+ virtual void setJournalsUrl(const TQString& s) {
+ mJournalsUrl = s;
+ }
+
+ /**
* Sets the parent qobject.
*/
virtual void setParent(TQObject *s) {
@@ -89,6 +96,13 @@ public:
}
/**
+ * @return Journals URL to load.
+ */
+ virtual TQString journalsUrl() const {
+ return mJournalsUrl;
+ }
+
+ /**
* @return parent object
*/
virtual TQObject *parent() {
@@ -117,6 +131,13 @@ public:
}
/**
+ * @return true if journals downloading process failed.
+ */
+ virtual bool journalsError() const {
+ return mJournalsError;
+ }
+
+ /**
* @return an event error string.
*/
virtual TQString errorString() const {
@@ -131,6 +152,13 @@ public:
}
/**
+ * @return a journal error string.
+ */
+ virtual TQString journalsErrorString() const {
+ return mJournalsErrorString;
+ }
+
+ /**
* @return an event error number.
*/
virtual long errorNumber() const {
@@ -144,6 +172,13 @@ public:
return mTasksErrorNumber;
}
+ /**
+ * @return a journal error number.
+ */
+ virtual long journalsErrorNumber() const {
+ return mJournalsErrorNumber;
+ }
+
protected:
virtual void run();
@@ -167,6 +202,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.
*/
virtual void cleanJob() {
@@ -176,6 +220,9 @@ protected:
mTasksError = false;
mTasksErrorString = "";
mTasksErrorNumber = 0;
+ mJournalsError = false;
+ mJournalsErrorString = "";
+ mJournalsErrorNumber = 0;
}
/**
@@ -189,6 +236,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
* should be done. Call setErrorString() to set the error after processing is done.
@@ -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 d70a3519..6eb87e45 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 666b8ccf..98245e6b 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 bb05a75f..7a72dd6b 100644
--- a/kresources/caldav/prefsskel.kcfg
+++ b/kresources/caldav/prefsskel.kcfg
@@ -14,8 +14,18 @@
<label>URL</label>
</entry>
+ <entry key="JournalsUrl" type="String" >
+ <label>URL</label>
+ </entry>
+
<entry key="UseSTasks" type="Bool" >
<label>Use separate Tasks URL</label>
+ <default>false</default>
+ </entry>
+
+ <entry key="UseSJournals" type="Bool" >
+ <label>Use separate Journals URL</label>
+ <default>false</default>
</entry>
<entry key="Username" type="String">
diff --git a/kresources/caldav/reader.cpp b/kresources/caldav/reader.cpp
index a7956fe6..892b490c 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 b62a5931..9bcc8c87 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 c0bbf115..003633a4 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("<b>") + i18n("Remote authorization required") + TQString("</b><p>") + 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 bb69807b..033a19ce 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 e939f3d9..a466322e 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 3b8f82a8..437eeed0 100644
--- a/kresources/caldav/writer.h
+++ b/kresources/caldav/writer.h
@@ -82,6 +82,15 @@ public:
}
/**
+ * 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.
* May be an empty string, which means there are no changed tasks to send.
@@ -91,6 +100,15 @@ public:
}
/**
+ * 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.
* May be an empty string, which means there are no deleted tasks to send.
@@ -100,6 +118,15 @@ public:
}
/**
+ * 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.
*/
void clearObjects() {
@@ -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<typename Operation>
@@ -139,6 +171,16 @@ protected:
return r;
}
+ /// Just a wrapper above libcaldav journal writing functions.
+ template<typename Operation>
+ 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
diff --git a/kresources/egroupware/kabc_resourcexmlrpc.cpp b/kresources/egroupware/kabc_resourcexmlrpc.cpp
index ee1e74be..115484c6 100644
--- a/kresources/egroupware/kabc_resourcexmlrpc.cpp
+++ b/kresources/egroupware/kabc_resourcexmlrpc.cpp
@@ -64,8 +64,11 @@ ResourceXMLRPC::ResourceXMLRPC( const KConfig *config )
mPrefs->addGroupPrefix( identifier() );
- if ( config )
+ if ( config ) {
mPrefs->readConfig();
+ } else {
+ setResourceName( i18n( "eGroupware Server" ) );
+ }
initEGroupware();
}
diff --git a/kresources/egroupware/kabc_xmlrpc.desktop b/kresources/egroupware/kabc_xmlrpc.desktop
index c7386a59..d7f8d5d6 100644
--- a/kresources/egroupware/kabc_xmlrpc.desktop
+++ b/kresources/egroupware/kabc_xmlrpc.desktop
@@ -20,7 +20,6 @@ Name[hu]=eGroupware-kiszolgáló (XML-RPC-n keresztül)
Name[is]=eGroupware þjónn (gegnum XML-RPC)
Name[it]=Server eGroupware (via XML-RPC)
Name[ja]=eGroupware サーバ (XML-RPC 経由)
-Name[ka]=სერბერი eGroupware (XML-RPC-ის საშუალებით)
Name[kk]=eGroupware сервері (XML-RPC арқылы)
Name[km]=ម៉ាស៊ីន​បម្រើ eGroupware (តាម​រយៈ XML-RPC)
Name[lt]=eGroupware serveris (per XML-RPC)
diff --git a/kresources/egroupware/kcal_resourcexmlrpc.cpp b/kresources/egroupware/kcal_resourcexmlrpc.cpp
index bb92b2d5..9072b166 100644
--- a/kresources/egroupware/kcal_resourcexmlrpc.cpp
+++ b/kresources/egroupware/kcal_resourcexmlrpc.cpp
@@ -110,8 +110,11 @@ ResourceXMLRPC::ResourceXMLRPC( const KConfig* config )
mPrefs->addGroupPrefix( identifier() );
- if ( config )
+ if ( config ) {
readConfig( config );
+ } else {
+ setResourceName( i18n( "eGroupware Server" ) );
+ }
initEGroupware();
}
diff --git a/kresources/egroupware/kcal_xmlrpc.desktop b/kresources/egroupware/kcal_xmlrpc.desktop
index 5480d86b..93a54217 100644
--- a/kresources/egroupware/kcal_xmlrpc.desktop
+++ b/kresources/egroupware/kcal_xmlrpc.desktop
@@ -20,7 +20,6 @@ Name[hu]=eGroupware-kiszolgáló (XML-RPC-n keresztül)
Name[is]=eGroupware þjónn (gegnum XML-RPC)
Name[it]=Server eGroupware (via XML-RPC)
Name[ja]=eGroupware サーバ (XML-RPC 経由)
-Name[ka]=სერბერი eGroupware (XML-RPC-ის საშუალებით)
Name[kk]=eGroupware сервері (XML-RPC арқылы)
Name[km]=ម៉ាស៊ីន​បម្រើ eGroupware (តាម​រយៈ XML-RPC)
Name[lt]=eGroupware serveris (per XML-RPC)
diff --git a/kresources/egroupware/knotes_resourcexmlrpc.cpp b/kresources/egroupware/knotes_resourcexmlrpc.cpp
index b0bdb5b0..774115d2 100644
--- a/kresources/egroupware/knotes_resourcexmlrpc.cpp
+++ b/kresources/egroupware/knotes_resourcexmlrpc.cpp
@@ -57,8 +57,11 @@ ResourceXMLRPC::ResourceXMLRPC( const KConfig* config )
mPrefs->addGroupPrefix( identifier() );
- if ( config )
+ if ( config ) {
readConfig( config );
+ } else {
+ setResourceName( i18n( "eGroupware Server" ) );
+ }
}
ResourceXMLRPC::ResourceXMLRPC( )
diff --git a/kresources/egroupware/knotes_xmlrpc.desktop b/kresources/egroupware/knotes_xmlrpc.desktop
index 61411ce0..b3f4faa6 100644
--- a/kresources/egroupware/knotes_xmlrpc.desktop
+++ b/kresources/egroupware/knotes_xmlrpc.desktop
@@ -20,7 +20,6 @@ Name[hu]=eGroupware-kiszolgáló (XML-RPC-n keresztül)
Name[is]=eGroupware þjónn (gegnum XML-RPC)
Name[it]=Server eGroupware (via XML-RPC)
Name[ja]=eGroupware サーバ (XML-RPC 経由)
-Name[ka]=სერბერი eGroupware (XML-RPC-ის საშუალებით)
Name[kk]=eGroupware сервері (XML-RPC арқылы)
Name[km]=ម៉ាស៊ីន​បម្រើ eGroupware (តាម​រយៈ XML-RPC)
Name[lt]=eGroupware serveris (per XML-RPC)
diff --git a/kresources/exchange/exchange.desktop b/kresources/exchange/exchange.desktop
index 9342e3ba..5bfe8a1e 100644
--- a/kresources/exchange/exchange.desktop
+++ b/kresources/exchange/exchange.desktop
@@ -26,7 +26,6 @@ Name[hu]=Exchange 2000-kiszolgáló
Name[is]=Exchange 2000 þjónn
Name[it]=Server Exchange 2000
Name[ja]=Exchange 2000 サーバ
-Name[ka]=სერვერი Exchange 2000
Name[kk]=MS Exchange 2000 сервері
Name[km]=ម៉ាស៊ីន​បម្រើ Exchange ២០០០
Name[lt]=Exchange 2000 serveris
diff --git a/kresources/exchange/exchange_deprecated.desktop b/kresources/exchange/exchange_deprecated.desktop
index 70ffbc63..eba22eed 100644
--- a/kresources/exchange/exchange_deprecated.desktop
+++ b/kresources/exchange/exchange_deprecated.desktop
@@ -21,7 +21,6 @@ Name[hu]=Exchange 2000-kiszolgáló (elavult)
Name[is]=Exchange 2000 þjónn (úrelt)
Name[it]=Server Exchange 2000 (deprecato)
Name[ja]=Exchange 2000 サーバ (廃止予定)
-Name[ka]=სერვერი Exchange 2000 (მოძველებული)
Name[kk]=MS Exchange 2000 сервері (ескірген)
Name[km]=ម៉ាស៊ីន​បម្រើ Exchange ២០០០ (មិន​សូវ​ល្អ)
Name[lt]=Exchange 2000 serveris (deprecated)
diff --git a/kresources/exchange/resourceexchange.cpp b/kresources/exchange/resourceexchange.cpp
index 8e877f9b..82c0ab07 100644
--- a/kresources/exchange/resourceexchange.cpp
+++ b/kresources/exchange/resourceexchange.cpp
@@ -91,6 +91,7 @@ ResourceExchange::ResourceExchange( const KConfig *config )
mCachedSeconds = config->readNumEntry( "ExchangeCacheTimeout", 600 );
mAutoMailbox = config->readBoolEntry( "ExchangeAutoMailbox", true );
} else {
+ setResourceName( i18n( "Exchange Server" ) );
mAccount = new ExchangeAccount( "", "", "", "" );
mCachedSeconds = 600;
}
@@ -248,19 +249,26 @@ void ResourceExchange::slotMonitorError( int errorCode, const TQString& moreInfo
}
-bool ResourceExchange::addEvent(Event *anEvent)
+bool ResourceExchange::addEvent( Event *event )
{
+ return addEvent( event, TQString() );
+}
+
+bool ResourceExchange::addEvent( Event *event, const TQString &subresource )
+{
+ Q_UNUSED( subresource ); //subresources are not supported
+
if( !mCache ) return false;
kdDebug() << "ResourceExchange::addEvent" << endl;
// FIXME: first check of upload finished successfully, only then
// add to cache
- mCache->addEvent( anEvent );
+ mCache->addEvent( event );
- uploadEvent( anEvent );
-// insertEvent(anEvent);
+ uploadEvent( event );
+// insertEvent( event );
- anEvent->registerObserver( this );
+ event->registerObserver( this );
// setModified( true );
return true;
@@ -341,8 +349,14 @@ void ResourceExchange::unsubscribeEvents( const TQDate &/*start*/, const TQDate
kdDebug() << "ResourceExchange::unsubscribeEvents()" << endl;
}
-bool ResourceExchange::addTodo(Todo */*todo*/)
+bool ResourceExchange::addTodo( Todo *todo )
+{
+ return addTodo( todo, TQString() );
+}
+
+bool ResourceExchange::addTodo( Todo */*todo*/, const TQString &subresource )
{
+ Q_UNUSED( subresource ); //subresources are not supported
// This resource doesn't handle todos yet!
return false;
/* if( !mCache)
@@ -356,6 +370,7 @@ bool ResourceExchange::addTodo(Todo */*todo*/)
return true;*/
}
+
bool ResourceExchange::deleteTodo(Todo */*todo*/)
{
// We don't handle todos yet
@@ -530,8 +545,15 @@ Event::List ResourceExchange::rawEvents( EventSortField sortField, SortDirection
return mCache->rawEvents( sortField, sortDirection );
}
-bool ResourceExchange::addJournal(Journal */*journal*/)
+bool ResourceExchange::addJournal( Journal *journal )
+{
+ return addJournal( journal, TQString() );
+}
+
+bool ResourceExchange::addJournal( Journal */*journal*/, const TQString &subresource )
{
+ Q_UNUSED( subresource ); //subresources are not supported
+
// This resource doesn't handle journals yet
return false;
/* kdDebug(5800) << "Adding Journal on " << journal->dtStart().toString() << endl;
diff --git a/kresources/exchange/resourceexchange.h b/kresources/exchange/resourceexchange.h
index d3492cf0..7328a27b 100644
--- a/kresources/exchange/resourceexchange.h
+++ b/kresources/exchange/resourceexchange.h
@@ -83,7 +83,9 @@ class ResourceExchange : public ResourceCalendar, public IncidenceBase::Observer
// void close();
/** Add Event to calendar. */
- bool addEvent(Event *anEvent);
+ KDE_DEPRECATED bool addEvent( Event *event );
+ bool addEvent( Event *event, const TQString &subresource );
+
/** deletes an event from this calendar. */
bool deleteEvent(Event *);
@@ -118,7 +120,8 @@ class ResourceExchange : public ResourceCalendar, public IncidenceBase::Observer
/**
Add a todo to the todolist.
*/
- bool addTodo( Todo *todo );
+ KDE_DEPRECATED bool addTodo( Todo *todo );
+ bool addTodo( Todo *todo, const TQString &subresource );
/**
Remove a todo from the todolist.
*/
@@ -138,7 +141,8 @@ class ResourceExchange : public ResourceCalendar, public IncidenceBase::Observer
Todo::List rawTodosForDate( const TQDate &date );
/** Add a Journal entry to calendar */
- virtual bool addJournal(Journal *);
+ KDE_DEPRECATED bool addJournal( Journal *journal );
+ bool addJournal( Journal *journal, const TQString &subresource );
/** deletes an event from this calendar. */
virtual bool deleteJournal(Journal *);
/** Return Journals for given date */
diff --git a/kresources/groupware/kabc_groupware.desktop b/kresources/groupware/kabc_groupware.desktop
index 6750248b..f2c56b26 100644
--- a/kresources/groupware/kabc_groupware.desktop
+++ b/kresources/groupware/kabc_groupware.desktop
@@ -20,7 +20,6 @@ Name[hu]=Groupware kiszolgáló
Name[is]=Groupware þjónn
Name[it]=Server Groupware
Name[ja]=グループウェアサーバ
-Name[ka]=სერვერი Groupware
Name[kk]=Groupware сервері
Name[km]=ម៉ាស៊ីន​បម្រើ​កម្មវិធី​ពហុ​អ្នកប្រើ
Name[lt]=Grupinio darbo serveris
diff --git a/kresources/groupware/kabc_resourcegroupware.cpp b/kresources/groupware/kabc_resourcegroupware.cpp
index c04988aa..c9fef7a0 100644
--- a/kresources/groupware/kabc_resourcegroupware.cpp
+++ b/kresources/groupware/kabc_resourcegroupware.cpp
@@ -43,6 +43,8 @@ ResourceGroupware::ResourceGroupware( const KConfig *config )
if ( config ) {
readConfig( config );
+ } else {
+ setResourceName( i18n( "Groupware Server" ) );
}
}
diff --git a/kresources/groupware/kcal_groupware.desktop b/kresources/groupware/kcal_groupware.desktop
index 0b43536b..9692900d 100644
--- a/kresources/groupware/kcal_groupware.desktop
+++ b/kresources/groupware/kcal_groupware.desktop
@@ -20,7 +20,6 @@ Name[hu]=Groupware kiszolgáló
Name[is]=Groupware þjónn
Name[it]=Server Groupware
Name[ja]=グループウェアサーバ
-Name[ka]=სერვერი Groupware
Name[kk]=Groupware сервері
Name[km]=ម៉ាស៊ីន​បម្រើ​កម្មវិធី​ពហុ​អ្នកប្រើ
Name[lt]=Grupinio darbo serveris
diff --git a/kresources/groupware/kcal_resourcegroupware.cpp b/kresources/groupware/kcal_resourcegroupware.cpp
index b651d739..01a51684 100644
--- a/kresources/groupware/kcal_resourcegroupware.cpp
+++ b/kresources/groupware/kcal_resourcegroupware.cpp
@@ -62,7 +62,11 @@ ResourceGroupware::ResourceGroupware( const KConfig *config )
mPrefs->addGroupPrefix( identifier() );
- if ( config ) readConfig( config );
+ if ( config ) {
+ readConfig( config );
+ } else {
+ setResourceName( i18n( "Groupware Server" ) );
+ }
}
ResourceGroupware::~ResourceGroupware()
diff --git a/kresources/kolab/kabc/contact.cpp b/kresources/kolab/kabc/contact.cpp
index fc908731..26a91e67 100644
--- a/kresources/kolab/kabc/contact.cpp
+++ b/kresources/kolab/kabc/contact.cpp
@@ -35,6 +35,7 @@
#include <kabc/addressee.h>
#include <kabc/stdaddressbook.h>
+#include <libkcal/freebusyurlstore.h>
#include <libkdepim/distributionlist.h>
#include <kio/netaccess.h>
#include <kdebug.h>
@@ -222,15 +223,15 @@ TQString Contact::profession() const
return mProfession;
}
-// void Contact::setJobTitle( const TQString& title )
-// {
-// mJobTitle = title;
-// }
+void Contact::setJobTitle( const TQString& title )
+{
+ mJobTitle = title;
+}
-// TQString Contact::jobTitle() const
-// {
-// return mJobTitle;
-// }
+TQString Contact::jobTitle() const
+{
+ return mJobTitle;
+}
void Contact::setManagerName( const TQString& name )
{
@@ -485,6 +486,11 @@ void Contact::saveCustomAttributes( TQDomElement& element ) const
if ( (*it).app == s_unhandledTagAppName ) {
writeString( element, (*it).name, (*it).value );
} else {
+ // skip writing the freebusyurl as it is a hack we need to remove eventually
+ if ( (*it).name == TQString::fromLatin1( "FreeBusyURL" ) ) {
+ continue;
+ }
+
// Let's use attributes so that other tag-preserving-code doesn't need sub-elements
TQDomElement e = element.ownerDocument().createElement( "x-custom" );
element.appendChild( e );
@@ -659,7 +665,7 @@ bool Contact::loadAttribute( TQDomElement& element )
case 'j':
if ( tagName == "job-title" ) {
// see saveAttributes: <job-title> is mapped to the Role field
- setRole( element.text() );
+ setJobTitle( element.text() );
return true;
}
break;
@@ -766,7 +772,6 @@ bool Contact::saveAttributes( TQDomElement& element ) const
{
// Save the base class elements
KolabBase::saveAttributes( element );
-
if ( mIsDistributionList ) {
writeString( element, "display-name", fullName() );
saveDistrListMembers( element );
@@ -779,11 +784,8 @@ bool Contact::saveAttributes( TQDomElement& element ) const
writeString( element, "department", department() );
writeString( element, "office-location", officeLocation() );
writeString( element, "profession", profession() );
- // <role> is gone; jobTitle() is not shown in the addresseeeditor,
- // so let's bind <job-title> to role()
- //writeString( element, "role", role() );
- //writeString( element, "job-title", jobTitle() );
- writeString( element, "job-title", role() );
+ writeString( element, "role", role() );
+ writeString( element, "job-title", jobTitle() );
writeString( element, "manager-name", managerName() );
writeString( element, "assistant", assistant() );
writeString( element, "nick-name", nickName() );
@@ -891,28 +893,28 @@ static TQStringList phoneTypeToString( int /*KABC::PhoneNumber::Types*/ type )
type = type & ~KABC::PhoneNumber::Work;
}
- // To support both "home1" and "home2", map Home+Pref to home1
+ // To support both "home1" and "home2", map Home+Pref to home2
if ( ( type & KABC::PhoneNumber::Home ) && ( type & KABC::PhoneNumber::Pref ) )
{
- types << "home1";
+ types << "home2";
type = type & ~KABC::PhoneNumber::Home;
type = type & ~KABC::PhoneNumber::Pref;
}
- // To support both "business1" and "business2", map Work+Pref to business1
+ // To support both "business1" and "business2", map Work+Pref to business2
if ( ( type & KABC::PhoneNumber::Work ) && ( type & KABC::PhoneNumber::Pref ) )
{
- types << "business1";
+ types << "business2";
type = type & ~KABC::PhoneNumber::Work;
type = type & ~KABC::PhoneNumber::Pref;
}
if ( type & KABC::PhoneNumber::Home )
- types << "home2";
+ types << "home1";
if ( type & KABC::PhoneNumber::Msg ) // Msg==messaging
types << "company";
if ( type & KABC::PhoneNumber::Work )
- types << "business2";
+ types << "business1";
if ( type & KABC::PhoneNumber::Pref )
types << "primary";
if ( type & KABC::PhoneNumber::Voice )
@@ -942,13 +944,13 @@ static int /*KABC::PhoneNumber::Types*/ phoneTypeFromString( const TQString& typ
return KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax;
if ( type == "businessfax" )
return KABC::PhoneNumber::Work | KABC::PhoneNumber::Fax;
- if ( type == "business1" )
- return KABC::PhoneNumber::Work | KABC::PhoneNumber::Pref;
if ( type == "business2" )
+ return KABC::PhoneNumber::Work | KABC::PhoneNumber::Pref;
+ if ( type == "business1" )
return KABC::PhoneNumber::Work;
- if ( type == "home1" )
- return KABC::PhoneNumber::Home | KABC::PhoneNumber::Pref;
if ( type == "home2" )
+ return KABC::PhoneNumber::Home | KABC::PhoneNumber::Pref;
+ if ( type == "home1" )
return KABC::PhoneNumber::Home;
if ( type == "company" )
return KABC::PhoneNumber::Msg;
@@ -1019,11 +1021,15 @@ void Contact::setFields( const KABC::Addressee* addressee )
setOrganization( addressee->organization() );
setWebPage( addressee->url().url() );
setIMAddress( addressee->custom( "KADDRESSBOOK", "X-IMAddress" ) );
+#if KDE_IS_VERSION(3,5,8)
+ setDepartment( addressee->department());
+#else
setDepartment( addressee->custom( "KADDRESSBOOK", "X-Department" ) );
+#endif
setOfficeLocation( addressee->custom( "KADDRESSBOOK", "X-Office" ) );
setProfession( addressee->custom( "KADDRESSBOOK", "X-Profession" ) );
setRole( addressee->role() );
- //setJobTitle( addressee->title() );
+ setJobTitle( addressee->title() );
setManagerName( addressee->custom( "KADDRESSBOOK", "X-ManagersName" ) );
setAssistant( addressee->custom( "KADDRESSBOOK", "X-AssistantsName" ) );
setNickName( addressee->nickName() );
@@ -1129,6 +1135,11 @@ void Contact::setFields( const KABC::Addressee* addressee )
}
}
+ TQString url = KCal::FreeBusyUrlStore::self()->readUrl( addressee->preferredEmail() );
+ if ( !url.isEmpty() ) {
+ setFreeBusyUrl( url );
+ }
+
// Those fields, although defined in Addressee, are not used in KDE
// (e.g. not visible in kaddressbook/addresseeeditorwidget.cpp)
// So it doesn't matter much if we don't have them in the XML.
@@ -1136,9 +1147,6 @@ void Contact::setFields( const KABC::Addressee* addressee )
// Things KAddressBook can't handle, so they are saved as unhandled tags:
// initials, children, gender, language
-
- // TODO: Free/Busy URL. This is done rather awkward in KAddressBook -
- // it stores it in a local file through a korganizer file :-(
}
// The loading is: xml -> Contact -> addressee, this is the second part
@@ -1173,11 +1181,15 @@ void Contact::saveTo( KABC::Addressee* addressee )
addressee->setOrganization( organization() );
addressee->setUrl( webPage() );
addressee->insertCustom( "KADDRESSBOOK", "X-IMAddress", imAddress() );
+#if KDE_IS_VERSION(3,5,8)
+ addressee->setDepartment( department() );
+#else
addressee->insertCustom( "KADDRESSBOOK", "X-Department", department() );
+#endif
addressee->insertCustom( "KADDRESSBOOK", "X-Office", officeLocation() );
addressee->insertCustom( "KADDRESSBOOK", "X-Profession", profession() );
addressee->setRole( role() );
- //addressee->setTitle( jobTitle() );
+ addressee->setTitle( jobTitle() );
addressee->insertCustom( "KADDRESSBOOK", "X-ManagersName", managerName() );
addressee->insertCustom( "KADDRESSBOOK", "X-AssistantsName", assistant() );
addressee->setNickName( nickName() );
diff --git a/kresources/kolab/kabc/contact.h b/kresources/kolab/kabc/contact.h
index 39a235cc..a9465642 100644
--- a/kresources/kolab/kabc/contact.h
+++ b/kresources/kolab/kabc/contact.h
@@ -121,9 +121,8 @@ public:
void setProfession( const TQString& profession );
TQString profession() const;
- // not shown in the kaddressbook GUI
- //void setJobTitle( const TQString& title );
- //TQString jobTitle() const;
+ void setJobTitle( const TQString& title );
+ TQString jobTitle() const;
void setManagerName( const TQString& name );
TQString managerName() const;
@@ -245,7 +244,7 @@ private:
TQString mDepartment;
TQString mOfficeLocation;
TQString mProfession;
- //TQString mJobTitle;
+ TQString mJobTitle;
TQString mManagerName;
TQString mAssistant;
TQString mNickName;
diff --git a/kresources/kolab/kabc/kolab.desktop b/kresources/kolab/kabc/kolab.desktop
index d75090a7..8339f9c2 100644
--- a/kresources/kolab/kabc/kolab.desktop
+++ b/kresources/kolab/kabc/kolab.desktop
@@ -21,7 +21,6 @@ Name[hu]=IMAP-kiszolgálón tárolt címjegyzék a KMailen keresztül
Name[is]=Vistfangaskrá á IMAP þjóni gegnum KMail
Name[it]=Rubrica indirizzi su server IMAP via KMail
Name[ja]=KMail 経由 IMAP サーバのアドレス帳
-Name[ka]=წიგნაკი IMAP-ის სერვერზე KMail-ის საშუალებით
Name[kk]=KMail арқылы IMAP серверіндегі адрестік кітапша
Name[km]=សៀវភៅ​អាសយដ្ឋាន​លើ​ម៉ាស៊ីន​បម្រើ IMAP តាម​រយៈ KMail
Name[lt]=Adresų knygelė IMAP serveryje per KMail
diff --git a/kresources/kolab/kabc/resourcekolab.cpp b/kresources/kolab/kabc/resourcekolab.cpp
index 034c32d7..ae8e225f 100644
--- a/kresources/kolab/kabc/resourcekolab.cpp
+++ b/kresources/kolab/kabc/resourcekolab.cpp
@@ -79,9 +79,12 @@ static const char* s_inlineMimeType = "text/x-vcard";
KABC::ResourceKolab::ResourceKolab( const KConfig *config )
: KPIM::ResourceABC( config ),
Kolab::ResourceKolabBase( "ResourceKolab-KABC" ),
- mCachedSubresource( TQString::null ), mLocked( false )
+ mCachedSubresource( TQString::null ), mCachedSubresourceNotFound( false ), mLocked( false )
{
setType( "imap" );
+ if ( !config ) {
+ setResourceName( i18n( "Kolab Server" ) );
+ }
}
KABC::ResourceKolab::~ResourceKolab()
@@ -124,14 +127,7 @@ bool KABC::ResourceKolab::doOpen()
void KABC::ResourceKolab::doClose()
{
- KConfig config( configFile() );
-
- Kolab::ResourceMap::ConstIterator it;
- for ( it = mSubResources.begin(); it != mSubResources.end(); ++it ) {
- config.setGroup( it.key() );
- config.writeEntry( "Active", it.data().active() );
- config.writeEntry( "CompletionWeight", it.data().completionWeight() );
- }
+ writeConfig();
}
KABC::Ticket * KABC::ResourceKolab::requestSaveTicket()
@@ -149,6 +145,7 @@ void KABC::ResourceKolab::releaseSaveTicket( Ticket* ticket )
{
mLocked = false;
mCachedSubresource = TQString::null;
+ mCachedSubresourceNotFound = false;
delete ticket;
}
@@ -163,7 +160,11 @@ TQString KABC::ResourceKolab::loadContact( const TQString& contactData,
contact.saveTo( &addr );
} else {
KABC::VCardConverter converter;
+#if defined(KABC_VCARD_ENCODING_FIX)
+ addr = converter.parseVCardRaw( contactData.utf8() );
+#else
addr = converter.parseVCard( contactData );
+#endif
}
addr.setResource( this );
@@ -301,11 +302,11 @@ void AttachmentList::updatePictureAttachment( const TQImage& image, const TQStri
{
assert( !name.isEmpty() );
if ( !image.isNull() ) {
- KTempFile* tempFile = new KTempFile;
- image.save( tempFile->file(), "PNG" );
- tempFile->close();
+ KTempFile tempFile;
+ image.save( tempFile.file(), "PNG" );
+ tempFile.close();
KURL url;
- url.setPath( tempFile->name() );
+ url.setPath( tempFile.name() );
kdDebug(5650) << "picture saved to " << url.path() << endl;
addAttachment( url.url(), name, "image/png" );
} else {
@@ -317,11 +318,11 @@ void AttachmentList::updateAttachment( const TQByteArray& data, const TQString&
{
assert( !name.isEmpty() );
if ( !data.isNull() ) {
- KTempFile* tempFile = new KTempFile;
- tempFile->file()->writeBlock( data );
- tempFile->close();
+ KTempFile tempFile;
+ tempFile.file()->writeBlock( data );
+ tempFile.close();
KURL url;
- url.setPath( tempFile->name() );
+ url.setPath( tempFile.name() );
kdDebug(5650) << "data saved to " << url.path() << endl;
addAttachment( url.url(), name, mimetype );
} else {
@@ -342,14 +343,20 @@ bool KABC::ResourceKolab::kmailUpdateAddressee( const Addressee& addr )
}
sernum = mUidMap[ uid ].serialNumber();
} else {
- if ( !mCachedSubresource.isNull() ) {
+ if ( !mCachedSubresource.isNull() || mCachedSubresourceNotFound ) {
subResource = mCachedSubresource;
} else {
- subResource = findWritableResource( mSubResources );
+ subResource = findWritableResource( Kolab::Contacts, mSubResources );
// We were locked, remember the subresource we are working with until
// we are unlocked
- if ( mLocked )
+ if ( mLocked ) {
mCachedSubresource = subResource;
+
+ // If the subresource is empty here, it means findWritableResource() failed, for example
+ // because the user cancelled the resource selection dialog. Remember that, so we avoid
+ // asking multiple times when locked.
+ mCachedSubresourceNotFound = subResource.isEmpty();
+ }
}
if ( subResource.isEmpty() )
return false;
@@ -374,7 +381,11 @@ bool KABC::ResourceKolab::kmailUpdateAddressee( const Addressee& addr )
} else {
mimetype = s_inlineMimeType;
KABC::VCardConverter converter;
+#if defined(KABC_VCARD_ENCODING_FIX)
+ data = TQString::fromUtf8( converter.createVCardRaw( addr ) );
+#else
data = converter.createVCard( addr );
+#endif
subject.prepend( "vCard " ); // as per kolab1 spec
}
bool rc = kmailUpdate( subResource, sernum, data, mimetype, subject,
@@ -652,6 +663,7 @@ void KABC::ResourceKolab::setSubresourceActive( const TQString &subresource, boo
} else {
kdDebug(5650) << "setSubresourceCompletionWeight: subresource " << subresource << " not found" << endl;
}
+ writeConfig();
}
@@ -667,4 +679,16 @@ bool KABC::ResourceKolab::removeSubresource( const TQString& id )
return kmailRemoveSubresource( id );
}
+void KABC::ResourceKolab::writeConfig()
+{
+ KConfig config( configFile() );
+
+ Kolab::ResourceMap::ConstIterator it;
+ for ( it = mSubResources.constBegin(); it != mSubResources.constEnd(); ++it ) {
+ config.setGroup( it.key() );
+ config.writeEntry( "Active", it.data().active() );
+ config.writeEntry( "CompletionWeight", it.data().completionWeight() );
+ }
+}
+
#include "resourcekolab.moc"
diff --git a/kresources/kolab/kabc/resourcekolab.h b/kresources/kolab/kabc/resourcekolab.h
index 1da47201..9158375a 100644
--- a/kresources/kolab/kabc/resourcekolab.h
+++ b/kresources/kolab/kabc/resourcekolab.h
@@ -164,9 +164,12 @@ protected:
return Kolab::ResourceKolabBase::configFile( "kabc" );
}
+ void writeConfig();
+
// The list of subresources
Kolab::ResourceMap mSubResources;
TQString mCachedSubresource;
+ bool mCachedSubresourceNotFound;
bool mLocked;
};
diff --git a/kresources/kolab/kcal/event.cpp b/kresources/kolab/kcal/event.cpp
index 0f25eb73..e1d58a13 100644
--- a/kresources/kolab/kcal/event.cpp
+++ b/kresources/kolab/kcal/event.cpp
@@ -190,7 +190,9 @@ void Event::setFields( const KCal::Event* event )
{
Incidence::setFields( event );
- if ( event->hasEndDate() ) {
+ // note: if hasEndDate() is false and hasDuration() is true
+ // dtEnd() returns start+duration
+ if ( event->hasEndDate() || event->hasDuration() ) {
if ( event->doesFloat() ) {
// This is a floating event. Don't timezone move this one
mFloatingStatus = AllDay;
@@ -199,8 +201,9 @@ void Event::setFields( const KCal::Event* event )
mFloatingStatus = HasTime;
setEndDate( localToUTC( event->dtEnd() ) );
}
- } else
+ } else {
mHasEndDate = false;
+ }
setTransparency( event->transparency() );
}
diff --git a/kresources/kolab/kcal/incidence.cpp b/kresources/kolab/kcal/incidence.cpp
index 74f41fd8..de076eb9 100644
--- a/kresources/kolab/kcal/incidence.cpp
+++ b/kresources/kolab/kcal/incidence.cpp
@@ -39,6 +39,8 @@
#include <libkcal/journal.h>
#include <korganizer/version.h>
+#include <libemailfunctions/email.h>
+
#include <kdebug.h>
#include <kmdcodec.h>
#include <kurl.h>
@@ -50,7 +52,6 @@ using namespace Kolab;
Incidence::Incidence( KCal::ResourceKolab *res, const TQString &subResource, Q_UINT32 sernum,
const TQString& tz )
: KolabBase( tz ), mFloatingStatus( Unset ), mHasAlarm( false ),
- mRevision( 0 ),
mResource( res ),
mSubResource( subResource ),
mSernum( sernum )
@@ -163,16 +164,6 @@ TQString Incidence::internalUID() const
return mInternalUID;
}
-void Incidence::setRevision( int revision )
-{
- mRevision = revision;
-}
-
-int Incidence::revision() const
-{
- return mRevision;
-}
-
bool Incidence::loadAttendeeAttribute( TQDomElement& element,
Attendee& attendee )
{
@@ -183,8 +174,16 @@ bool Incidence::loadAttendeeAttribute( TQDomElement& element,
TQDomElement e = n.toElement();
TQString tagName = e.tagName();
- if ( tagName == "display-name" )
- attendee.displayName = e.text();
+ if ( tagName == "display-name" ) {
+ // Quote the text in case it contains commas or other quotable chars.
+ TQString tusername = KPIM::quoteNameIfNecessary( e.text() );
+
+ TQString tname, temail;
+ // ignore the return value because it will always be false since
+ // tusername does not contain "@domain".
+ KPIM::getNameAndMail( tusername, tname, temail );
+ attendee.displayName = tname;
+ }
else if ( tagName == "smtp-address" )
attendee.smtpAddress = e.text();
else if ( tagName == "status" )
@@ -249,6 +248,69 @@ void Incidence::saveAttachments( TQDomElement& element ) const
}
}
+void Incidence::saveAlarms( TQDomElement& element ) const
+{
+ if ( mAlarms.isEmpty() ) return;
+
+ TQDomElement list = element.ownerDocument().createElement( "advanced-alarms" );
+ element.appendChild( list );
+ for ( KCal::Alarm::List::ConstIterator it = mAlarms.constBegin(); it != mAlarms.constEnd(); ++it ) {
+ KCal::Alarm* a = *it;
+ TQDomElement e = list.ownerDocument().createElement( "alarm" );
+ list.appendChild( e );
+
+ writeString( e, "enabled", a->enabled() ? "1" : "0" );
+ if ( a->hasStartOffset() ) {
+ writeString( e, "start-offset", TQString::number( a->startOffset().asSeconds()/60 ) );
+ }
+ if ( a->hasEndOffset() ) {
+ writeString( e, "end-offset", TQString::number( a->endOffset().asSeconds()/60 ) );
+ }
+ if ( a->repeatCount() ) {
+ writeString( e, "repeat-count", TQString::number( a->repeatCount() ) );
+ writeString( e, "repeat-interval", TQString::number( a->snoozeTime() ) );
+ }
+
+ switch ( a->type() ) {
+ case KCal::Alarm::Invalid:
+ break;
+ case KCal::Alarm::Display:
+ e.setAttribute( "type", "display" );
+ writeString( e, "text", a->text() );
+ break;
+ case KCal::Alarm::Procedure:
+ e.setAttribute( "type", "procedure" );
+ writeString( e, "program", a->programFile() );
+ writeString( e, "arguments", a->programArguments() );
+ break;
+ case KCal::Alarm::Email:
+ {
+ e.setAttribute( "type", "email" );
+ TQDomElement addresses = e.ownerDocument().createElement( "addresses" );
+ e.appendChild( addresses );
+ for ( TQValueList<KCal::Person>::ConstIterator it = a->mailAddresses().constBegin(); it != a->mailAddresses().constEnd(); ++it ) {
+ writeString( addresses, "address", (*it).fullName() );
+ }
+ writeString( e, "subject", a->mailSubject() );
+ writeString( e, "mail-text", a->mailText() );
+ TQDomElement attachments = e.ownerDocument().createElement( "attachments" );
+ e.appendChild( attachments );
+ for ( TQStringList::ConstIterator it = a->mailAttachments().constBegin(); it != a->mailAttachments().constEnd(); ++it ) {
+ writeString( attachments, "attachment", *it );
+ }
+ break;
+ }
+ case KCal::Alarm::Audio:
+ e.setAttribute( "type", "audio" );
+ writeString( e, "file", a->audioFile() );
+ break;
+ default:
+ kdWarning() << "Unhandled alarm type:" << a->type() << endl;
+ break;
+ }
+ }
+}
+
void Incidence::saveRecurrence( TQDomElement& element ) const
{
TQDomElement e = element.ownerDocument().createElement( "recurrence" );
@@ -289,8 +351,14 @@ void Incidence::loadRecurrence( const TQDomElement& element )
TQDomElement e = n.toElement();
TQString tagName = e.tagName();
- if ( tagName == "interval" )
- mRecurrence.interval = e.text().toInt();
+ if ( tagName == "interval" ) {
+ //kolab/issue4229, sometimes the interval value can be empty
+ if ( e.text().isEmpty() || e.text().toInt() <= 0 ) {
+ mRecurrence.interval = 1;
+ } else {
+ mRecurrence.interval = e.text().toInt();
+ }
+ }
else if ( tagName == "day" ) // can be present multiple times
mRecurrence.days.append( e.text() );
else if ( tagName == "daynumber" )
@@ -309,6 +377,118 @@ void Incidence::loadRecurrence( const TQDomElement& element )
}
}
+static void loadAddressesHelper( const TQDomElement& element, KCal::Alarm* a )
+{
+ for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ if ( n.isComment() )
+ continue;
+ if ( n.isElement() ) {
+ TQDomElement e = n.toElement();
+ TQString tagName = e.tagName();
+
+ if ( tagName == "address" ) {
+ a->addMailAddress( KCal::Person( e.text() ) );
+ } else {
+ kdWarning() << "Unhandled tag" << tagName << endl;
+ }
+ }
+ }
+}
+
+static void loadAttachmentsHelper( const TQDomElement& element, KCal::Alarm* a )
+{
+ for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ if ( n.isComment() )
+ continue;
+ if ( n.isElement() ) {
+ TQDomElement e = n.toElement();
+ TQString tagName = e.tagName();
+
+ if ( tagName == "attachment" ) {
+ a->addMailAttachment( e.text() );
+ } else {
+ kdWarning() << "Unhandled tag" << tagName << endl;
+ }
+ }
+ }
+}
+
+static void loadAlarmHelper( const TQDomElement& element, KCal::Alarm* a )
+{
+ for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ if ( n.isComment() )
+ continue;
+ if ( n.isElement() ) {
+ TQDomElement e = n.toElement();
+ TQString tagName = e.tagName();
+
+ if ( tagName == "start-offset" ) {
+ a->setStartOffset( e.text().toInt()*60 );
+ } else if ( tagName == "end-offset" ) {
+ a->setEndOffset( e.text().toInt()*60 );
+ } else if ( tagName == "repeat-count" ) {
+ a->setRepeatCount( e.text().toInt() );
+ } else if ( tagName == "repeat-interval" ) {
+ a->setSnoozeTime( e.text().toInt() );
+ } else if ( tagName == "text" ) {
+ a->setText( e.text() );
+ } else if ( tagName == "program" ) {
+ a->setProgramFile( e.text() );
+ } else if ( tagName == "arguments" ) {
+ a->setProgramArguments( e.text() );
+ } else if ( tagName == "addresses" ) {
+ loadAddressesHelper( e, a );
+ } else if ( tagName == "subject" ) {
+ a->setMailSubject( e.text() );
+ } else if ( tagName == "mail-text" ) {
+ a->setMailText( e.text() );
+ } else if ( tagName == "attachments" ) {
+ loadAttachmentsHelper( e, a );
+ } else if ( tagName == "file" ) {
+ a->setAudioFile( e.text() );
+ } else if ( tagName == "enabled" ) {
+ a->setEnabled( e.text().toInt() != 0 );
+ } else {
+ kdWarning() << "Unhandled tag" << tagName << endl;
+ }
+ }
+ }
+}
+
+void Incidence::loadAlarms( const TQDomElement& element )
+{
+ for ( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() ) {
+ if ( n.isComment() )
+ continue;
+ if ( n.isElement() ) {
+ TQDomElement e = n.toElement();
+ TQString tagName = e.tagName();
+
+ if ( tagName == "alarm" ) {
+ KCal::Alarm *a = new KCal::Alarm( 0 );
+ a->setEnabled( true ); // default to enabled, unless some XML attribute says otherwise.
+ TQString type = e.attribute( "type" );
+ if ( type == "display" ) {
+ a->setType( KCal::Alarm::Display );
+ } else if ( type == "procedure" ) {
+ a->setType( KCal::Alarm::Procedure );
+ } else if ( type == "email" ) {
+ a->setType( KCal::Alarm::Email );
+ } else if ( type == "audio" ) {
+ a->setType( KCal::Alarm::Audio );
+ } else {
+ kdWarning() << "Unhandled alarm type:" << type << endl;
+ }
+
+ loadAlarmHelper( e, a );
+ mAlarms << a;
+ } else {
+ kdWarning() << "Unhandled tag" << tagName << endl;
+ }
+ }
+ }
+}
+
bool Incidence::loadAttribute( TQDomElement& element )
{
TQString tagName = element.tagName();
@@ -340,20 +520,17 @@ bool Incidence::loadAttribute( TQDomElement& element )
} else if ( tagName == "alarm" )
// Alarms should be minutes before. Libkcal uses event time + alarm time
setAlarm( - element.text().toInt() );
+ else if ( tagName == "advanced-alarms" )
+ loadAlarms( element );
else if ( tagName == "x-kde-internaluid" )
setInternalUID( element.text() );
- else if ( tagName == "revision" ) {
- bool ok;
- int revision = element.text().toInt( &ok );
- if ( ok )
- setRevision( revision );
- } else if ( tagName == "x-custom" )
+ else if ( tagName == "x-custom" )
loadCustomAttributes( element );
else {
bool ok = KolabBase::loadAttribute( element );
if ( !ok ) {
// Unhandled tag - save for later storage
- kdDebug() << "Saving unhandled tag " << element.tagName() << endl;
+ //kdDebug() << "Saving unhandled tag " << element.tagName() << endl;
Custom c;
c.key = TQCString( "X-KDE-KolabUnhandled-" ) + element.tagName().latin1();
c.value = element.text();
@@ -385,8 +562,8 @@ bool Incidence::saveAttributes( TQDomElement& element ) const
int alarmTime = qRound( -alarm() );
writeString( element, "alarm", TQString::number( alarmTime ) );
}
+ saveAlarms( element );
writeString( element, "x-kde-internaluid", internalUID() );
- writeString( element, "revision", TQString::number( revision() ) );
saveCustomAttributes( element );
return true;
}
@@ -424,13 +601,15 @@ static KCal::Attendee::PartStat attendeeStringToStatus( const TQString& s )
return KCal::Attendee::NeedsAction;
if ( s == "tentative" )
return KCal::Attendee::Tentative;
+ if ( s == "accepted" )
+ return KCal::Attendee::Accepted;
if ( s == "declined" )
return KCal::Attendee::Declined;
if ( s == "delegated" )
return KCal::Attendee::Delegated;
// Default:
- return KCal::Attendee::Accepted;
+ return KCal::Attendee::None;
}
static TQString attendeeStatusToString( KCal::Attendee::PartStat status )
@@ -649,6 +828,14 @@ void Incidence::setFields( const KCal::Incidence* incidence )
mAttachments.push_back( a );
}
+ mAlarms.clear();
+
+ // Alarms
+ const KCal::Alarm::List alarms = incidence->alarms();
+ for ( KCal::Alarm::List::ConstIterator it = alarms.begin(); it != alarms.end(); ++it ) {
+ mAlarms.push_back( *it );
+ }
+
if ( incidence->doesRecur() ) {
setRecurrence( incidence->recurrence() );
mRecurrence.exclusions = incidence->recurrence()->exDates();
@@ -711,10 +898,17 @@ void Incidence::saveTo( KCal::Incidence* incidence )
incidence->setSummary( summary() );
incidence->setLocation( location() );
- if ( mHasAlarm ) {
+ if ( mHasAlarm && mAlarms.isEmpty() ) {
KCal::Alarm* alarm = incidence->newAlarm();
alarm->setStartOffset( qRound( mAlarm * 60.0 ) );
alarm->setEnabled( true );
+ alarm->setType( KCal::Alarm::Display );
+ } else if ( !mAlarms.isEmpty() ) {
+ for ( KCal::Alarm::List::ConstIterator it = mAlarms.constBegin(); it != mAlarms.constEnd(); ++it ) {
+ KCal::Alarm *alarm = *it;
+ alarm->setParent( incidence );
+ incidence->addAlarm( alarm );
+ }
}
if ( organizer().displayName.isEmpty() )
@@ -803,7 +997,7 @@ void Incidence::saveTo( KCal::Incidence* incidence )
if ( hasPilotSyncStatus() )
incidence->setSyncStatus( pilotSyncStatus() );
- for( TQValueList<Custom>::ConstIterator it = mCustomList.begin(); it != mCustomList.end(); ++it ) {
+ for( TQValueList<Custom>::ConstIterator it = mCustomList.constBegin(); it != mCustomList.constEnd(); ++it ) {
incidence->setNonKDECustomProperty( (*it).key, (*it).value );
}
@@ -836,7 +1030,7 @@ void Incidence::loadAttachments()
TQString Incidence::productID() const
{
- return TQString( "KOrganizer " ) + korgVersion + ", Kolab resource";
+ return TQString( "KOrganizer %1, Kolab resource" ).arg( korgVersion );
}
// Unhandled KCal::Incidence fields:
diff --git a/kresources/kolab/kcal/incidence.h b/kresources/kolab/kcal/incidence.h
index 32b112aa..582d34c3 100644
--- a/kresources/kolab/kcal/incidence.h
+++ b/kresources/kolab/kcal/incidence.h
@@ -41,6 +41,7 @@ class TQDomElement;
namespace KCal {
class Incidence;
class Recurrence;
+ class Alarm;
class Attachment;
class ResourceKolab;
}
@@ -115,9 +116,6 @@ public:
void setInternalUID( const TQString& iuid );
TQString internalUID() const;
- virtual void setRevision( int );
- virtual int revision() const;
-
// Load the attributes of this class
virtual bool loadAttribute( TQDomElement& );
@@ -136,6 +134,9 @@ protected:
void saveAttendees( TQDomElement& element ) const;
void saveAttachments( TQDomElement& element ) const;
+ void loadAlarms( const TQDomElement& element );
+ void saveAlarms( TQDomElement& element ) const;
+
void loadRecurrence( const TQDomElement& element );
void saveRecurrence( TQDomElement& element ) const;
void saveCustomAttributes( TQDomElement& element ) const;
@@ -154,9 +155,9 @@ protected:
bool mHasAlarm;
Recurrence mRecurrence;
TQValueList<Attendee> mAttendees;
+ TQValueList<KCal::Alarm*> mAlarms;
TQValueList<KCal::Attachment*> mAttachments;
TQString mInternalUID;
- int mRevision;
struct Custom {
TQCString key;
diff --git a/kresources/kolab/kcal/kolab.desktop b/kresources/kolab/kcal/kolab.desktop
index 579e6406..c0a7daa5 100644
--- a/kresources/kolab/kcal/kolab.desktop
+++ b/kresources/kolab/kcal/kolab.desktop
@@ -21,7 +21,6 @@ Name[hu]=IMAP-kiszolgálón tárolt naptár a KMailen keresztül
Name[is]=Dagatal á IMAP þjóni gegnum KMail
Name[it]=Calendario su server IMAP via KMail
Name[ja]=KMail 経由 IMAP サーバのカレンダー
-Name[ka]=კალენდარი IMAP სერვერზე KMail-ის საშუალებით
Name[kk]=KMail арқылы IMAP серверіндегі күнтізбе
Name[km]=ប្រតិទិន​លើ​ម៉ាស៊ីន​បម្រើ IMAP តាម​រយៈ KMail
Name[lt]=Kalendorius IMAP serveryje per KMail
diff --git a/kresources/kolab/kcal/resourcekolab.cpp b/kresources/kolab/kcal/resourcekolab.cpp
index b61b1211..1f5f486f 100644
--- a/kresources/kolab/kcal/resourcekolab.cpp
+++ b/kresources/kolab/kcal/resourcekolab.cpp
@@ -41,7 +41,6 @@
#include <kio/uiserver_stub.h>
#include <kapplication.h>
#include <dcopclient.h>
-#include <libkcal/icalformat.h>
#include <libkdepim/kincidencechooser.h>
#include <kabc/locknull.h>
#include <kmainwindow.h>
@@ -72,8 +71,11 @@ static const char* incidenceInlineMimeType = "text/calendar";
ResourceKolab::ResourceKolab( const KConfig *config )
: ResourceCalendar( config ), ResourceKolabBase( "ResourceKolab-libkcal" ),
mCalendar( TQString::fromLatin1("UTC") ), mOpen( false ),mResourceChangedTimer( 0,
- "mResourceChangedTimer" )
+ "mResourceChangedTimer" ), mBatchAddingInProgress( false )
{
+ if ( !config ) {
+ setResourceName( i18n( "Kolab Server" ) );
+ }
setType( "imap" );
connect( &mResourceChangedTimer, TQT_SIGNAL( timeout() ),
this, TQT_SLOT( slotEmitResourceChanged() ) );
@@ -132,7 +134,7 @@ bool ResourceKolab::doOpen()
&& openResource( config, kmailJournalContentsType, mJournalSubResources );
}
-static void closeResource( KConfig& config, ResourceMap& map )
+static void writeResourceConfig( KConfig& config, ResourceMap& map )
{
ResourceMap::ConstIterator it;
for ( it = map.begin(); it != map.end(); ++it ) {
@@ -148,10 +150,7 @@ void ResourceKolab::doClose()
return;
mOpen = false;
- KConfig config( configFile() );
- closeResource( config, mEventSubResources );
- closeResource( config, mTodoSubResources );
- closeResource( config, mJournalSubResources );
+ writeConfig();
}
bool ResourceKolab::loadSubResource( const TQString& subResource,
@@ -217,11 +216,20 @@ bool ResourceKolab::loadSubResource( const TQString& subResource,
bool ResourceKolab::doLoad()
{
if (!mUidMap.isEmpty() ) {
+ emit resourceLoaded( this );
return true;
}
mUidMap.clear();
- return loadAllEvents() & loadAllTodos() & loadAllJournals();
+ bool result = loadAllEvents() & loadAllTodos() & loadAllJournals();
+ if ( result ) {
+ emit resourceLoaded( this );
+ } else {
+ // FIXME: anyone know if the resource correctly calls loadError()
+ // if it has one?
+ }
+
+ return result;
}
bool ResourceKolab::doLoadAll( ResourceMap& map, const char* mimetype )
@@ -297,19 +305,54 @@ bool ResourceKolab::doSave()
&& kmailTriggerSync( kmailJournalContentsType );
*/
}
-void ResourceKolab::incidenceUpdatedSilent( KCal::IncidenceBase* incidencebase)
+void ResourceKolab::incidenceUpdatedSilent( KCal::IncidenceBase* incidencebase )
{
- const TQString uid = incidencebase->uid();
+ const TQString uid = incidencebase->uid();
//kdDebug() << k_funcinfo << uid << endl;
if ( mUidsPendingUpdate.contains( uid ) || mUidsPendingAdding.contains( uid ) ) {
/* We are currently processing this event ( removing and readding or
* adding it ). If so, ignore this update. Keep the last of these around
* and process once we hear back from KMail on this event. */
- mPendingUpdates.replace( uid, incidencebase );
+ mPendingUpdates.remove( uid );
+ mPendingUpdates.insert( uid, incidencebase );
return;
}
+ { // start optimization
+ /**
+ KOrganizer and libkcal like calling two Incidence::updated()
+ for only one user change. That's because after a change,
+ IncidenceChanger calls incidence->setRevision( rev++ );
+ which also calls Incidence::updated().
+
+ Lets ignore the first updated() and only send to kmail
+ the second. This makes things faster.
+ */
+
+ //IncidenceBase doesn't have revision(), downcast needed.
+ Incidence *i = dynamic_cast<Incidence*>( incidencebase );
+
+ if ( i ) {
+ bool ignoreThisUpdate = false;
+
+ if ( !mLastKnownRevisions.contains( uid ) ) {
+ mLastKnownRevisions[uid] = i->revision();
+ }
+
+ // update the last known revision
+ if ( mLastKnownRevisions[uid] < i->revision() ) {
+ mLastKnownRevisions[uid] = i->revision();
+ } else {
+ ignoreThisUpdate = true;
+ }
+
+ if ( ignoreThisUpdate ) {
+ return;
+ }
+ }
+ } // end optimization
+
TQString subResource;
Q_UINT32 sernum = 0;
if ( mUidMap.contains( uid ) ) {
@@ -317,78 +360,85 @@ void ResourceKolab::incidenceUpdatedSilent( KCal::IncidenceBase* incidencebase)
sernum = mUidMap[ uid ].serialNumber();
mUidsPendingUpdate.append( uid );
}
- sendKMailUpdate( incidencebase, subResource, sernum );
+ sendKMailUpdate( incidencebase, subResource, sernum );
}
void ResourceKolab::incidenceUpdated( KCal::IncidenceBase* incidencebase )
{
- if ( incidencebase->isReadOnly() ) return;
+ if ( incidencebase->isReadOnly() ) {
+ return;
+ }
+
incidencebase->setSyncStatusSilent( KCal::Event::SYNCMOD );
incidencebase->setLastModified( TQDateTime::currentDateTime() );
+
// we should probably update the revision number here,
// or internally in the Event itself when certain things change.
// need to verify with ical documentation.
incidenceUpdatedSilent( incidencebase );
-
}
void ResourceKolab::resolveConflict( KCal::Incidence* inc, const TQString& subresource, Q_UINT32 sernum )
{
- if ( ! inc )
- return;
- if ( ! mResolveConflict ) {
- // we should do no conflict resolution
- delete inc;
- return;
- }
- const TQString origUid = inc->uid();
- Incidence* local = mCalendar.incidence( origUid );
- Incidence* localIncidence = 0;
- Incidence* addedIncidence = 0;
- Incidence* result = 0;
- if ( local ) {
- if (*local == *inc) {
- // real duplicate, remove the second one
- result = local;
- } else {
- KIncidenceChooser* ch = new KIncidenceChooser();
- ch->setIncidence( local ,inc );
- if ( KIncidenceChooser::chooseMode == KIncidenceChooser::ask ) {
- connect ( this, TQT_SIGNAL( useGlobalMode() ), ch, TQT_SLOT ( useGlobalMode() ) );
- if ( ch->exec() )
- if ( KIncidenceChooser::chooseMode != KIncidenceChooser::ask )
- emit useGlobalMode() ;
- }
- result = ch->getIncidence();
- delete ch;
- }
- } else {
- // nothing there locally, just take the new one. Can't Happen (TM)
- result = inc;
- }
- if ( result == local ) {
- delete inc;
- localIncidence = local;
- } else if ( result == inc ) {
- addedIncidence = inc;
- } else if ( result == 0 ) { // take both
- addedIncidence = inc;
- addedIncidence->setSummary( i18n("Copy of: %1").arg( addedIncidence->summary() ) );
- addedIncidence->setUid( CalFormat::createUniqueId() );
- localIncidence = local;
- }
- bool silent = mSilent;
- mSilent = false;
- if ( !localIncidence ) {
- deleteIncidence( local ); // remove local from kmail
- }
- mUidsPendingDeletion.append( origUid );
- if ( addedIncidence ) {
- sendKMailUpdate( addedIncidence, subresource, sernum );
- } else {
- kmailDeleteIncidence( subresource, sernum );// remove new from kmail
- }
- mSilent = silent;
+ if ( !inc ) {
+ return;
+ }
+
+ if ( !mResolveConflict ) {
+ // we should do no conflict resolution
+ delete inc;
+ return;
+ }
+ const TQString origUid = inc->uid();
+ Incidence* local = mCalendar.incidence( origUid );
+ Incidence* localIncidence = 0;
+ Incidence* addedIncidence = 0;
+ Incidence* result = 0;
+ if ( local ) {
+ if ( *local == *inc ) {
+ // real duplicate, remove the second one
+ result = local;
+ } else {
+ KIncidenceChooser* ch = new KIncidenceChooser();
+ ch->setIncidence( local ,inc );
+ if ( KIncidenceChooser::chooseMode == KIncidenceChooser::ask ) {
+ connect ( this, TQT_SIGNAL( useGlobalMode() ), ch, TQT_SLOT ( useGlobalMode() ) );
+ if ( ch->exec() ) {
+ if ( KIncidenceChooser::chooseMode != KIncidenceChooser::ask ) {
+ emit useGlobalMode() ;
+ }
+ }
+ }
+ result = ch->getIncidence();
+ delete ch;
+ }
+ } else {
+ // nothing there locally, just take the new one. Can't Happen (TM)
+ result = inc;
+ }
+ if ( result == local ) {
+ delete inc;
+ localIncidence = local;
+ } else if ( result == inc ) {
+ addedIncidence = inc;
+ } else if ( result == 0 ) { // take both
+ addedIncidence = inc;
+ addedIncidence->setSummary( i18n("Copy of: %1").arg( addedIncidence->summary() ) );
+ addedIncidence->setUid( CalFormat::createUniqueId() );
+ localIncidence = local;
+ }
+ const bool silent = mSilent;
+ mSilent = false;
+ if ( !localIncidence ) {
+ deleteIncidence( local ); // remove local from kmail
+ }
+ mUidsPendingDeletion.append( origUid );
+ if ( addedIncidence ) {
+ sendKMailUpdate( addedIncidence, subresource, sernum );
+ } else {
+ kmailDeleteIncidence( subresource, sernum );// remove new from kmail
+ }
+ mSilent = silent;
}
void ResourceKolab::addIncidence( const char* mimetype, const TQString& data,
const TQString& subResource, Q_UINT32 sernum )
@@ -457,15 +507,24 @@ bool ResourceKolab::sendKMailUpdate( KCal::IncidenceBase* incidencebase, const T
TQStringList attURLs, attMimeTypes, attNames;
TQValueList<KTempFile*> tmpFiles;
for ( KCal::Attachment::List::ConstIterator it = atts.constBegin(); it != atts.constEnd(); ++it ) {
- KTempFile* tempFile = new KTempFile;
- TQCString decoded = KCodecs::base64Decode( TQCString( (*it)->data() ) );
- tempFile->file()->writeBlock( decoded.data(), decoded.length() );
- tempFile->close();
- KURL url;
- url.setPath( tempFile->name() );
- attURLs.append( url.url() );
- attMimeTypes.append( (*it)->mimeType() );
- attNames.append( (*it)->label() );
+ if ( (*it)->isUri() ) {
+ continue;
+ }
+ KTempFile *tempFile = new KTempFile;
+ if ( tempFile->status() == 0 ) { // open ok
+ const TQByteArray decoded = (*it)->decodedData() ;
+
+ tempFile->file()->writeBlock( decoded.data(), decoded.count() );
+ KURL url;
+ url.setPath( tempFile->name() );
+ attURLs.append( url.url() );
+ attMimeTypes.append( (*it)->mimeType() );
+ attNames.append( (*it)->label() );
+ tempFile->close();
+ tmpFiles.append( tempFile );
+ } else {
+ kdWarning(5006) << "Cannot open temporary file for attachment";
+ }
}
TQStringList deletedAtts;
if ( kmailListAttachments( deletedAtts, subresource, sernum ) ) {
@@ -474,8 +533,9 @@ bool ResourceKolab::sendKMailUpdate( KCal::IncidenceBase* incidencebase, const T
}
}
CustomHeaderMap customHeaders;
- if ( incidence->schedulingID() != incidence->uid() )
+ if ( incidence->schedulingID() != incidence->uid() ) {
customHeaders.insert( "X-Kolab-SchedulingID", incidence->schedulingID() );
+ }
TQString subject = incidencebase->uid();
if ( !isXMLStorageFormat ) subject.prepend( "iCal " ); // conform to the old style
@@ -499,34 +559,49 @@ bool ResourceKolab::addIncidence( KCal::Incidence* incidence, const TQString& _s
Q_UINT32 sernum )
{
Q_ASSERT( incidence );
- if ( !incidence ) return false;
+ if ( !incidence ) {
+ return false;
+ }
+
+ kdDebug() << "Resourcekolab, adding incidence "
+ << incidence->summary()
+ << "; subresource = " << _subresource
+ << "; sernum = " << sernum
+ << "; mBatchAddingInProgress = " << mBatchAddingInProgress
+ << endl;
+
TQString uid = incidence->uid();
TQString subResource = _subresource;
Kolab::ResourceMap *map = &mEventSubResources; // don't use a ref here!
const TQString& type = incidence->type();
- if ( type == "Event" )
+ if ( type == "Event" ) {
map = &mEventSubResources;
- else if ( type == "Todo" )
+ } else if ( type == "Todo" ) {
map = &mTodoSubResources;
- else if ( type == "Journal" )
+ } else if ( type == "Journal" ) {
map = &mJournalSubResources;
- else
+ } else {
kdWarning() << "unknown type " << type << endl;
+ }
if ( !mSilent ) { /* We got this one from the user, tell KMail. */
// Find out if this event was previously stored in KMail
bool newIncidence = _subresource.isEmpty();
if ( newIncidence ) {
+ ResourceType type = Incidences;
// Add a description of the incidence
TQString text = "<b><font size=\"+1\">";
- if ( incidence->type() == "Event" )
+ if ( incidence->type() == "Event" ) {
+ type = Events;
text += i18n( "Choose the folder where you want to store this event" );
- else if ( incidence->type() == "Todo" )
+ } else if ( incidence->type() == "Todo" ) {
+ type = Tasks;
text += i18n( "Choose the folder where you want to store this task" );
- else
+ } else {
text += i18n( "Choose the folder where you want to store this incidence" );
+ }
text += "<font></b><br>";
if ( !incidence->summary().isEmpty() )
text += i18n( "<b>Summary:</b> %1" ).arg( incidence->summary() ) + "<br>";
@@ -541,24 +616,51 @@ bool ResourceKolab::addIncidence( KCal::Incidence* incidence, const TQString& _s
text += "<br>";
if ( incidence->type() == "Event" ) {
Event* event = static_cast<Event*>( incidence );
- if ( event->hasEndDate() )
- if ( !event->doesFloat() )
+ if ( event->hasEndDate() ) {
+ if ( !event->doesFloat() ) {
text += i18n( "<b>End:</b> %1, %2" )
.arg( event->dtEndDateStr(), event->dtEndTimeStr() );
- else
+ } else {
text += i18n( "<b>End:</b> %1" ).arg( event->dtEndDateStr() );
+ }
+ }
text += "<br>";
}
- subResource = findWritableResource( *map, text );
+
+ // Lets not warn the user 100 times that there's no writable resource
+ // and not ask 100 times which resource to use
+ if ( !mBatchAddingInProgress || !mLastUsedResources.contains( type ) ) {
+ subResource = findWritableResource( type, *map, text );
+ mLastUsedResources[type] = subResource;
+ } else {
+ subResource = mLastUsedResources[type];
+ }
+
+ if ( subResource.isEmpty() ) {
+ switch( mErrorCode ) {
+ case NoWritableFound:
+ setException( new ErrorFormat( ErrorFormat::NoWritableFound ) );
+ break;
+ case UserCancel:
+ setException( new ErrorFormat( ErrorFormat::UserCancel ) );
+ break;
+ case NoError:
+ break;
+ }
+ }
}
- if ( subResource.isEmpty() )
+ if ( subResource.isEmpty() ) {
+ endAddingIncidences(); // cleanup
+ kdDebug(5650) << "ResourceKolab: subResource is empty" << endl;
return false;
+ }
mNewIncidencesMap.insert( uid, subResource );
if ( !sendKMailUpdate( incidence, subResource, sernum ) ) {
kdError(5650) << "Communication problem in ResourceKolab::addIncidence()\n";
+ endAddingIncidences(); // cleanup
return false;
} else {
// KMail is doing it's best to add the event now, put a sticker on it,
@@ -568,13 +670,14 @@ bool ResourceKolab::addIncidence( KCal::Incidence* incidence, const TQString& _s
/* Add to the cache immediately if this is a new event coming from
* KOrganizer. It relies on the incidence being in the calendar when
* addIncidence returns. */
- if ( newIncidence ) {
+ if ( newIncidence || sernum == 0 ) {
mCalendar.addIncidence( incidence );
- incidence->registerObserver( this );
+ incidence->registerObserver( this );
}
}
} else { /* KMail told us */
- bool ourOwnUpdate = mUidsPendingUpdate.contains( uid );
+ const bool ourOwnUpdate = mUidsPendingUpdate.contains( uid );
+ kdDebug( 5650 ) << "addIncidence: ourOwnUpdate " << ourOwnUpdate << endl;
/* Check if we updated this one, which means kmail deleted and added it.
* We know the new state, so lets just not do much at all. The old incidence
* in the calendar remains valid, but the serial number changed, so we need to
@@ -592,6 +695,7 @@ bool ResourceKolab::addIncidence( KCal::Incidence* incidence, const TQString& _s
if ( mUidMap.contains( uid ) ) {
if ( mUidMap[ uid ].resource() == subResource ) {
if ( (*map)[ subResource ].writable() ) {
+ kdDebug( 5650 ) << "lets resolve the conflict " << endl;
resolveConflict( incidence, subResource, sernum );
} else {
kdWarning( 5650 ) << "Duplicate event in a read-only folder detected! "
@@ -601,8 +705,13 @@ bool ResourceKolab::addIncidence( KCal::Incidence* incidence, const TQString& _s
} else {
// duplicate uid in a different folder, do the internal-uid tango
incidence->setSchedulingID( uid );
- incidence->setUid(CalFormat::createUniqueId( ) );
+
+ incidence->setUid( CalFormat::createUniqueId( ) );
uid = incidence->uid();
+
+ /* Will be needed when kmail triggers a delete, so we don't delete the inocent
+ * incidence that's sharing the uid with this one */
+ mOriginalUID2fakeUID[qMakePair( incidence->schedulingID(), subResource )] = uid;
}
}
/* Add to the cache if the add didn't come from KOrganizer, in which case
@@ -636,13 +745,18 @@ bool ResourceKolab::addIncidence( KCal::Incidence* incidence, const TQString& _s
return true;
}
+bool ResourceKolab::addEvent( KCal::Event *event )
+{
+ return addEvent( event, TQString() );
+}
-bool ResourceKolab::addEvent( KCal::Event* event )
+bool ResourceKolab::addEvent( KCal::Event *event, const TQString &subResource )
{
- if ( mUidMap.contains( event->uid() ) )
+ if ( mUidMap.contains( event->uid() ) ) {
return true; //noop
- else
- return addIncidence( event, TQString::null, 0 );
+ } else {
+ return addIncidence( event, subResource, 0 );
+ }
}
void ResourceKolab::addEvent( const TQString& xml, const TQString& subresource,
@@ -650,14 +764,16 @@ void ResourceKolab::addEvent( const TQString& xml, const TQString& subresource,
{
KCal::Event* event = Kolab::Event::xmlToEvent( xml, mCalendar.timeZoneId(), this, subresource, sernum );
Q_ASSERT( event );
- if( event ) {
+ if ( event ) {
addIncidence( event, subresource, sernum );
}
}
bool ResourceKolab::deleteIncidence( KCal::Incidence* incidence )
{
- if ( incidence->isReadOnly() ) return false;
+ if ( incidence->isReadOnly() ) {
+ return false;
+ }
const TQString uid = incidence->uid();
if( !mUidMap.contains( uid ) ) return false; // Odd
@@ -709,12 +825,18 @@ KCal::Event::List ResourceKolab::rawEvents( const TQDate& start,
return mCalendar.rawEvents( start, end, inclusive );
}
-bool ResourceKolab::addTodo( KCal::Todo* todo )
+bool ResourceKolab::addTodo( KCal::Todo *todo )
{
- if ( mUidMap.contains( todo->uid() ) )
+ return addTodo( todo, TQString() );
+}
+
+bool ResourceKolab::addTodo( KCal::Todo *todo, const TQString &subResource )
+{
+ if ( mUidMap.contains( todo->uid() ) ) {
return true; //noop
- else
- return addIncidence( todo, TQString::null, 0 );
+ } else {
+ return addIncidence( todo, subResource, 0 );
+ }
}
void ResourceKolab::addTodo( const TQString& xml, const TQString& subresource,
@@ -722,8 +844,9 @@ void ResourceKolab::addTodo( const TQString& xml, const TQString& subresource,
{
KCal::Todo* todo = Kolab::Task::xmlToTask( xml, mCalendar.timeZoneId(), this, subresource, sernum );
Q_ASSERT( todo );
- if( todo )
- addIncidence( todo, subresource, sernum );
+ if ( todo ) {
+ addIncidence( todo, subresource, sernum );
+ }
}
bool ResourceKolab::deleteTodo( KCal::Todo* todo )
@@ -746,12 +869,17 @@ KCal::Todo::List ResourceKolab::rawTodosForDate( const TQDate& date )
return mCalendar.rawTodosForDate( date );
}
-bool ResourceKolab::addJournal( KCal::Journal* journal )
+bool ResourceKolab::addJournal( KCal::Journal *journal )
+{
+ return addJournal( journal, TQString() );
+}
+
+bool ResourceKolab::addJournal( KCal::Journal *journal, const TQString &subResource )
{
if ( mUidMap.contains( journal->uid() ) )
return true; //noop
else
- return addIncidence( journal, TQString::null, 0 );
+ return addIncidence( journal, subResource, 0 );
}
void ResourceKolab::addJournal( const TQString& xml, const TQString& subresource,
@@ -839,27 +967,33 @@ bool ResourceKolab::fromKMailAddIncidence( const TQString& type,
bool rc = true;
TemporarySilencer t( this ); // RAII
if ( type != kmailCalendarContentsType && type != kmailTodoContentsType
- && type != kmailJournalContentsType )
+ && type != kmailJournalContentsType ) {
// Not ours
return false;
- if ( !subresourceActive( subResource ) ) return true;
+ }
+
+ if ( !subresourceActive( subResource ) ) {
+ return true;
+ }
if ( format == KMailICalIface::StorageXML ) {
// If this data file is one of ours, load it here
- if ( type == kmailCalendarContentsType )
+ if ( type == kmailCalendarContentsType ) {
addEvent( data, subResource, sernum );
- else if ( type == kmailTodoContentsType )
+ } else if ( type == kmailTodoContentsType ) {
addTodo( data, subResource, sernum );
- else if ( type == kmailJournalContentsType )
+ } else if ( type == kmailJournalContentsType ) {
addJournal( data, subResource, sernum );
- else
+ } else {
rc = false;
+ }
} else {
Incidence *inc = mFormat.fromString( data );
- if ( !inc )
- rc = false;
- else
+ if ( inc ) {
addIncidence( inc, subResource, sernum );
+ } else {
+ rc = false;
+ }
}
return rc;
}
@@ -881,13 +1015,25 @@ void ResourceKolab::fromKMailDelIncidence( const TQString& type,
// It's good to know if was deleted, but we are waiting on a new one to
// replace it, so let's just sit tight.
} else {
+ TQString uidToUse;
+
+ QPair<TQString, TQString> p( uid, subResource );
+ if ( mOriginalUID2fakeUID.contains( p ) ) {
+ // Incidence with the same uid in a different folder...
+ // use the UID that addIncidence(...) generated
+ uidToUse = mOriginalUID2fakeUID[p];
+ } else {
+ uidToUse = uid;
+ }
+
// We didn't trigger this, so KMail did, remove the reference to the uid
- KCal::Incidence* incidence = mCalendar.incidence( uid );
+ KCal::Incidence* incidence = mCalendar.incidence( uidToUse );
if( incidence ) {
incidence->unRegisterObserver( this );
mCalendar.deleteIncidence( incidence );
}
- mUidMap.remove( uid );
+ mUidMap.remove( uidToUse );
+ mOriginalUID2fakeUID.remove( p );
mResourceChangedTimer.changeInterval( 100 );
}
}
@@ -1039,6 +1185,23 @@ void ResourceKolab::setSubresourceActive( const TQString &subresource, bool v )
}
mResourceChangedTimer.changeInterval( 100 );
}
+ TQTimer::singleShot( 0, this, TQT_SLOT(writeConfig()) );
+}
+
+bool ResourceKolab::subresourceWritable( const TQString& subresource ) const
+{
+ // Workaround: The ResourceView in KOrganizer wants to know this
+ // before it opens the resource :-( Make sure we are open
+ const_cast<ResourceKolab*>( this )->doOpen();
+
+ if ( mEventSubResources.contains( subresource ) )
+ return mEventSubResources[ subresource ].writable();
+ if ( mTodoSubResources.contains( subresource ) )
+ return mTodoSubResources[ subresource ].writable();
+ if ( mJournalSubResources.contains( subresource ) )
+ return mJournalSubResources[ subresource ].writable();
+
+ return false; //better a safe default
}
void ResourceKolab::slotEmitResourceChanged()
@@ -1053,7 +1216,6 @@ KABC::Lock* ResourceKolab::lock()
return new KABC::LockNull( true );
}
-
Kolab::ResourceMap* ResourceKolab::subResourceMap( const TQString& contentsType )
{
if ( contentsType == kmailCalendarContentsType ) {
@@ -1122,6 +1284,7 @@ bool ResourceKolab::unloadSubResource( const TQString& subResource )
const bool silent = mSilent;
mSilent = true;
Kolab::UidMap::Iterator mapIt = mUidMap.begin();
+ TQPtrList<KCal::Incidence> incidences;
while ( mapIt != mUidMap.end() )
{
Kolab::UidMap::Iterator it = mapIt++;
@@ -1130,11 +1293,18 @@ bool ResourceKolab::unloadSubResource( const TQString& subResource )
// FIXME incidence() is expensive
KCal::Incidence* incidence = mCalendar.incidence( it.key() );
if( incidence ) {
- incidence->unRegisterObserver( this );
- mCalendar.deleteIncidence( incidence );
+ // register all observers first before actually deleting them
+ // in case of inter-incidence relations the other part will get
+ // the change notification otherwise
+ incidence->unRegisterObserver( this );
+ incidences.append( incidence );
}
mUidMap.remove( it );
}
+ TQPtrListIterator<KCal::Incidence> it( incidences );
+ for ( ; it.current(); ++it ) {
+ mCalendar.deleteIncidence( it.current() );
+ }
mSilent = silent;
return true;
}
@@ -1150,4 +1320,23 @@ TQString ResourceKolab::subresourceType( const TQString &resource )
return TQString();
}
+void ResourceKolab::writeConfig()
+{
+ KConfig config( configFile() );
+ writeResourceConfig( config, mEventSubResources );
+ writeResourceConfig( config, mTodoSubResources );
+ writeResourceConfig( config, mJournalSubResources );
+}
+
+void ResourceKolab::beginAddingIncidences()
+{
+ mBatchAddingInProgress = true;
+}
+
+void ResourceKolab::endAddingIncidences()
+{
+ mBatchAddingInProgress = false;
+ mLastUsedResources.clear();
+}
+
#include "resourcekolab.moc"
diff --git a/kresources/kolab/kcal/resourcekolab.h b/kresources/kolab/kcal/resourcekolab.h
index e68c2c6b..dda5ba32 100644
--- a/kresources/kolab/kcal/resourcekolab.h
+++ b/kresources/kolab/kcal/resourcekolab.h
@@ -70,8 +70,9 @@ public:
void doClose();
// The libkcal functions. See the resource for descriptions
- bool addEvent( KCal::Event* anEvent );
- bool deleteEvent( KCal::Event* );
+ KDE_DEPRECATED bool addEvent( KCal::Event *event );
+ bool addEvent( KCal::Event *event, const TQString &subResource );
+ bool deleteEvent( KCal::Event * );
KCal::Event* event( const TQString &UniqueStr );
KCal::Event::List rawEvents( EventSortField sortField = EventSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
KCal::Event::List rawEventsForDate(
@@ -82,15 +83,17 @@ public:
KCal::Event::List rawEvents( const TQDate& start, const TQDate& end,
bool inclusive = false );
- bool addTodo( KCal::Todo* todo );
- bool deleteTodo( KCal::Todo* );
- KCal::Todo* todo( const TQString& uid );
+ KDE_DEPRECATED bool addTodo( KCal::Todo * todo );
+ bool addTodo( KCal::Todo *todo, const TQString &subResource );
+ bool deleteTodo( KCal::Todo * );
+ KCal::Todo* todo( const TQString &uid );
KCal::Todo::List rawTodos( TodoSortField sortField = TodoSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
KCal::Todo::List rawTodosForDate( const TQDate& date );
- bool addJournal( KCal::Journal* );
- bool deleteJournal( KCal::Journal* );
- KCal::Journal* journal( const TQString& uid );
+ KDE_DEPRECATED bool addJournal( KCal::Journal * );
+ bool addJournal( KCal::Journal *, const TQString &subResource );
+ bool deleteJournal( KCal::Journal * );
+ KCal::Journal* journal( const TQString &uid );
KCal::Journal::List rawJournals( JournalSortField sortField = JournalSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
KCal::Journal::List rawJournalsForDate( const TQDate &date );
@@ -128,6 +131,9 @@ public:
/** (De)activate the subresource */
virtual void setSubresourceActive( const TQString &, bool );
+ /** Is this subresource writable? */
+ bool subresourceWritable( const TQString& ) const;
+
/** What is the label for this subresource? */
virtual const TQString labelForSubresource( const TQString& resource ) const;
@@ -140,10 +146,16 @@ public:
KABC::Lock* lock();
+ void beginAddingIncidences();
+
+ void endAddingIncidences();
+
signals:
void useGlobalMode();
protected slots:
void slotEmitResourceChanged();
+ void writeConfig();
+
protected:
/**
* Return list of alarms which are relevant for the current user. These
@@ -157,7 +169,11 @@ private:
void addIncidence( const char* mimetype, const TQString& xml,
const TQString& subResource, Q_UINT32 sernum );
- bool addIncidence( KCal::Incidence* i, const TQString& subresource,
+
+ /**
+ Caller guarantees i is not null.
+ */
+ bool addIncidence( KCal::Incidence *i, const TQString& subresource,
Q_UINT32 sernum );
void addEvent( const TQString& xml, const TQString& subresource,
@@ -215,6 +231,36 @@ private:
*/
TQMap<TQString, TQString> mNewIncidencesMap;
int mProgressDialogIncidenceLimit;
+
+ /**
+ * If a user has a subresource for viewing another user's folder then it can happen
+ * that addIncidence(...) adds an incidence with an already existing UID.
+ *
+ * When this happens, addIncidence(...) sets a new random UID and stores the
+ * original UID using incidence->setSchedulingID(uid) because KCal doesn't
+ * allow two incidences to have the same UID.
+ *
+ * This map keeps track of the generated UIDs (which are local) so we can delete the
+ * right incidence inside fromKMailDelIncidence(...) whenever we sync.
+ *
+ * The key is originalUID,subResource and the value is the fake UID.
+ */
+ TQMap< QPair<TQString, TQString>, TQString > mOriginalUID2fakeUID;
+
+ bool mBatchAddingInProgress;
+ TQMap<Kolab::ResourceType,TQString> mLastUsedResources;
+
+ /**
+ Indexed by uid, it holds the last known revision of an incidence.
+ If we receive an update where the incidence still has the same
+ revision as the last known, we ignore it and don't send it to kmail,
+ because shortly after, IncidenceChanger will increment the revision
+ and that will trigger another update.
+
+ If we didn't discard the first update, kmail would have been updated twice.
+ */
+ TQMap<TQString,int> mLastKnownRevisions;
+
};
struct TemporarySilencer {
diff --git a/kresources/kolab/kcal/task.cpp b/kresources/kolab/kcal/task.cpp
index 7bbdba97..36876b7d 100644
--- a/kresources/kolab/kcal/task.cpp
+++ b/kresources/kolab/kcal/task.cpp
@@ -38,6 +38,41 @@
using namespace Kolab;
+// Kolab Storage Specification:
+// "The priority can be a number between 1 and 5, with 1 being the highest priority."
+// iCalendar (RFC 2445):
+// "The priority is specified as an integer in the range
+// zero to nine. A value of zero specifies an
+// undefined priority. A value of one is the
+// highest priority. A value of nine is the lowest
+// priority."
+
+static int kcalPriorityToKolab( const int kcalPriority )
+{
+ if ( kcalPriority >= 0 && kcalPriority <= 9 ) {
+ // We'll map undefined (0) to 3 (default)
+ // 0 1 2 3 4 5 6 7 8 9
+ static const int priorityMap[10] = { 3, 1, 1, 2, 2, 3, 3, 4, 4, 5 };
+ return priorityMap[kcalPriority];
+ }
+ else {
+ kdWarning() << "kcalPriorityToKolab(): Got invalid priority " << kcalPriority << endl;
+ return 3;
+ }
+}
+
+static int kolabPrioritytoKCal( const int kolabPriority )
+{
+ if ( kolabPriority >= 1 && kolabPriority <= 5 ) {
+ // 1 2 3 4 5
+ static const int priorityMap[5] = { 1, 3, 5, 7, 9 };
+ return priorityMap[kolabPriority - 1];
+ }
+ else {
+ kdWarning() << "kolabPrioritytoKCal(): Got invalid priority " << kolabPriority << endl;
+ return 5;
+ }
+}
KCal::Todo* Task::xmlToTask( const TQString& xml, const TQString& tz, KCal::ResourceKolab *res,
const TQString& subResource, Q_UINT32 sernum )
@@ -115,6 +150,26 @@ void Task::setDueDate( const TQDateTime& date )
{
mDueDate = date;
mHasDueDate = true;
+ mFloatingStatus = HasTime;
+}
+
+void Task::setDueDate( const TQDate &date )
+{
+ mDueDate = date;
+ mHasDueDate = true;
+ mFloatingStatus = AllDay;
+}
+
+
+void Task::setDueDate( const TQString &date )
+{
+ if ( date.length() > 10 ) {
+ // This is a date + time
+ setDueDate( stringToDateTime( date ) );
+ } else {
+ // This is only a date
+ setDueDate( stringToDate( date ) );
+ }
}
TQDateTime Task::dueDate() const
@@ -159,10 +214,18 @@ bool Task::loadAttribute( TQDomElement& element )
if ( tagName == "priority" ) {
bool ok;
- int priority = element.text().toInt( &ok );
- if ( !ok || priority < 0 || priority > 9 )
- priority = 5;
- setPriority( priority );
+ mKolabPriorityFromDom = element.text().toInt( &ok );
+ if ( !ok || mKolabPriorityFromDom < 1 || mKolabPriorityFromDom > 5 ) {
+ kdWarning() << "loadAttribute(): Invalid \"priority\" value: " << element.text() << endl;
+ mKolabPriorityFromDom = -1;
+ }
+ } else if ( tagName == "x-kcal-priority" ) {
+ bool ok;
+ mKCalPriorityFromDom = element.text().toInt( &ok );
+ if ( !ok || mKCalPriorityFromDom < 0 || mKCalPriorityFromDom > 9 ) {
+ kdWarning() << "loadAttribute(): Invalid \"x-kcal-priority\" value: " << element.text() << endl;
+ mKCalPriorityFromDom = -1;
+ }
} else if ( tagName == "completed" ) {
bool ok;
int percent = element.text().toInt( &ok );
@@ -182,13 +245,13 @@ bool Task::loadAttribute( TQDomElement& element )
else
// Default
setStatus( KCal::Incidence::StatusNone );
- } else if ( tagName == "due-date" )
- setDueDate( stringToDateTime( element.text() ) );
- else if ( tagName == "parent" )
+ } else if ( tagName == "due-date" ) {
+ setDueDate( element.text() );
+ } else if ( tagName == "parent" ) {
setParent( element.text() );
- else if ( tagName == "x-completed-date" )
+ } else if ( tagName == "x-completed-date" ) {
setCompletedDate( stringToDateTime( element.text() ) );
- else if ( tagName == "start-date" ) {
+ } else if ( tagName == "start-date" ) {
setHasStartDate( true );
setStartDate( element.text() );
} else
@@ -203,7 +266,11 @@ bool Task::saveAttributes( TQDomElement& element ) const
// Save the base class elements
Incidence::saveAttributes( element );
- writeString( element, "priority", TQString::number( priority() ) );
+ // We need to save x-kcal-priority as well, since the Kolab priority can only save values from
+ // 1 to 5, but we have values from 0 to 9, and do not want to loose them
+ writeString( element, "priority", TQString::number( kcalPriorityToKolab( priority() ) ) );
+ writeString( element, "x-kcal-priority", TQString::number( priority() ) );
+
writeString( element, "completed", TQString::number( percentCompleted() ) );
switch( status() ) {
@@ -232,14 +299,21 @@ bool Task::saveAttributes( TQDomElement& element ) const
break;
}
- if ( hasDueDate() )
- writeString( element, "due-date", dateTimeToString( dueDate() ) );
+ if ( hasDueDate() ) {
+ if ( mFloatingStatus == HasTime ) {
+ writeString( element, "due-date", dateTimeToString( dueDate() ) );
+ } else {
+ writeString( element, "due-date", dateToString( dueDate().date() ) );
+ }
+ }
- if ( !parent().isNull() )
+ if ( !parent().isNull() ) {
writeString( element, "parent", parent() );
+ }
- if ( hasCompletedDate() && percentCompleted() == 100)
+ if ( hasCompletedDate() && percentCompleted() == 100 ) {
writeString( element, "x-completed-date", dateTimeToString( completedDate() ) );
+ }
return true;
}
@@ -247,6 +321,9 @@ bool Task::saveAttributes( TQDomElement& element ) const
bool Task::loadXML( const TQDomDocument& document )
{
+ mKolabPriorityFromDom = -1;
+ mKCalPriorityFromDom = -1;
+
TQDomElement top = document.documentElement();
if ( top.tagName() != "task" ) {
@@ -269,6 +346,7 @@ bool Task::loadXML( const TQDomDocument& document )
}
loadAttachments();
+ decideAndSetPriority();
return true;
}
@@ -278,7 +356,7 @@ TQString Task::saveXML() const
TQDomElement element = document.createElement( "task" );
element.setAttribute( "version", "1.0" );
saveAttributes( element );
- if ( !hasStartDate() ) {
+ if ( !hasStartDate() && startDate().isValid() ) {
// events and journals always have a start date, but tasks don't.
// Remove the entry done by the inherited save above, because we
// don't have one.
@@ -299,21 +377,68 @@ void Task::setFields( const KCal::Todo* task )
setStatus( task->status() );
setHasStartDate( task->hasStartDate() );
- if ( task->hasDueDate() )
+ if ( task->hasDueDate() ) {
setDueDate( localToUTC( task->dtDue() ) );
- else
+ if ( task->doesFloat() ) {
+ // This is a floating task. Don't timezone move this one
+ mFloatingStatus = AllDay;
+ setDueDate( task->dtDue().date() );
+ } else {
+ mFloatingStatus = HasTime;
+ setDueDate( localToUTC( task->dtDue() ) );
+ }
+ } else {
mHasDueDate = false;
- if ( task->relatedTo() )
+ }
+
+ if ( task->relatedTo() ) {
setParent( task->relatedTo()->uid() );
- else if ( !task->relatedToUid().isEmpty() )
- setParent( task->relatedToUid() );
- else
+ } else if ( !task->relatedToUid().isEmpty() ) {
+ setParent( task->relatedToUid( ) );
+ } else {
setParent( TQString::null );
+ }
- if ( task->hasCompletedDate() && task->percentComplete() == 100 )
+ if ( task->hasCompletedDate() && task->percentComplete() == 100 ) {
setCompletedDate( localToUTC( task->completed() ) );
- else
+ } else {
mHasCompletedDate = false;
+ }
+}
+
+void Task::decideAndSetPriority()
+{
+ // If we have both Kolab and KCal values in the XML, we prefer the KCal value, but only if the
+ // values are still in sync
+ if ( mKolabPriorityFromDom != -1 && mKCalPriorityFromDom != -1 ) {
+ const bool inSync = ( kcalPriorityToKolab( mKCalPriorityFromDom ) == mKolabPriorityFromDom );
+ if ( inSync ) {
+ setPriority( mKCalPriorityFromDom );
+ }
+ else {
+ // Out of sync, some other client changed the Kolab priority, so we have to ignore our
+ // KCal priority
+ setPriority( kolabPrioritytoKCal( mKolabPriorityFromDom ) );
+ }
+ }
+
+ // Only KCal priority set, use that.
+ else if ( mKolabPriorityFromDom == -1 && mKCalPriorityFromDom != -1 ) {
+ kdWarning() << "decideAndSetPriority(): No Kolab priority found, only the KCal priority!" << endl;
+ setPriority( mKCalPriorityFromDom );
+ }
+
+ // Only Kolab priority set, use that
+ else if ( mKolabPriorityFromDom != -1 && mKCalPriorityFromDom == -1 ) {
+ setPriority( kolabPrioritytoKCal( mKolabPriorityFromDom ) );
+ }
+
+ // No priority set, use the default
+ else {
+ // According the RFC 2445, we should use 0 here, for undefined priority, but AFAIK KOrganizer
+ // doesn't support that, so we'll use 5.
+ setPriority( 5 );
+ }
}
void Task::saveTo( KCal::Todo* task )
diff --git a/kresources/kolab/kcal/task.h b/kresources/kolab/kcal/task.h
index 5dfb5585..f7e7c6d5 100644
--- a/kresources/kolab/kcal/task.h
+++ b/kresources/kolab/kcal/task.h
@@ -86,7 +86,9 @@ public:
virtual void setHasStartDate( bool );
virtual bool hasStartDate() const;
- virtual void setDueDate( const TQDateTime& date );
+ virtual void setDueDate( const TQDateTime &date );
+ virtual void setDueDate( const TQString &date );
+ virtual void setDueDate( const TQDate &date );
virtual TQDateTime dueDate() const;
virtual bool hasDueDate() const;
@@ -110,7 +112,19 @@ protected:
// Read all known fields from this ical todo
void setFields( const KCal::Todo* );
+ // This sets the priority of this task by looking at mKolabPriorityFromDom and
+ // mKCalPriorityFromDom.
+ void decideAndSetPriority();
+
+ // This is the KCal priority, not the Kolab priority.
+ // See kcalPriorityToKolab() and kolabPrioritytoKCal().
int mPriority;
+
+ // Those priority values are the raw values read by loadAttribute().
+ // They will be converted later in decideAndSetPriority().
+ int mKolabPriorityFromDom;
+ int mKCalPriorityFromDom;
+
int mPercentCompleted;
KCal::Incidence::Status mStatus;
TQString mParent;
diff --git a/kresources/kolab/knotes/kolabresource.desktop b/kresources/kolab/knotes/kolabresource.desktop
index d74e3f59..317032d1 100644
--- a/kresources/kolab/knotes/kolabresource.desktop
+++ b/kresources/kolab/knotes/kolabresource.desktop
@@ -21,7 +21,6 @@ Name[hu]=IMAP-kiszolgáló a KMailen keresztül
Name[is]=IMAP þjónn gegnum KMail
Name[it]=Server IMAP via KMail
Name[ja]=KMail 経由 IMAP サーバ
-Name[ka]= IMAP-ს სერვერთან დაშვება KMail-ის საშუალებით
Name[kk]=KMail арқылы IMAP сервері
Name[km]=ម៉ាស៊ីន​បម្រើ IMAP តាម​រយៈ KMail
Name[lt]=IMAP serveris per KMail
diff --git a/kresources/kolab/knotes/note.cpp b/kresources/kolab/knotes/note.cpp
index 66556aaf..168dae56 100644
--- a/kresources/kolab/knotes/note.cpp
+++ b/kresources/kolab/knotes/note.cpp
@@ -108,7 +108,6 @@ bool Note::richText() const
bool Note::loadAttribute( TQDomElement& element )
{
TQString tagName = element.tagName();
-
if ( tagName == "summary" )
setSummary( element.text() );
else if ( tagName == "foreground-color" )
@@ -136,8 +135,10 @@ bool Note::saveAttributes( TQDomElement& element ) const
#endif
writeString( element, "summary", summary() );
- writeString( element, "foreground-color", colorToString( foregroundColor() ) );
- writeString( element, "background-color", colorToString( backgroundColor() ) );
+ if ( foregroundColor().isValid() )
+ writeString( element, "foreground-color", colorToString( foregroundColor() ) );
+ if ( backgroundColor().isValid() )
+ writeString( element, "background-color", colorToString( backgroundColor() ) );
writeString( element, "knotes-richtext", mRichText ? "true" : "false" );
return true;
@@ -183,11 +184,27 @@ void Note::setFields( const KCal::Journal* journal )
{
KolabBase::setFields( journal );
- // TODO: background and foreground
setSummary( journal->summary() );
- setBackgroundColor( journal->customProperty( "KNotes", "BgColor" ) );
- setForegroundColor( journal->customProperty( "KNotes", "FgColor" ) );
- setRichText( journal->customProperty( "KNotes", "RichText" ) == "true" );
+
+ TQString property = journal->customProperty( "KNotes", "BgColor" );
+ if ( !property.isNull() ) {
+ setBackgroundColor( property );
+ } else {
+ setBackgroundColor( "yellow" );
+ }
+ property = journal->customProperty( "KNotes", "FgColor" );
+ if ( !property.isNull() ) {
+ setForegroundColor( property );
+ } else {
+ setForegroundColor( "black" );
+ }
+
+ property = journal->customProperty( "KNotes", "RichText" );
+ if ( !property.isNull() ) {
+ setRichText( property == "true" ? true : false );
+ } else {
+ setRichText( "false" );
+ }
}
void Note::saveTo( KCal::Journal* journal )
@@ -196,10 +213,12 @@ void Note::saveTo( KCal::Journal* journal )
// TODO: background and foreground
journal->setSummary( summary() );
- journal->setCustomProperty( "KNotes", "FgColor",
- colorToString( foregroundColor() ) );
- journal->setCustomProperty( "KNotes", "BgColor",
- colorToString( backgroundColor() ) );
+ if ( foregroundColor().isValid() )
+ journal->setCustomProperty( "KNotes", "FgColor",
+ colorToString( foregroundColor() ) );
+ if ( backgroundColor().isValid() )
+ journal->setCustomProperty( "KNotes", "BgColor",
+ colorToString( backgroundColor() ) );
journal->setCustomProperty( "KNotes", "RichText",
richText() ? "true" : "false" );
}
diff --git a/kresources/kolab/knotes/resourcekolab.cpp b/kresources/kolab/knotes/resourcekolab.cpp
index 1d633b62..d917d0ac 100644
--- a/kresources/kolab/knotes/resourcekolab.cpp
+++ b/kresources/kolab/knotes/resourcekolab.cpp
@@ -41,6 +41,7 @@
#include <kdebug.h>
#include <kglobal.h>
+#include <klocale.h>
using namespace Kolab;
@@ -53,6 +54,9 @@ ResourceKolab::ResourceKolab( const KConfig *config )
: ResourceNotes( config ), ResourceKolabBase( "ResourceKolab-KNotes" ),
mCalendar( TQString::fromLatin1("UTC") )
{
+ if ( !config ) {
+ setResourceName( i18n( "Kolab Server" ) );
+ }
setType( "imap" );
}
@@ -73,7 +77,7 @@ bool ResourceKolab::doOpen()
// Make the resource map from the folder list
TQValueList<KMailICalIface::SubResource>::ConstIterator it;
mSubResources.clear();
- for ( it = subResources.begin(); it != subResources.end(); ++it ) {
+ for ( it = subResources.constBegin(); it != subResources.constEnd(); ++it ) {
const TQString subResource = (*it).location;
const bool active = config.readBoolEntry( subResource, true );
mSubResources[ subResource ] = Kolab::SubResource( active, (*it).writable, (*it).label );
@@ -87,7 +91,7 @@ void ResourceKolab::doClose()
KConfig config( configFile() );
config.setGroup( configGroupName );
Kolab::ResourceMap::ConstIterator it;
- for ( it = mSubResources.begin(); it != mSubResources.end(); ++it )
+ for ( it = mSubResources.constBegin(); it != mSubResources.constEnd(); ++it )
config.writeEntry( it.key(), it.data().active() );
}
@@ -113,8 +117,8 @@ bool ResourceKolab::loadSubResource( const TQString& subResource,
// Populate with the new entries
const bool silent = mSilent;
mSilent = true;
- TQMap<Q_UINT32, TQString>::Iterator it;
- for ( it = lst.begin(); it != lst.end(); ++it ) {
+ TQMap<Q_UINT32, TQString>::ConstIterator it;
+ for ( it = lst.constBegin(); it != lst.constEnd(); ++it ) {
KCal::Journal* journal = addNote( it.data(), subResource, it.key(), mimetype );
if ( !journal )
kdDebug(5500) << "loading note " << it.key() << " failed" << endl;
@@ -134,7 +138,7 @@ bool ResourceKolab::load()
bool rc = true;
Kolab::ResourceMap::ConstIterator itR;
- for ( itR = mSubResources.begin(); itR != mSubResources.end(); ++itR ) {
+ for ( itR = mSubResources.constBegin(); itR != mSubResources.constEnd(); ++itR ) {
if ( !itR.data().active() )
// This subResource is disabled
continue;
@@ -162,25 +166,35 @@ bool ResourceKolab::addNote( KCal::Journal* journal )
KCal::Journal* ResourceKolab::addNote( const TQString& data, const TQString& subresource,
Q_UINT32 sernum, const TQString &mimetype )
{
- KCal::Journal* journal = 0;
- // FIXME: This does not take into account the time zone!
+ KCal::Journal *journal = 0;
+
+ // FIXME: This does not take into account the time zone!
KCal::ICalFormat formatter;
- if ( mimetype == attachmentMimeType )
+ if ( mimetype == attachmentMimeType ) {
journal = Note::xmlToJournal( data );
- else
+ } else {
journal = static_cast<KCal::Journal*>( formatter.fromString( data ) );
-
+ }
Q_ASSERT( journal );
- if( journal && !mUidMap.contains( journal->uid() ) )
- if ( addNote( journal, subresource, sernum ) )
- return journal;
- else
- delete journal;
- return 0;
+
+ bool addedOk = journal &&
+ !mUidMap.contains( journal->uid() ) &&
+ addNote( journal, subresource, sernum );
+
+ // for debugging
+ if ( journal && mUidMap.contains( journal->uid() ) ) {
+ kdDebug(5500) << "mUidMap already contains " << journal->uid() << endl;
+ }
+
+ if ( !addedOk ) {
+ delete journal;
+ journal = 0;
+ }
+
+ return journal;
}
-bool ResourceKolab::addNote( KCal::Journal* journal,
- const TQString& subresource, Q_UINT32 sernum )
+bool ResourceKolab::addNote( KCal::Journal *journal, const TQString &subresource, Q_UINT32 sernum )
{
kdDebug(5500) << "ResourceKolab::addNote( KCal::Journal*, '" << subresource << "', " << sernum << " )\n";
@@ -188,12 +202,15 @@ bool ResourceKolab::addNote( KCal::Journal* journal,
// Find out if this note was previously stored in KMail
bool newNote = subresource.isEmpty();
- mCalendar.addJournal( journal );
+ if ( !mCalendar.addJournal( journal ) ) {
+ return false;
+ }
- TQString resource =
- newNote ? findWritableResource( mSubResources ) : subresource;
- if ( resource.isEmpty() ) // canceled
+ TQString resource = newNote ? findWritableResource( Kolab::Notes, mSubResources ) : subresource;
+ if ( resource.isEmpty() ) {
+ // canceled
return false;
+ }
if ( !mSilent ) {
TQString xml = Note::journalToXML( journal );
@@ -209,7 +226,6 @@ bool ResourceKolab::addNote( KCal::Journal* journal,
mUidMap[ journal->uid() ] = StorageReference( resource, sernum );
return true;
}
-
return false;
}
@@ -225,9 +241,7 @@ bool ResourceKolab::deleteNote( KCal::Journal* journal )
mUidMap[ uid ].serialNumber() );
}
mUidMap.remove( uid );
- manager()->deleteNote( journal );
- mCalendar.deleteJournal( journal );
- return true;
+ return mCalendar.deleteJournal( journal );
}
KCal::Alarm::List ResourceKolab::alarms( const TQDateTime& from, const TQDateTime& to )
@@ -239,7 +253,7 @@ KCal::Alarm::List ResourceKolab::alarms( const TQDateTime& from, const TQDateTim
{
TQDateTime preTime = from.addSecs( -1 );
KCal::Alarm::List::ConstIterator it;
- for( it = (*note)->alarms().begin(); it != (*note)->alarms().end(); ++it )
+ for( it = (*note)->alarms().constBegin(); it != (*note)->alarms().constEnd(); ++it )
{
if ( (*it)->enabled() )
{
@@ -261,7 +275,7 @@ void ResourceKolab::incidenceUpdated( KCal::IncidenceBase* i )
subResource = mUidMap[ i->uid() ].resource();
sernum = mUidMap[ i->uid() ].serialNumber();
} else { // can this happen?
- subResource = findWritableResource( mSubResources );
+ subResource = findWritableResource( Kolab::Notes, mSubResources );
if ( subResource.isEmpty() ) // canceled
return;
sernum = 0;
@@ -313,8 +327,11 @@ void ResourceKolab::fromKMailDelIncidence( const TQString& type,
const bool silent = mSilent;
mSilent = true;
KCal::Journal* j = mCalendar.journal( uid );
- if( j )
- deleteNote( j );
+ if ( j ) {
+ if ( deleteNote( j ) ) {
+ manager()->deleteNote( j );
+ }
+ }
mSilent = silent;
}
@@ -370,7 +387,7 @@ void ResourceKolab::fromKMailDelSubresource( const TQString& type,
// Make a list of all uids to remove
Kolab::UidMap::ConstIterator mapIt;
TQStringList uids;
- for ( mapIt = mUidMap.begin(); mapIt != mUidMap.end(); ++mapIt )
+ for ( mapIt = mUidMap.constBegin(); mapIt != mUidMap.constEnd(); ++mapIt )
if ( mapIt.data().resource() == subResource )
// We have a match
uids << mapIt.key();
@@ -380,7 +397,7 @@ void ResourceKolab::fromKMailDelSubresource( const TQString& type,
const bool silent = mSilent;
mSilent = true;
TQStringList::ConstIterator it;
- for ( it = uids.begin(); it != uids.end(); ++it ) {
+ for ( it = uids.constBegin(); it != uids.constEnd(); ++it ) {
KCal::Journal* j = mCalendar.journal( *it );
if( j )
deleteNote( j );
@@ -405,7 +422,7 @@ void ResourceKolab::fromKMailAsyncLoadResult( const TQMap<Q_UINT32, TQString>& m
mimetype = attachmentMimeType;
else
mimetype = inlineMimeType;
- for( TQMap<Q_UINT32, TQString>::ConstIterator it = map.begin(); it != map.end(); ++it ) {
+ for( TQMap<Q_UINT32, TQString>::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it ) {
KCal::Journal* journal = addNote( it.data(), folder, it.key(), mimetype );
if ( !journal )
kdDebug(5500) << "loading note " << it.key() << " failed" << endl;
@@ -433,5 +450,14 @@ bool ResourceKolab::subresourceActive( const TQString& res ) const
return true;
}
+bool ResourceKolab::subresourceWritable( const TQString& res ) const
+{
+ if ( mSubResources.contains( res ) ) {
+ return mSubResources[ res ].writable();
+ }
+
+ // Safe default bet:
+ return false;
+}
#include "resourcekolab.moc"
diff --git a/kresources/kolab/knotes/resourcekolab.h b/kresources/kolab/knotes/resourcekolab.h
index a738a30a..6ff994cc 100644
--- a/kresources/kolab/knotes/resourcekolab.h
+++ b/kresources/kolab/knotes/resourcekolab.h
@@ -102,6 +102,9 @@ public:
/** Is this subresource active? */
bool subresourceActive( const TQString& ) const;
+ /** Is this subresource writable? */
+ bool subresourceWritable( const TQString& ) const;
+
signals:
void signalSubresourceAdded( Resource*, const TQString&, const TQString& );
void signalSubresourceRemoved( Resource*, const TQString&, const TQString& );
diff --git a/kresources/kolab/shared/kmailconnection.cpp b/kresources/kolab/shared/kmailconnection.cpp
index 9135e16d..66674abf 100644
--- a/kresources/kolab/shared/kmailconnection.cpp
+++ b/kresources/kolab/shared/kmailconnection.cpp
@@ -73,16 +73,38 @@ static const TQCString dcopObjectId = "KMailICalIface";
bool KMailConnection::connectToKMail()
{
if ( !mKMailIcalIfaceStub ) {
- TQString error;
TQCString dcopService;
- int result = KDCOPServiceStarter::self()->
- findServiceFor( "DCOP/ResourceBackend/IMAP", TQString::null,
- TQString::null, &error, &dcopService );
- if ( result != 0 ) {
- kdError(5650) << "Couldn't connect to the IMAP resource backend\n";
- // TODO: You might want to show "error" (if not empty) here,
- // using e.g. KMessageBox
- return false;
+
+ // if we are kmail (and probably kontact as well) ourselves, don't try to start us again
+ // this prevents a DCOP deadlock when launching the kmail while kontact is the IMAP backend
+ // provider (and probably vice versa)
+ if ( kapp->instanceName() == "kmail" ) {
+ // someone, probably ourselves, already offers the interface, if not stop here
+ const QCStringList services = kapp->dcopClient()->registeredApplications();
+ for ( uint i = 0; i < services.count(); ++i ) {
+ if ( services[i].find( "anonymous" ) == 0 ) // querying anonymous-XXXXX deadlocks as well, what are those anyway?
+ continue;
+ const QCStringList objs = kapp->dcopClient()->remoteObjects( services[i] );
+ if ( objs.contains( dcopObjectId ) ) {
+ dcopService = services[i];
+ break;
+ }
+ }
+ if ( dcopService.isEmpty() ) {
+ kdError(5650) << k_funcinfo << "Not connecting to KMail to prevent DCOP deadlock" << endl;
+ return false;
+ }
+ } else {
+ TQString error;
+ int result = KDCOPServiceStarter::self()->
+ findServiceFor( "DCOP/ResourceBackend/IMAP", TQString::null,
+ TQString::null, &error, &dcopService );
+ if ( result != 0 ) {
+ kdError(5650) << "Couldn't connect to the IMAP resource backend\n";
+ // TODO: You might want to show "error" (if not empty) here,
+ // using e.g. KMessageBox
+ return false;
+ }
}
mKMailIcalIfaceStub = new KMailICalIface_stub( kapp->dcopClient(),
diff --git a/kresources/kolab/shared/kolabbase.cpp b/kresources/kolab/shared/kolabbase.cpp
index 9a4a17f7..b7f50257 100644
--- a/kresources/kolab/shared/kolabbase.cpp
+++ b/kresources/kolab/shared/kolabbase.cpp
@@ -36,6 +36,7 @@
#include <kabc/addressee.h>
#include <libkcal/journal.h>
#include <libkdepim/kpimprefs.h>
+#include <libemailfunctions/email.h>
#include <kdebug.h>
#include <tqfile.h>
@@ -257,8 +258,16 @@ bool KolabBase::loadEmailAttribute( TQDomElement& element, Email& email )
TQDomElement e = n.toElement();
const TQString tagName = e.tagName();
- if ( tagName == "display-name" )
- email.displayName = e.text();
+ if ( tagName == "display-name" ) {
+ // Quote the text in case it contains commas or other quotable chars.
+ TQString tusername = KPIM::quoteNameIfNecessary( e.text() );
+
+ TQString tname, temail;
+ // ignore the return value because it will always be false since
+ // tusername does not contain "@domain".
+ KPIM::getNameAndMail( tusername, tname, temail );
+ email.displayName = tname;
+ }
else if ( tagName == "smtp-address" )
email.smtpAddress = e.text();
else
@@ -411,7 +420,11 @@ TQString KolabBase::dateToString( const TQDate& date )
TQDateTime KolabBase::stringToDateTime( const TQString& _date )
{
TQString date( _date );
- if ( date.endsWith( "Z" ) )
+ //Deal with data from some clients that always append a Z to dates.
+ if ( date.endsWith( "ZZ" ) )
+ date.truncate( date.length() - 2 );
+ //In TQt3, TQt::ISODate cannot handle a trailing Z for UTC, so remove if found.
+ else if ( date.endsWith( "Z" ) )
date.truncate( date.length() - 1 );
return TQDateTime::fromString( date, Qt::ISODate );
}
diff --git a/kresources/kolab/shared/resourcekolabbase.cpp b/kresources/kolab/shared/resourcekolabbase.cpp
index 291910fb..2db2117d 100644
--- a/kresources/kolab/shared/resourcekolabbase.cpp
+++ b/kresources/kolab/shared/resourcekolabbase.cpp
@@ -210,9 +210,12 @@ bool ResourceKolabBase::kmailRemoveSubresource( const TQString& resource )
return mConnection->kmailRemoveSubresource( resource );
}
-TQString ResourceKolabBase::findWritableResource( const ResourceMap& resources,
+TQString ResourceKolabBase::findWritableResource( const ResourceType &type,
+ const ResourceMap& resources,
const TQString& text )
{
+ mErrorCode = NoError;
+
// I have to use the label (shown in the dialog) as key here. But given how the
// label is made up, it should be unique. If it's not, well the dialog would suck anyway...
TQMap<TQString, TQString> possible;
@@ -227,7 +230,33 @@ TQString ResourceKolabBase::findWritableResource( const ResourceMap& resources,
if ( possible.isEmpty() ) { // None found!!
kdWarning(5650) << "No writable resource found!" << endl;
- KMessageBox::error( 0, i18n( "No writable resource was found, saving will not be possible. Reconfigure KMail first." ) );
+
+ TQString errorText;
+ switch( type ) {
+ case Events:
+ errorText = i18n( "You have no writable event folders so saving will not be possible.\n"
+ "Please create or activate at least one writable event folder and try again." );
+ break;
+ case Tasks:
+ errorText = i18n( "You have no writable task folders so saving will not be possible.\n"
+ "Please create or activate at least one writable task folder and try again." );
+ break;
+ case Incidences:
+ errorText = i18n( "You have no writable calendar folder so saving will not be possible.\n"
+ "Please create or activate at least one writable calendar folder and try again." );
+ break;
+ case Notes:
+ errorText = i18n( "You have no writable notes folders so saving will not be possible.\n"
+ "Please create or activate at least one writable notes folder and try again." );
+ break;
+ case Contacts:
+ errorText = i18n( "You have no writable addressbook folder so saving will not be possible.\n"
+ "Please create or activate at least one writable addressbook folder and try again." );
+ break;
+ }
+
+ KMessageBox::error( 0, errorText );
+ mErrorCode = NoWritableFound;
return TQString::null;
}
if ( possible.count() == 1 )
@@ -242,8 +271,11 @@ TQString ResourceKolabBase::findWritableResource( const ResourceMap& resources,
// Several found, ask the user
TQString chosenLabel = KPIM::FolderSelectDialog::getItem( i18n( "Select Resource Folder" ),
t, possible.keys() );
- if ( chosenLabel.isEmpty() ) // cancelled
+ if ( chosenLabel.isEmpty() ) {
+ // cancelled
+ mErrorCode = UserCancel;
return TQString::null;
+ }
return possible[chosenLabel];
}
diff --git a/kresources/kolab/shared/resourcekolabbase.h b/kresources/kolab/shared/resourcekolabbase.h
index b2ce0501..1bd8b951 100644
--- a/kresources/kolab/shared/resourcekolabbase.h
+++ b/kresources/kolab/shared/resourcekolabbase.h
@@ -46,6 +46,8 @@ class KURL;
namespace Kolab {
+enum ResourceType { Tasks, Events, Incidences, Contacts, Notes };
+
class KMailConnection;
/**
@@ -168,9 +170,17 @@ protected:
TQString configFile( const TQString& type ) const;
/// If only one of these is writable, return that. Otherwise return null.
- TQString findWritableResource( const ResourceMap& resources,
+ TQString findWritableResource( const ResourceType &type,
+ const ResourceMap& resources,
const TQString& text = TQString::null );
+ enum ErrorCode {
+ NoError,
+ NoWritableFound, /**< No writable resource is available */
+ UserCancel /**< User canceled the operation */
+ };
+ ErrorCode mErrorCode;
+
bool mSilent;
/**
diff --git a/kresources/lib/addressbookadaptor.cpp b/kresources/lib/addressbookadaptor.cpp
index 900772e5..80da3942 100644
--- a/kresources/lib/addressbookadaptor.cpp
+++ b/kresources/lib/addressbookadaptor.cpp
@@ -32,9 +32,9 @@
using namespace KABC;
-AddressBookUploadItem::AddressBookUploadItem(
- KPIM::GroupwareDataAdaptor *adaptor,
- KABC::Addressee addr,
+AddressBookUploadItem::AddressBookUploadItem(
+ KPIM::GroupwareDataAdaptor *adaptor,
+ KABC::Addressee addr,
GroupwareUploadItem::UploadType type )
: GroupwareUploadItem( type )
{
@@ -42,7 +42,11 @@ AddressBookUploadItem::AddressBookUploadItem(
setUrl( addr.custom( adaptor->identifier(), "storagelocation" ) );
setUid( addr.uid() );
KABC::VCardConverter vcard;
+#if defined(KABC_VCARD_ENCODING_FIX)
+ setData( vcard.createVCardRaw( addr ) );
+#else
setData( vcard.createVCard( addr ) );
+#endif
}
@@ -105,12 +109,12 @@ void AddressBookAdaptor::addressbookItemDownloaded( KABC::Addressee addr,
deleteItem( newLocalId );
TQString localId = idMapper()->localId( remoteId.path() );
if ( !localId.isEmpty() ) deleteItem( localId );
-
+
// add the new item
addr.insertCustom( identifier(), "storagelocation", storagelocation );
if ( !localId.isEmpty() ) addr.setUid( localId );
addItem( addr );
-
+
// update the fingerprint and the ids in the idMapper
idMapper()->removeRemoteId( localId );
idMapper()->removeRemoteId( newLocalId );
@@ -123,7 +127,7 @@ void AddressBookAdaptor::clearChange( const TQString &uid )
mResource->clearChange( uid );
}
-KPIM::GroupwareUploadItem *AddressBookAdaptor::newUploadItem(
+KPIM::GroupwareUploadItem *AddressBookAdaptor::newUploadItem(
KABC::Addressee addr, KPIM::GroupwareUploadItem::UploadType type )
{
return new AddressBookUploadItem( this, addr, type );
diff --git a/kresources/lib/folderselectdialog.cpp b/kresources/lib/folderselectdialog.cpp
index 0942f822..c4d34359 100644
--- a/kresources/lib/folderselectdialog.cpp
+++ b/kresources/lib/folderselectdialog.cpp
@@ -39,7 +39,7 @@ using namespace KPIM;
FolderSelectDialog::FolderSelectDialog( const TQString& caption, const TQString& label,
const TQStringList& list )
- : KDialogBase(0, 0, true, caption, Ok, Ok, true)
+ : KDialogBase(0, 0, true, caption, Ok|Cancel, Ok, true)
{
TQFrame* frame = makeMainWidget();
TQVBoxLayout* layout = new TQVBoxLayout( frame, 0, spacingHint() );
@@ -81,3 +81,8 @@ void FolderSelectDialog::closeEvent(TQCloseEvent *event)
{
event->ignore();
}
+
+void FolderSelectDialog::reject()
+{
+}
+
diff --git a/kresources/lib/folderselectdialog.h b/kresources/lib/folderselectdialog.h
index a7879f9a..e5901239 100644
--- a/kresources/lib/folderselectdialog.h
+++ b/kresources/lib/folderselectdialog.h
@@ -49,6 +49,7 @@ public:
protected:
virtual void closeEvent(TQCloseEvent *event);
+ void reject();
private:
KListBox* mListBox;
};
diff --git a/kresources/lib/kcal_resourcegroupwarebase.cpp b/kresources/lib/kcal_resourcegroupwarebase.cpp
index 7499b224..823943c2 100644
--- a/kresources/lib/kcal_resourcegroupwarebase.cpp
+++ b/kresources/lib/kcal_resourcegroupwarebase.cpp
@@ -39,13 +39,13 @@
using namespace KCal;
ResourceGroupwareBase::ResourceGroupwareBase()
- : ResourceCached( 0 ), mPrefs(0), mFolderLister(0),
+ : ResourceCached( 0 ), mPrefs(0), mFolderLister(0),
mLock( true ), mAdaptor(0), mDownloadJob(0), mUploadJob(0)
{
}
ResourceGroupwareBase::ResourceGroupwareBase( const KConfig *config )
- : ResourceCached( config ), mPrefs(0), mFolderLister(0),
+ : ResourceCached( config ), mPrefs(0), mFolderLister(0),
mLock( true ), mAdaptor(0), mDownloadJob(0), mUploadJob(0)
{
if ( config ) readConfig( config );
@@ -69,7 +69,7 @@ bool ResourceGroupwareBase::addEvent( Event *event )
{
if ( adaptor() && ( adaptor()->supports( KPIM::FolderLister::Event ) ||
adaptor()->supports( KPIM::FolderLister::All ) ) ) {
- return ResourceCached::addEvent( event );
+ return ResourceCached::addEvent( event, TQString() );
} else return false;
}
@@ -77,7 +77,7 @@ bool ResourceGroupwareBase::addTodo( Todo *todo )
{
if ( adaptor() && ( adaptor()->supports( KPIM::FolderLister::Todo ) ||
adaptor()->supports( KPIM::FolderLister::All ) ) ) {
- return ResourceCached::addTodo( todo );
+ return ResourceCached::addTodo( todo, TQString() );
} else return false;
}
@@ -85,30 +85,30 @@ bool ResourceGroupwareBase::addJournal( Journal *journal )
{
if ( adaptor() && ( adaptor()->supports( KPIM::FolderLister::Journal ) ||
adaptor()->supports( KPIM::FolderLister::All ) ) ) {
- return ResourceCached::addJournal( journal );
+ return ResourceCached::addJournal( journal, TQString() );
} else return false;
}
-KPIM::GroupwareDownloadJob *ResourceGroupwareBase::createDownloadJob(
+KPIM::GroupwareDownloadJob *ResourceGroupwareBase::createDownloadJob(
CalendarAdaptor *adaptor )
{
return new KPIM::GroupwareDownloadJob( adaptor );
}
-KPIM::GroupwareUploadJob *ResourceGroupwareBase::createUploadJob(
+KPIM::GroupwareUploadJob *ResourceGroupwareBase::createUploadJob(
CalendarAdaptor *adaptor )
{
return new KPIM::GroupwareUploadJob( adaptor );
}
-void ResourceGroupwareBase::setPrefs( KPIM::GroupwarePrefsBase *newprefs )
+void ResourceGroupwareBase::setPrefs( KPIM::GroupwarePrefsBase *newprefs )
{
if ( !newprefs ) return;
if ( mPrefs ) delete mPrefs;
mPrefs = newprefs;
mPrefs->addGroupPrefix( identifier() );
-
+
mPrefs->readConfig();
if ( mFolderLister ) mFolderLister->readConfig( mPrefs );
}
@@ -236,7 +236,7 @@ void ResourceGroupwareBase::doClose()
ResourceCached::doClose();
if ( mDownloadJob ) mDownloadJob->kill();
- if ( adaptor() &&
+ if ( adaptor() &&
adaptor()->flags() & KPIM::GroupwareDataAdaptor::GWResNeedsLogoff ) {
KIO::Job *logoffJob = adaptor()->createLogoffJob( prefs()->url(), prefs()->user(), prefs()->password() );
connect( logoffJob, TQT_SIGNAL( result( KIO::Job * ) ),
@@ -267,7 +267,7 @@ bool ResourceGroupwareBase::doLoad()
kdWarning() << "Download still in progress" << endl;
return false;
}
-
+
mCalendar.close();
clearChanges();
disableChangeNotification();
@@ -292,7 +292,7 @@ void ResourceGroupwareBase::slotDownloadJobResult( KPIM::GroupwareJob *job )
mIsShowingError = false;
} else {
kdDebug(5800) << "Successfully downloaded data" << endl;
-
+
clearChanges();
saveCache();
enableChangeNotification();
@@ -318,9 +318,9 @@ bool ResourceGroupwareBase::doSave()
// to upload only certain changes and discard the rest. This is
// particularly important for resources like the blogging resource,
// where uploading would mean a republication of the blog, not only
- // a modifications.
+ // a modifications.
if ( !confirmSave() ) return false;
-
+
mUploadJob = createUploadJob( adaptor() );
connect( mUploadJob, TQT_SIGNAL( result( KPIM::GroupwareJob * ) ),
TQT_SLOT( slotUploadJobResult( KPIM::GroupwareJob * ) ) );
@@ -331,20 +331,20 @@ bool ResourceGroupwareBase::doSave()
inc = addedIncidences();
for( it = inc.begin(); it != inc.end(); ++it ) {
- addedItems.append( adaptor()->newUploadItem( *it,
+ addedItems.append( adaptor()->newUploadItem( *it,
KPIM::GroupwareUploadItem::Added ) );
}
// TODO: Check if the item has changed on the server...
- // In particular, check if the version we based our change on is still current
+ // In particular, check if the version we based our change on is still current
// on the server
inc = changedIncidences();
for( it = inc.begin(); it != inc.end(); ++it ) {
- changedItems.append( adaptor()->newUploadItem( *it,
+ changedItems.append( adaptor()->newUploadItem( *it,
KPIM::GroupwareUploadItem::Changed ) );
}
inc = deletedIncidences();
for( it = inc.begin(); it != inc.end(); ++it ) {
- deletedItems.append( adaptor()->newUploadItem( *it,
+ deletedItems.append( adaptor()->newUploadItem( *it,
KPIM::GroupwareUploadItem::Deleted ) );
}
@@ -368,10 +368,10 @@ void ResourceGroupwareBase::slotUploadJobResult( KPIM::GroupwareJob *job )
mIsShowingError = false;
} else {
kdDebug(5800) << "Successfully uploaded data" << endl;
- /*
+ /*
* After the put the server might have expanded recurring events and will
* also change the uids of the uploaded events. Remove them from the cache
- * and get the fresh delta and download.
+ * and get the fresh delta and download.
*/
if ( !mDownloadJob ) {
diff --git a/kresources/newexchange/exchangeconvertercontact.cpp b/kresources/newexchange/exchangeconvertercontact.cpp
index 0764d310..732c9db1 100644
--- a/kresources/newexchange/exchangeconvertercontact.cpp
+++ b/kresources/newexchange/exchangeconvertercontact.cpp
@@ -52,7 +52,7 @@ void ExchangeConverterContact::createRequest( TQDomDocument &doc, TQDomElement &
TQDomAttr att_cal = doc.createAttribute( "xmlns:cal" );
att_cal.setValue( "urn:schemas:calendar:" );
doc.documentElement().setAttributeNode( att_cal );
-
+
propertyDAV( "contentclass" );
propertyDAV( "getcontenttype" );
propertyNS( "http://schemas.microsoft.com/exchange/", "outlookmessageclass" );
@@ -160,10 +160,10 @@ void ExchangeConverterContact::createRequest( TQDomDocument &doc, TQDomElement &
#undef property
-bool ExchangeConverterContact::extractAddress( const TQDomElement &node,
+bool ExchangeConverterContact::extractAddress( const TQDomElement &node,
Addressee &addressee, int type,
- const TQString &street, const TQString &pobox, const TQString &location,
- const TQString &postalcode, const TQString &state, const TQString &country,
+ const TQString &street, const TQString &pobox, const TQString &location,
+ const TQString &postalcode, const TQString &state, const TQString &country,
const TQString &/*countycode*/ )
{
bool haveAddr = false;
@@ -206,13 +206,13 @@ bool ExchangeConverterContact::extractAddress( const TQDomElement &node,
/**
-For the complete list of Exchange <=> KABC field mappings see the file
+For the complete list of Exchange <=> KABC field mappings see the file
Person.mapping */
-bool ExchangeConverterContact::readAddressee( const TQDomElement &node, Addressee &addressee )
+bool ExchangeConverterContact::readAddressee( const TQDomElement &node, Addressee &addressee )
{
TQString tmpstr;
long tmplng;
-
+
// The UID is absolutely required!
if ( WebdavHandler::extractString( node, "uid", tmpstr ) ) {
addressee.setUid( tmpstr );
@@ -224,7 +224,7 @@ bool ExchangeConverterContact::readAddressee( const TQDomElement &node, Addresse
addressee.insertCustom( "KDEPIM-Exchange-Resource", "fingerprint", tmpstr );
if ( WebdavHandler::extractString( node, "href", tmpstr ) )
addressee.insertCustom( "KDEPIM-Exchange-Resource", "href", tmpstr );
-
+
/* KDE4: addressee does not have any creation or modification date :-(( */
/* KDE4: read-only not supported by libkabc */
@@ -232,16 +232,16 @@ bool ExchangeConverterContact::readAddressee( const TQDomElement &node, Addresse
if ( WebdavHandler::extractString( node, "fileas", tmpstr ) ||
WebdavHandler::extractString( node, "cn", tmpstr ) )
addressee.setFormattedName( tmpstr );
- if ( WebdavHandler::extractString( node, "givenName", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "givenName", tmpstr ) )
addressee.setGivenName( tmpstr );
- if ( WebdavHandler::extractString( node, "middlename", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "middlename", tmpstr ) )
addressee.setAdditionalName( tmpstr );
- if ( WebdavHandler::extractString( node, "sn", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "sn", tmpstr ) )
addressee.setFamilyName( tmpstr );
//urn:schemas:contacts:initials not used -
- if ( WebdavHandler::extractString( node, "namesuffix", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "namesuffix", tmpstr ) )
addressee.setSuffix( tmpstr );
- if ( WebdavHandler::extractString( node, "personaltitle", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "personaltitle", tmpstr ) )
addressee.setPrefix( tmpstr );
// Role
@@ -249,31 +249,37 @@ bool ExchangeConverterContact::readAddressee( const TQDomElement &node, Addresse
addressee.setRole( tmpstr );
// Company-Related settings
- if ( WebdavHandler::extractString( node, "o", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "o", tmpstr ) )
addressee.setOrganization( tmpstr );
- if ( WebdavHandler::extractString( node, "department", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "department", tmpstr ) )
+ {
+#if KDE_IS_VERSION(3,5,8)
+ addressee.setDepartment( tmpstr );
+#else
addressee.insertCustom( "KADDRESSBOOK", "X-Department", tmpstr );
- if ( WebdavHandler::extractString( node, "roomnumber", tmpstr ) )
+#endif
+ }
+ if ( WebdavHandler::extractString( node, "roomnumber", tmpstr ) )
addressee.insertCustom( "KADDRESSBOOK", "X-Office", tmpstr );
- if ( WebdavHandler::extractString( node, "profession", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "profession", tmpstr ) )
addressee.insertCustom( "KADDRESSBOOK", "X-Profession", tmpstr );
- if ( WebdavHandler::extractString( node, "manager", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "manager", tmpstr ) )
addressee.insertCustom( "KADDRESSBOOK", "X-ManagersName", tmpstr );
- if ( WebdavHandler::extractString( node, "secretarycn", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "secretarycn", tmpstr ) )
addressee.insertCustom( "KADDRESSBOOK", "X-AssistantsName", tmpstr );
// Web-Related settings
if ( WebdavHandler::extractString( node, "email1", tmpstr ) )
addressee.insertEmail( tmpstr, true );
- if ( WebdavHandler::extractString( node, "email2", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "email2", tmpstr ) )
addressee.insertEmail( tmpstr );
- if ( WebdavHandler::extractString( node, "email3", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "email3", tmpstr ) )
addressee.insertEmail( tmpstr );
-
+
// No kabc field for personalHomePage
- if ( WebdavHandler::extractString( node, "businesshomepage", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "businesshomepage", tmpstr ) )
addressee.setUrl( tmpstr );
if ( WebdavHandler::extractString( node, "fburl", tmpstr ) ) {
@@ -284,14 +290,14 @@ bool ExchangeConverterContact::readAddressee( const TQDomElement &node, Addresse
// General stuff:
TQStringList tmplst;
- if ( WebdavHandler::extractStringList( node, "Keywords", tmplst ) )
+ if ( WebdavHandler::extractStringList( node, "Keywords", tmplst ) )
addressee.setCategories( tmplst );
// Exchange sentitivity values:
// 0 None, 1 Personal, 2 Private, 3 Company Confidential
if ( WebdavHandler::extractLong( node, "sensitivity", tmplng ) ) {
switch( tmplng ) {
case 0: addressee.setSecrecy( KABC::Secrecy::Public ); break;
- case 1:
+ case 1:
case 2: addressee.setSecrecy( KABC::Secrecy::Private ); break;
case 3: addressee.setSecrecy( KABC::Secrecy::Confidential ); break;
default: kdWarning() << "Unknown sensitivity: " << tmplng << endl;
@@ -322,39 +328,39 @@ bool ExchangeConverterContact::readAddressee( const TQDomElement &node, Addresse
insertPhone( "callbackphone", PhoneNumber::Msg );
insertPhone( "telexnumber", PhoneNumber::Bbs );
insertPhone( "ttytddphone", PhoneNumber::Pcs );
-#undef insertPhone
+#undef insertPhone
// Addresses: Work, Home, Mailing and Other:
extractAddress( node, addressee, Address::Work | Address::Pref,
"street", "postofficebox", "l", "postalcode", "st", "co", "c" );
extractAddress( node, addressee, Address::Home,
- "homeStreet", "homepostofficebox", "homeCity", "homePostalCode",
+ "homeStreet", "homepostofficebox", "homeCity", "homePostalCode",
"homeState", "homeCountry", "homeCountrycode" );
// Exchange doesn't support writing/changing the mailing address fields,
// so don't download it. It's equal to either the home or work address anyway
/* extractAddress( node, addressee, Address::Postal,
- "mailingstreet", "mailingpostofficebox", "mailingcity", "mailingpostalcode",
+ "mailingstreet", "mailingpostofficebox", "mailingcity", "mailingpostalcode",
"mailingstate", "mailingcountry", "mailingcountrycode" );*/
extractAddress( node, addressee, 0,
- "otherstreet", "otherpostofficebox", "othercity", "otherpostalcode",
+ "otherstreet", "otherpostofficebox", "othercity", "otherpostalcode",
"otherstate", "othercountry", "othercountrycode" );
- if ( WebdavHandler::extractString( node, "nickname", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "nickname", tmpstr ) )
addressee.setNickName( tmpstr );
- if ( WebdavHandler::extractString( node, "spousecn", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "spousecn", tmpstr ) )
addressee.insertCustom( "KADDRESSBOOK", "X-SpousesName", tmpstr );
TQDateTime tmpdt;
- if ( WebdavHandler::extractDateTime( node, "bday", tmpdt ) )
+ if ( WebdavHandler::extractDateTime( node, "bday", tmpdt ) )
addressee.setBirthday( tmpdt.date() );
- if ( WebdavHandler::extractString( node, "weddinganniversary", tmpstr ) )
+ if ( WebdavHandler::extractString( node, "weddinganniversary", tmpstr ) )
addressee.insertCustom( "KADDRESSBOOK", "X-Anniversary", tmpstr );
// TODO? timeZone()
float lt,lng;
- if ( WebdavHandler::extractFloat( node, "geolatitude", lt ) &&
+ if ( WebdavHandler::extractFloat( node, "geolatitude", lt ) &&
WebdavHandler::extractFloat( node, "geolongitude", lng ) )
addressee.setGeo( Geo( lt, lng ) );
// TODO: mapurl
@@ -363,7 +369,7 @@ bool ExchangeConverterContact::readAddressee( const TQDomElement &node, Addresse
if ( WebdavHandler::extractString( node, "textdescription", tmpstr ) )
addressee.setNote( tmpstr );
-// if ( WebdavHandler::extractString( node, "usercertificate", tmpstr ) )
+// if ( WebdavHandler::extractString( node, "usercertificate", tmpstr ) )
// addressee.setKeys()
return true;
@@ -380,24 +386,24 @@ Addressee::List ExchangeConverterContact::parseWebDAV( const TQDomDocument& davd
kdDebug()<<"ExchangeConverterContact::parseWebDAV, no response->propstat->prop element!"<<endl;
return list;
}
-
+
TQString contentclass;
bool success = WebdavHandler::extractString( prop, "contentclass", contentclass );
if ( !success ) {
kdDebug()<<"ExchangeConverterContact::parseWebDAV, No contentclass entry"<<endl;
return list;
}
-
+
success = false;
Addressee addressee;
if ( contentclass == "urn:content-classes:person" ) {
success = readAddressee( prop, addressee );
- }
-
+ }
+
if ( success ) {
list.append( addressee );
} else {
-
+
}
return list;
}
@@ -420,11 +426,11 @@ TQDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
TQDomElement root = WebdavHandler::addDavElement( doc, doc, "d:propertyupdate" );
TQDomElement set = WebdavHandler::addElement( doc, root, "d:set" );
TQDomElement prop = WebdavHandler::addElement( doc, set, "d:prop" );
-
+
TQDomAttr att_c = doc.createAttribute( "xmlns:c" );
att_c.setValue( "urn:schemas:contacts:" );
doc.documentElement().setAttributeNode( att_c );
-
+
TQDomAttr att_b = doc.createAttribute( "xmlns:b" );
att_b.setValue( "urn:schemas-microsoft-com:datatypes" );
root.setAttributeNode( att_b );
@@ -433,25 +439,29 @@ TQDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
domProperty( "http://schemas.microsoft.com/exchange/",
"outlookmessageclass", "IPM.Contact" );
// domContactProperty( "uid", addr.uid() );
-
+
domContactProperty( "fileas", addr.formattedName() );
domContactProperty( "givenName", addr.givenName() );
domContactProperty( "middlename", addr.additionalName() );
domContactProperty( "sn", addr.familyName() );
domContactProperty( "namesuffix", addr.suffix() );
domContactProperty( "personaltitle", addr.prefix() );
-
+
domContactProperty( "title", addr.role() );
domContactProperty( "o", addr.organization() );
+#if KDE_IS_VERSION(3,5,8)
+ domContactProperty( "department", addr.department() );
+#else
domContactProperty( "department", addr.custom( "KADDRESSBOOK", "X-Department" ) );
+#endif
domContactProperty( "roomnumber", addr.custom( "KADDRESSBOOK", "X-Office" ) );
domContactProperty( "profession", addr.custom( "KADDRESSBOOK", "X-Profession" ) );
domContactProperty( "manager", addr.custom( "KADDRESSBOOK", "X-ManagersName" ) );
domContactProperty( "secretarycn", addr.custom( "KADDRESSBOOK", "X-AssistantsName" ) );
-
+
TQStringList emails = addr.emails();
TQString prefemail = addr.preferredEmail();
- if ( emails.contains( prefemail ) )
+ if ( emails.contains( prefemail ) )
emails.remove( prefemail );
emails.prepend( prefemail );
if ( emails.count() > 0 ) {
@@ -463,10 +473,10 @@ TQDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
if ( emails.count() > 2 ) {
domContactProperty( "email3", emails[2] );
}
-
+
// No value for "personalHomePage"
domContactProperty( "businesshomepage", addr.url().url() );
-
+
TQString fburl = KCal::FreeBusyUrlStore::self()->readUrl( addr.preferredEmail() );
if ( !fburl.isEmpty() ) {
domContactProperty( "fburl", fburl );
@@ -475,16 +485,16 @@ TQDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
/* FIXME: This doesn't work!
TQStringList cats = addr.categories();
if ( cats.isEmpty() ) {
- TQDomElement catsnode = WebdavHandler::addElementNS( doc, prop,
+ TQDomElement catsnode = WebdavHandler::addElementNS( doc, prop,
"urn:schemas-microsoft-com:office:office", "Keywords" );
for ( TQStringList::Iterator it = cats.begin(); it != cats.end(); ++it ) {
WebdavHandler::addElementNS( doc, catsnode, "xml:", "v", *it );
}
} else {
-// TQDomElement catsnode = addProperty( doc, prop,
+// TQDomElement catsnode = addProperty( doc, prop,
// "urn:schemas-microsoft-com:office:office", "Keywords", "" );
}*/
-
+
// Exchange sentitivity values:
// 0 None, 1 Personal, 2 Private, 3 Company Confidential
TQString value;
@@ -517,7 +527,7 @@ TQDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
domPhoneProperty( "telexnumber", PhoneNumber::Bbs );
domPhoneProperty( "ttytddphone", PhoneNumber::Pcs );
-
+
// work address:
Address workaddr = addr.address( Address::Work | Address::Pref );
if ( !workaddr.isEmpty() ) {
@@ -541,7 +551,7 @@ TQDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
domContactProperty( "homeCountry", homeaddr.country() );
// domContactProperty( "homeCountrycode", homeaddr.countryCode() );
}
-
+
// mailing address:
// Exchange doesn't support writing/changing the mailing address fields
/* Address mailingaddr = addr.address( Address::Postal );
@@ -566,8 +576,8 @@ TQDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
domContactProperty( "othercountry", otheraddr.country() );
// domContactProperty( "othercountrycode", otheraddr.countryCode() );
}
-
-
+
+
domContactProperty( "nickname", addr.nickName() );
domContactProperty( "spousecn", addr.custom( "KADDRESSBOOK", "X-SpousesName" ) );
@@ -606,7 +616,7 @@ TQDomDocument ExchangeConverterContact::createWebDAV( Addressee addr )
// TODO:usercertificate
// TODO: custom fields
kdDebug()<<"DOM document: "<<doc.toString() << endl;
-
+
return doc;
}
#undef domDavProperty
diff --git a/kresources/newexchange/kabc_newexchange.desktop b/kresources/newexchange/kabc_newexchange.desktop
index b829ace7..d48d30f2 100644
--- a/kresources/newexchange/kabc_newexchange.desktop
+++ b/kresources/newexchange/kabc_newexchange.desktop
@@ -20,7 +20,6 @@ Name[hu]=Exchange-kiszolgáló címjegyzéke (kísérleti)
Name[is]=Vistfangaskrá Exchange þjóni (á tilraunarstigi)
Name[it]=Rubrica indirizzi su un server Exchange (sperimentale)
Name[ja]=Exchange サーバのアドレス帳 (実験版)
-Name[ka]=წიგნაკი Exchange სერვერზე(ექსპერიმენტული)
Name[kk]=Exchange серверіндегі адрестік кітапша (сынақтағы)
Name[km]=សៀវភៅ​អាសយដ្ឋាន​លើ​ម៉ាស៊ីន​បម្រើ Exchange (សម្រាប់​អ្នក​មាន​បទពិសោធន៍)
Name[lt]=Adresų knygelė Exchange serveryje (eksperimentine tvarka)
diff --git a/kresources/newexchange/kabc_newexchange_final.desktop b/kresources/newexchange/kabc_newexchange_final.desktop
index 7069b14d..19cdda43 100644
--- a/kresources/newexchange/kabc_newexchange_final.desktop
+++ b/kresources/newexchange/kabc_newexchange_final.desktop
@@ -22,7 +22,6 @@ Name[hu]=Exchange-kiszolgáló címjegyzéke
Name[is]=Vistfangaskrá á Exchange þjóni
Name[it]=Rubrica indirizzi su un server Exchange
Name[ja]=Exchange サーバのアドレス帳
-Name[ka]=წიგნაკი Exchange სერვერზე
Name[kk]=Exchange серверіндегі адрестік кітапша
Name[km]=សៀវភៅ​អាសយដ្ឋាន​លើ​ម៉ាស៊ីន​បម្រើ Exchange
Name[lt]=Adresų knygelė Exchange serveryje
diff --git a/kresources/newexchange/kabc_resourceexchange.cpp b/kresources/newexchange/kabc_resourceexchange.cpp
index 8b32a4fa..7b08423a 100644
--- a/kresources/newexchange/kabc_resourceexchange.cpp
+++ b/kresources/newexchange/kabc_resourceexchange.cpp
@@ -26,13 +26,19 @@
#include "groupwareuploadjob.h"
#include "kresources_groupwareprefs.h"
+#include <klocale.h>
+
using namespace KABC;
ResourceExchange::ResourceExchange( const KConfig *config )
: ResourceGroupwareBase( config )
{
init();
- if ( config ) readConfig( config );
+ if ( config ) {
+ readConfig( config );
+ } else {
+ setResourceName( i18n( "Exchange Server" ) );
+ }
}
void ResourceExchange::init()
diff --git a/kresources/newexchange/kcal_newexchange.desktop b/kresources/newexchange/kcal_newexchange.desktop
index b94e28ce..a0dd29c1 100644
--- a/kresources/newexchange/kcal_newexchange.desktop
+++ b/kresources/newexchange/kcal_newexchange.desktop
@@ -20,7 +20,6 @@ Name[hu]=Exchange 2000-kiszolgáló naptára (kísérleti)
Name[is]=Dagatal á Exchange þjóni (á tilraunarstigi)
Name[it]=Calendario su un server Exchange (sperimentale)
Name[ja]=Exchange サーバのカレンダー (実験版)
-Name[ka]=კალენდარი Exchange სერვერზე (ექსპერიმენტული)
Name[kk]=Exchange серверіндегі күнтізбе (сынақтағы)
Name[km]=ប្រតិទិន​លើ​ម៉ាស៊ីន​បម្រើ Exchange (សម្រាប់​អ្នក​មាន​បទពិសោធន៍)
Name[lt]=Kalendorius Exchange serveryje (eksperimentine tvarka)
diff --git a/kresources/newexchange/kcal_newexchange_final.desktop b/kresources/newexchange/kcal_newexchange_final.desktop
index fd159051..01904c54 100644
--- a/kresources/newexchange/kcal_newexchange_final.desktop
+++ b/kresources/newexchange/kcal_newexchange_final.desktop
@@ -22,7 +22,6 @@ Name[hu]=Exchange 2000-kiszolgáló naptára
Name[is]=Dagatal á Exchange þjóni
Name[it]=Calendario su un server Exchange
Name[ja]=Exchange サーバのカレンダー
-Name[ka]=კალენდარი Exchange სერვერზე
Name[kk]=Exchange серверіндегі күнтізбе
Name[km]=ប្រតិទិន​លើ​ម៉ាស៊ីន​បម្រើ Exchange
Name[lt]=Kalendorius Exchange serveryje
diff --git a/kresources/newexchange/kcal_resourceexchange.cpp b/kresources/newexchange/kcal_resourceexchange.cpp
index 4c9f7726..37d99d37 100644
--- a/kresources/newexchange/kcal_resourceexchange.cpp
+++ b/kresources/newexchange/kcal_resourceexchange.cpp
@@ -25,6 +25,7 @@
#include <groupwaredownloadjob.h>
#include <groupwareuploadjob.h>
#include <kresources_groupwareprefs.h>
+#include <klocale.h>
using namespace KCal;
@@ -38,7 +39,11 @@ ResourceExchange::ResourceExchange( const KConfig *config )
: ResourceGroupwareBase( config )
{
init();
- if ( config ) readConfig( config );
+ if ( config ) {
+ readConfig( config );
+ } else {
+ setResourceName( i18n( "Exchange Server" ) );
+ }
}
void ResourceExchange::init()
diff --git a/kresources/remote/remote.desktop b/kresources/remote/remote.desktop
index 66a1542a..2ddebc7e 100644
--- a/kresources/remote/remote.desktop
+++ b/kresources/remote/remote.desktop
@@ -24,7 +24,6 @@ Name[hu]=Távoli fájlban tárolt naptár
Name[is]=Dagatal í fjarlægri skrá
Name[it]=Calendario in file remoto
Name[ja]=リモートファイルのカレンダー
-Name[ka]=კალენდარი გარე ფაილზე
Name[kk]=Қашықтағы файлдағы күнтізбе
Name[km]=ប្រតិទិន​នៅ​ក្នុង​ឯកសារ​នៅ​ឆ្ងាយ
Name[lt]=Kalendorius nutolusioje byloje
diff --git a/kresources/remote/resourceremote.cpp b/kresources/remote/resourceremote.cpp
index 2aceaad0..229dd86b 100644
--- a/kresources/remote/resourceremote.cpp
+++ b/kresources/remote/resourceremote.cpp
@@ -56,6 +56,8 @@ ResourceRemote::ResourceRemote( const KConfig *config )
{
if ( config ) {
readConfig( config );
+ } else {
+ setResourceName( i18n( "Remote Calendar" ) );
}
init();
diff --git a/kresources/scalix/kcal/resourcescalix.cpp b/kresources/scalix/kcal/resourcescalix.cpp
index d2849e86..63e964eb 100644
--- a/kresources/scalix/kcal/resourcescalix.cpp
+++ b/kresources/scalix/kcal/resourcescalix.cpp
@@ -510,6 +510,12 @@ bool ResourceScalix::addEvent( KCal::Event* event )
return addIncidence( event, TQString::null, 0 );
}
+bool ResourceScalix::addEvent( KCal::Event *event, const TQString &subresource )
+{
+ Q_UNUSED( subresource ); // ResourceScalix does not support subresources
+ return this->addEvent( event );
+}
+
bool ResourceScalix::deleteIncidence( KCal::Incidence* incidence )
{
if ( incidence->isReadOnly() ) return false;
@@ -572,6 +578,12 @@ bool ResourceScalix::addTodo( KCal::Todo* todo )
return addIncidence( todo, TQString::null, 0 );
}
+bool ResourceScalix::addTodo( KCal::Todo *todo, const TQString &subresource )
+{
+ Q_UNUSED( subresource ); // ResourceScalix does not support subresources
+ return this->addTodo( todo );
+}
+
bool ResourceScalix::deleteTodo( KCal::Todo* todo )
{
return deleteIncidence( todo );
@@ -600,6 +612,12 @@ bool ResourceScalix::addJournal( KCal::Journal* journal )
return addIncidence( journal, TQString::null, 0 );
}
+bool ResourceScalix::addJournal( KCal::Journal *journal, const TQString &subresource )
+{
+ Q_UNUSED( subresource ); // ResourceScalix does not support subresources
+ return this->addJournal( journal );
+}
+
bool ResourceScalix::deleteJournal( KCal::Journal* journal )
{
return deleteIncidence( journal );
diff --git a/kresources/scalix/kcal/resourcescalix.h b/kresources/scalix/kcal/resourcescalix.h
index 223161b4..11baa5ec 100644
--- a/kresources/scalix/kcal/resourcescalix.h
+++ b/kresources/scalix/kcal/resourcescalix.h
@@ -70,6 +70,7 @@ public:
// The libkcal functions. See the resource for descriptions
bool addEvent( KCal::Event* anEvent );
+ bool addEvent( KCal::Event* anEvent, const TQString &subresource );
bool deleteEvent( KCal::Event* );
KCal::Event* event( const TQString &UniqueStr );
KCal::Event::List rawEvents( EventSortField sortField = EventSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
@@ -82,12 +83,14 @@ public:
bool inclusive = false );
bool addTodo( KCal::Todo* todo );
+ bool addTodo( KCal::Todo* todo, const TQString &subresource );
bool deleteTodo( KCal::Todo* );
KCal::Todo* todo( const TQString& uid );
KCal::Todo::List rawTodos( TodoSortField sortField = TodoSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
KCal::Todo::List rawTodosForDate( const TQDate& date );
bool addJournal( KCal::Journal* );
+ bool addJournal( KCal::Journal* journal, const TQString &subresource );
bool deleteJournal( KCal::Journal* );
KCal::Journal* journal( const TQString& uid );
KCal::Journal::List rawJournals( JournalSortField sortField = JournalSortUnsorted, SortDirection sortDirection = SortDirectionAscending );
diff --git a/kresources/slox/kabc_ox.desktop b/kresources/slox/kabc_ox.desktop
index 4f4fb8c2..8388f080 100644
--- a/kresources/slox/kabc_ox.desktop
+++ b/kresources/slox/kabc_ox.desktop
@@ -18,7 +18,6 @@ Name[gl]=Servidor OpenXchange
Name[hu]=OpenXchange-kiszolgáló
Name[is]=OpenXchange þjónn
Name[ja]=OpenXchange サーバ
-Name[ka]=Openexchange სერვერი
Name[kk]=OpenXchange сервері
Name[km]=ម៉ាស៊ីន​បម្រើ OpenXchange
Name[lt]=OpenXchange serveris
diff --git a/kresources/slox/kabc_slox.desktop b/kresources/slox/kabc_slox.desktop
index bdfce204..5a0192ca 100644
--- a/kresources/slox/kabc_slox.desktop
+++ b/kresources/slox/kabc_slox.desktop
@@ -21,7 +21,6 @@ Name[hu]=SUSE LINUX Openexchange-kiszolgáló
Name[is]=SUSE LINUX Openexchange þjónn
Name[it]=Server SUSE LINUX Openexchange
Name[ja]=SUSE LINUX Openexchange サーバ
-Name[ka]= SUSE LINUX Openexchange სერვერი
Name[kk]=SUSE LINUX Openexchange сервері
Name[km]=ម៉ាស៊ីន​បម្រើ Openexchange របស់​ស៊ូស៊ីលីនីក
Name[lt]=SUSE LINUX Openexchange serveris
diff --git a/kresources/slox/kabcresourceslox.cpp b/kresources/slox/kabcresourceslox.cpp
index 757bfae0..16d5aced 100644
--- a/kresources/slox/kabcresourceslox.cpp
+++ b/kresources/slox/kabcresourceslox.cpp
@@ -49,6 +49,8 @@ ResourceSlox::ResourceSlox( const KConfig *config )
if ( config ) {
readConfig( config );
+ } else {
+ setResourceName( i18n( "OpenXchange Server" ) );
}
}
@@ -353,7 +355,11 @@ void ResourceSlox::parseContactAttribute( const TQDomElement &e, Addressee &a )
} else if ( tag == fieldName( Organization ) ) {
a.setOrganization( text );
} else if ( tag == fieldName( Department ) ) {
+#if KDE_IS_VERSION(3,5,8)
+ a.setDepartment( text );
+#else
a.insertCustom( "KADDRESSBOOK", "X-Department", text );
+#endif
} else if ( tag == fieldName( FamilyName ) ) {
a.setFamilyName( text );
} else if ( tag == fieldName( GivenName) ) {
@@ -542,8 +548,13 @@ void ResourceSlox::createAddresseeFields( TQDomDocument &doc, TQDomElement &prop
else
WebdavHandler::addSloxElement( this, doc, prop, fieldName( Birthday ) );
WebdavHandler::addSloxElement( this, doc, prop, fieldName( Role ), a.role() );
+#if KDE_IS_VERSION(3,5,8)
+ WebdavHandler::addSloxElement( this, doc, prop, fieldName( Department ),
+ a.department( ) );
+#else
WebdavHandler::addSloxElement( this, doc, prop, fieldName( Department ),
a.custom( "KADDRESSBOOK", "X-Department" ) );
+#endif
if ( type() == "ox" ) { // OX only fields
WebdavHandler::addSloxElement( this, doc, prop, fieldName( DisplayName ), a.formattedName() );
WebdavHandler::addSloxElement( this, doc, prop, fieldName( SecondName ), a.additionalName() );
diff --git a/kresources/slox/kcal_ox.desktop b/kresources/slox/kcal_ox.desktop
index e0eaa922..5bc7600a 100644
--- a/kresources/slox/kcal_ox.desktop
+++ b/kresources/slox/kcal_ox.desktop
@@ -18,7 +18,6 @@ Name[gl]=Servidor OpenXchange
Name[hu]=OpenXchange-kiszolgáló
Name[is]=OpenXchange þjónn
Name[ja]=OpenXchange サーバ
-Name[ka]=Openexchange სერვერი
Name[kk]=OpenXchange сервері
Name[km]=ម៉ាស៊ីន​បម្រើ OpenXchange
Name[lt]=OpenXchange serveris
diff --git a/kresources/slox/kcal_slox.desktop b/kresources/slox/kcal_slox.desktop
index 0daca0b2..b4fe8e7a 100644
--- a/kresources/slox/kcal_slox.desktop
+++ b/kresources/slox/kcal_slox.desktop
@@ -21,7 +21,6 @@ Name[hu]=SUSE LINUX Openexchange-kiszolgáló
Name[is]=SUSE LINUX Openexchange þjónn
Name[it]=Server SUSE LINUX Openexchange
Name[ja]=SUSE LINUX Openexchange サーバ
-Name[ka]= SUSE LINUX Openexchange სერვერი
Name[kk]=SUSE LINUX Openexchange сервері
Name[km]=ម៉ាស៊ីន​បម្រើ Openexchange របស់​ស៊ូស៊ីលីនីក
Name[lt]=SUSE LINUX Openexchange serveris
diff --git a/kresources/slox/kcalresourceslox.cpp b/kresources/slox/kcalresourceslox.cpp
index 2fcb0baa..edd13e6f 100644
--- a/kresources/slox/kcalresourceslox.cpp
+++ b/kresources/slox/kcalresourceslox.cpp
@@ -70,6 +70,8 @@ KCalResourceSlox::KCalResourceSlox( const KConfig *config )
if ( config ) {
readConfig( config );
+ } else {
+ setResourceName( i18n( "OpenXchange Server" ) );
}
}