summaryrefslogtreecommitdiffstats
path: root/kresources/lib/kcal_resourcegroupwarebase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kresources/lib/kcal_resourcegroupwarebase.cpp')
-rw-r--r--kresources/lib/kcal_resourcegroupwarebase.cpp410
1 files changed, 410 insertions, 0 deletions
diff --git a/kresources/lib/kcal_resourcegroupwarebase.cpp b/kresources/lib/kcal_resourcegroupwarebase.cpp
new file mode 100644
index 000000000..aaf471218
--- /dev/null
+++ b/kresources/lib/kcal_resourcegroupwarebase.cpp
@@ -0,0 +1,410 @@
+/*
+ This file is part of kdepim.
+
+ Copyright (c) 2004 Cornelius Schumacher <[email protected]>
+ Copyright (c) 2004 Till Adam <[email protected]>
+ Copyright (c) 2005 Reinhold Kainhofer <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kcal_resourcegroupwarebase.h"
+#include "kresources_groupwareprefs.h"
+
+#include "libkcal/confirmsavedialog.h"
+#include "folderlister.h"
+#include "calendaradaptor.h"
+#include "groupwaredownloadjob.h"
+#include "groupwareuploadjob.h"
+
+#include <libkcal/icalformat.h>
+#include <kio/job.h>
+#include <klocale.h>
+
+#include <qapplication.h>
+
+using namespace KCal;
+
+ResourceGroupwareBase::ResourceGroupwareBase()
+ : 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),
+ mLock( true ), mAdaptor(0), mDownloadJob(0), mUploadJob(0)
+{
+ if ( config ) readConfig( config );
+}
+
+ResourceGroupwareBase::~ResourceGroupwareBase()
+{
+ disableChangeNotification();
+
+ delete mPrefs;
+ mPrefs = 0;
+}
+
+KPIM::GroupwarePrefsBase *ResourceGroupwareBase::createPrefs()
+{
+ return new KPIM::GroupwarePrefsBase();
+}
+
+
+bool ResourceGroupwareBase::addEvent( Event *event )
+{
+ if ( adaptor() && ( adaptor()->supports( KPIM::FolderLister::Event ) ||
+ adaptor()->supports( KPIM::FolderLister::All ) ) ) {
+ return ResourceCached::addEvent( event );
+ } else return false;
+}
+
+bool ResourceGroupwareBase::addTodo( Todo *todo )
+{
+ if ( adaptor() && ( adaptor()->supports( KPIM::FolderLister::Todo ) ||
+ adaptor()->supports( KPIM::FolderLister::All ) ) ) {
+ return ResourceCached::addTodo( todo );
+ } else return false;
+}
+
+bool ResourceGroupwareBase::addJournal( Journal *journal )
+{
+ if ( adaptor() && ( adaptor()->supports( KPIM::FolderLister::Journal ) ||
+ adaptor()->supports( KPIM::FolderLister::All ) ) ) {
+ return ResourceCached::addJournal( journal );
+ } else return false;
+}
+
+
+KPIM::GroupwareDownloadJob *ResourceGroupwareBase::createDownloadJob(
+ CalendarAdaptor *adaptor )
+{
+ return new KPIM::GroupwareDownloadJob( adaptor );
+}
+
+KPIM::GroupwareUploadJob *ResourceGroupwareBase::createUploadJob(
+ CalendarAdaptor *adaptor )
+{
+ return new KPIM::GroupwareUploadJob( adaptor );
+}
+
+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 );
+}
+
+void ResourceGroupwareBase::setFolderLister( KPIM::FolderLister *folderLister )
+{
+ if ( !folderLister ) return;
+ if ( mFolderLister ) delete mFolderLister;
+ mFolderLister = folderLister;
+ if ( mPrefs ) mFolderLister->readConfig( mPrefs );
+ if ( adaptor() ) {
+ adaptor()->setFolderLister( mFolderLister );
+ mFolderLister->setAdaptor( adaptor() );
+ }
+}
+
+void ResourceGroupwareBase::setAdaptor( CalendarAdaptor *adaptor )
+{
+ if ( !adaptor ) return;
+ if ( mAdaptor ) delete mAdaptor;
+ mAdaptor = adaptor;
+ mAdaptor->setFolderLister( mFolderLister );
+ if ( mFolderLister ) mFolderLister->setAdaptor( mAdaptor );
+ // TODO: Set the prgreess status in the up/download jobs, and set
+ // the resource name as the label. This should be done in the
+ // up/download jobs, but these don't have access to the resource's
+ // name, do they?
+/* mAdaptor->setDownloadProgressMessage( i18n("Downloading calendar") );
+ mAdaptor->setUploadProgressMessage( i18n("Uploading calendar") );*/
+ if ( prefs() ) {
+ mAdaptor->setBaseURL( prefs()->url() );
+ mAdaptor->setUser( prefs()->user() );
+ mAdaptor->setPassword( prefs()->password() );
+ }
+ mAdaptor->setIdMapper( &idMapper() );
+ mAdaptor->setResource( this );
+}
+
+void ResourceGroupwareBase::init()
+{
+ mDownloadJob = 0;
+ mIsShowingError = false;
+
+ enableChangeNotification();
+}
+
+KPIM::GroupwarePrefsBase *ResourceGroupwareBase::prefs()
+{
+ return mPrefs;
+}
+
+void ResourceGroupwareBase::readConfig( const KConfig *config )
+{
+ kdDebug(5800) << "KCal::ResourceGroupwareBase::readConfig()" << endl;
+ ResourceCached::readConfig( config );
+ if ( mPrefs ) {
+ mPrefs->readConfig();
+ if ( mFolderLister )
+ mFolderLister->readConfig( mPrefs );
+ }
+}
+
+void ResourceGroupwareBase::writeConfig( KConfig *config )
+{
+ kdDebug(5800) << "KCal::ResourceGroupwareBase::writeConfig()" << endl;
+
+ ResourceCalendar::writeConfig( config );
+ ResourceCached::writeConfig( config );
+
+ if ( mPrefs ) {
+ if ( mFolderLister )
+ mFolderLister->writeConfig( mPrefs );
+ mPrefs->writeConfig();
+ }
+}
+
+bool ResourceGroupwareBase::doOpen()
+{
+ if ( !adaptor() )
+ return false;
+ if ( adaptor()->flags() & KPIM::GroupwareDataAdaptor::GWResNeedsLogon ) {
+ KIO::Job *loginJob = adaptor()->createLoginJob( prefs()->url(), prefs()->user(), prefs()->password() );
+ if ( !loginJob ) {
+ return false;
+ } else {
+ mLoginFinished = false;
+ connect( loginJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotLoginJobResult( KIO::Job* ) ) );
+ enter_loop();
+ return mLoginFinished;
+ }
+ }
+ return true;
+}
+
+// BEGIN:COPIED
+// TODO: Get rid of this hack, which is copied from KIO::NetAccess, which is
+// LGPL'ed and
+// Copyright (C) 1997 Torben Weis ([email protected])
+// Copyright (C) 1998 Matthias Ettrich ([email protected])
+// Copyright (C) 1999 David Faure ([email protected])
+// If a troll sees this, he kills me
+void qt_enter_modal( QWidget *widget );
+void qt_leave_modal( QWidget *widget );
+
+void ResourceGroupwareBase::enter_loop()
+{
+ QWidget dummy(0,0,WType_Dialog | WShowModal);
+ dummy.setFocusPolicy( QWidget::NoFocus );
+ qt_enter_modal(&dummy);
+ qApp->enter_loop();
+ qt_leave_modal(&dummy);
+}
+// END:COPIED
+
+void ResourceGroupwareBase::slotLoginJobResult( KIO::Job *job )
+{
+ if ( !adaptor() ) return;
+ mLoginFinished = adaptor()->interpretLoginJobResult( job );
+ qApp->exit_loop();
+}
+
+void ResourceGroupwareBase::doClose()
+{
+ ResourceCached::doClose();
+ if ( mDownloadJob ) mDownloadJob->kill();
+
+ if ( adaptor() &&
+ adaptor()->flags() & KPIM::GroupwareDataAdaptor::GWResNeedsLogoff ) {
+ KIO::Job *logoffJob = adaptor()->createLogoffJob( prefs()->url(), prefs()->user(), prefs()->password() );
+ connect( logoffJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotLogoffJobResult( KIO::Job* ) ) );
+ // TODO: Do we really need to block while waiting for the job to return?
+ enter_loop();
+ }
+}
+
+void ResourceGroupwareBase::slotLogoffJobResult( KIO::Job *job )
+{
+ if ( !adaptor() ) return;
+ adaptor()->interpretLogoffJobResult( job );
+ // TODO: Do we really need to block while waiting for the job to return?
+ qApp->exit_loop();
+}
+
+bool ResourceGroupwareBase::doLoad()
+{
+ kdDebug(5800) << "ResourceGroupwareBase::load()" << endl;
+
+ if ( mIsShowingError ) {
+ kdDebug(5800) << "Still showing error" << endl;
+ return true;
+ }
+
+ if ( mDownloadJob ) {
+ kdWarning() << "Download still in progress" << endl;
+ return false;
+ }
+
+ mCalendar.close();
+ clearChanges();
+ disableChangeNotification();
+ loadCache();
+ enableChangeNotification();
+ emit resourceChanged( this );
+
+ mDownloadJob = createDownloadJob( adaptor() );
+ connect( mDownloadJob, SIGNAL( result( KPIM::GroupwareJob * ) ),
+ SLOT( slotDownloadJobResult( KPIM::GroupwareJob * ) ) );
+
+ return true;
+}
+
+void ResourceGroupwareBase::slotDownloadJobResult( KPIM::GroupwareJob *job )
+{
+ kdDebug(5800) << "ResourceGroupwareBase::slotJobResult(): " << endl;
+
+ if ( job->error() ) {
+ mIsShowingError = true;
+ loadError( job->errorString() );
+ mIsShowingError = false;
+ } else {
+ kdDebug(5800) << "Successfully downloaded data" << endl;
+
+ clearChanges();
+ saveCache();
+ enableChangeNotification();
+
+ emit resourceChanged( this );
+ emit resourceLoaded( this );
+ }
+
+ mDownloadJob = 0;
+}
+
+bool ResourceGroupwareBase::doSave()
+{
+ kdDebug(5800) << "KCal::ResourceGroupwareBase::doSave()" << endl;
+
+ saveCache();
+
+ if ( !hasChanges() ) {
+ kdDebug(5800) << "No changes" << endl;
+ return true;
+ }
+ // TODO: Implement confirming of single changes i.e. it should be possible
+ // 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.
+ if ( !confirmSave() ) return false;
+
+ mUploadJob = createUploadJob( adaptor() );
+ connect( mUploadJob, SIGNAL( result( KPIM::GroupwareJob * ) ),
+ SLOT( slotUploadJobResult( KPIM::GroupwareJob * ) ) );
+
+ Incidence::List inc;
+ Incidence::List::Iterator it;
+ KPIM::GroupwareUploadItem::List addedItems, changedItems, deletedItems;
+
+ inc = addedIncidences();
+ for( it = inc.begin(); it != inc.end(); ++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
+ // on the server
+ inc = changedIncidences();
+ for( it = inc.begin(); it != inc.end(); ++it ) {
+ changedItems.append( adaptor()->newUploadItem( *it,
+ KPIM::GroupwareUploadItem::Changed ) );
+ }
+ inc = deletedIncidences();
+ for( it = inc.begin(); it != inc.end(); ++it ) {
+ deletedItems.append( adaptor()->newUploadItem( *it,
+ KPIM::GroupwareUploadItem::Deleted ) );
+ }
+
+ mUploadJob->setAddedItems( addedItems );
+ mUploadJob->setChangedItems( changedItems );
+ mUploadJob->setDeletedItems( deletedItems );
+
+ // FIXME: Calling clearChanges() here is not the ideal way since the
+ // upload might fail, but there is no other place to call it...
+ clearChanges();
+ return true;
+}
+
+void ResourceGroupwareBase::slotUploadJobResult( KPIM::GroupwareJob *job )
+{
+ kdDebug(5800) << "ResourceGroupwareBase::slotUploadJobResult(): " << endl;
+
+ if ( job->error() ) {
+ mIsShowingError = true;
+ loadError( job->errorString() );
+ 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.
+ */
+
+ if ( !mDownloadJob ) {
+ mDownloadJob = createDownloadJob( adaptor() );
+ connect( mDownloadJob, SIGNAL( result( KPIM::GroupwareJob * ) ),
+ SLOT( slotDownloadJobResult( KPIM::GroupwareJob * ) ) );
+ } else {
+ kdWarning() << k_funcinfo << "Download still in progress. "
+ "Can't happen. (TM)" << endl;
+ }
+ }
+
+ mDownloadJob = 0;
+}
+
+// FIXME: Put this into ResourceCached
+bool ResourceGroupwareBase::confirmSave()
+{
+ if ( !hasChanges() ) return true;
+
+ ConfirmSaveDialog dlg( resourceName(), 0 );
+
+ dlg.addIncidences( addedIncidences(), i18n("Added") );
+ dlg.addIncidences( changedIncidences(), i18n("Changed") );
+ dlg.addIncidences( deletedIncidences(), i18n("Deleted") );
+
+ int result = dlg.exec();
+ return result == QDialog::Accepted;
+}
+
+KABC::Lock *ResourceGroupwareBase::lock()
+{
+ return &mLock;
+}
+
+#include "kcal_resourcegroupwarebase.moc"