You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/kresources/lib/kcal_resourcegroupwarebase.cpp

411 lines
12 KiB

/*
This file is part of kdepim.
Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
Copyright (c) 2004 Till Adam <adam@kde.org>
Copyright (c) 2005 Reinhold Kainhofer <reinhold@kainhofer.com>
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 <tqapplication.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, TQString() );
} else return false;
}
bool ResourceGroupwareBase::addTodo( Todo *todo )
{
if ( adaptor() && ( adaptor()->supports( KPIM::FolderLister::Todo ) ||
adaptor()->supports( KPIM::FolderLister::All ) ) ) {
return ResourceCached::addTodo( todo, TQString() );
} else return false;
}
bool ResourceGroupwareBase::addJournal( Journal *journal )
{
if ( adaptor() && ( adaptor()->supports( KPIM::FolderLister::Journal ) ||
adaptor()->supports( KPIM::FolderLister::All ) ) ) {
return ResourceCached::addJournal( journal, TQString() );
} 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, TQT_SIGNAL( result( KIO::Job * ) ),
TQT_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 (weis@kde.org)
// Copyright (C) 1998 Matthias Ettrich (ettrich@kde.org)
// Copyright (C) 1999 David Faure (faure@kde.org)
// If a troll sees this, he kills me
void qt_enter_modal( TQWidget *widget );
void qt_leave_modal( TQWidget *widget );
void ResourceGroupwareBase::enter_loop()
{
TQWidget dummy(0,0,WType_Dialog | WShowModal);
dummy.setFocusPolicy( TQWidget::NoFocus );
qt_enter_modal(&dummy);
tqApp->enter_loop();
qt_leave_modal(&dummy);
}
// END:COPIED
void ResourceGroupwareBase::slotLoginJobResult( KIO::Job *job )
{
if ( !adaptor() ) return;
mLoginFinished = adaptor()->interpretLoginJobResult( job );
tqApp->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, TQT_SIGNAL( result( KIO::Job * ) ),
TQT_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?
tqApp->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, TQT_SIGNAL( result( KPIM::GroupwareJob * ) ),
TQT_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, TQT_SIGNAL( result( KPIM::GroupwareJob * ) ),
TQT_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, TQT_SIGNAL( result( KPIM::GroupwareJob * ) ),
TQT_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 == TQDialog::Accepted;
}
KABC::Lock *ResourceGroupwareBase::lock()
{
return &mLock;
}
#include "kcal_resourcegroupwarebase.moc"