Commit fd1242c5 authored by Bertjan Broeksema's avatar Bertjan Broeksema
Browse files

Add support for remote files in the SingleFileRecourse based resources.

svn path=/trunk/KDE/kdepim/akonadi/; revision=878442
parent 1d0641e7
......@@ -25,8 +25,10 @@
#include <akonadi/collectiondisplayattribute.h>
#include <kio/job.h>
#include <KDirWatch>
#include <KLocale>
#include <KStandardDirs>
#include <QFile>
......@@ -70,34 +72,57 @@ class SingleFileResource : public SingleFileResourceBase
return;
}
// FIXME: Make this asynchronous by using a KIO file job.
// See: http://api.kde.org/4.x-api/kdelibs-apidocs/kio/html/namespaceKIO.html
// NOTE: Test what happens with remotefile -> save, close before save is finished.
mCurrentUrl = KUrl( Settings::self()->path() );
if ( !nameWasChanged )
setName( mCurrentUrl.fileName() );
// check if the file does not exist yet, if so, create it
if ( !QFile::exists( mCurrentUrl.path() ) ) {
QFile f( mCurrentUrl.path() );
if ( f.open( QIODevice::WriteOnly ) && f.resize( 0 ) ) {
emit status( Idle, i18n( "File '%1' created.", mCurrentUrl.prettyUrl() ) );
} else {
emit status( Broken, i18n( "Could not create file '%1'.", mCurrentUrl.prettyUrl() ) );
mCurrentUrl.clear();
if ( mCurrentUrl.isLocalFile() )
{
if ( !nameWasChanged )
setName( mCurrentUrl.fileName() );
// check if the file does not exist yet, if so, create it
if ( !QFile::exists( mCurrentUrl.path() ) ) {
QFile f( mCurrentUrl.path() );
if ( f.open( QIODevice::WriteOnly ) && f.resize( 0 ) ) {
emit status( Idle, i18n( "File '%1' created.", mCurrentUrl.prettyUrl() ) );
} else {
emit status( Broken, i18n( "Could not create file '%1'.", mCurrentUrl.prettyUrl() ) );
mCurrentUrl.clear();
return;
}
}
if ( !readFromFile( mCurrentUrl.path() ) ) {
mCurrentUrl = KUrl(); // reset so we don't accidentally overwrite the file
return;
}
}
if ( !readFromFile( mCurrentUrl.path() ) ) {
mCurrentUrl = KUrl(); // reset so we don't accidentally overwrite the file
return;
if ( Settings::self()->monitorFile() )
KDirWatch::self()->addFile( mCurrentUrl.path() );
emit status( Idle, i18n( "Data loaded from '%1'.", mCurrentUrl.prettyUrl() ) );
}
else
{
if ( mDownloadJob )
{
emit error( i18n( "Another download is still in progress." ) );
return;
}
if ( mUploadJob )
{
emit error( i18n( "Uploading of another file is still in progress." ) );
return;
}
if ( Settings::self()->monitorFile() )
KDirWatch::self()->addFile( mCurrentUrl.path() );
emit status( Idle, i18n( "Data loaded from '%1'.", mCurrentUrl.prettyUrl() ) );
KGlobal::ref();
// NOTE: Test what happens with remotefile -> save, close before save is finished.
mDownloadJob = KIO::file_copy( mCurrentUrl, KUrl( cacheFile() ), -1, KIO::Overwrite | KIO::DefaultFlags );
connect( mDownloadJob, SIGNAL( result( KJob * ) ),
SLOT( slotDownloadJobResult( KJob * ) ) );
emit status( Running, i18n( "Downloading remote file." ) );
}
}
/**
......@@ -112,8 +137,6 @@ class SingleFileResource : public SingleFileResourceBase
mDirtyTimer.stop();
// FIXME: Make asynchronous.
// We don't use the Settings::self()->path() here as that might have changed
// and in that case it would probably cause data lose.
if ( mCurrentUrl.isEmpty() ) {
......@@ -121,13 +144,38 @@ class SingleFileResource : public SingleFileResourceBase
return;
}
KDirWatch::self()->stopScan();
const bool writeResult = writeToFile( mCurrentUrl.path() );
KDirWatch::self()->startScan();
if ( !writeResult )
return;
if ( mCurrentUrl.isLocalFile() ) {
KDirWatch::self()->stopScan();
const bool writeResult = writeToFile( mCurrentUrl.path() );
KDirWatch::self()->startScan();
if ( !writeResult )
return;
emit status( Idle, i18n( "Data successfully saved to '%1'.", mCurrentUrl.prettyUrl() ) );
emit status( Idle, i18n( "Data successfully saved to '%1'.", mCurrentUrl.prettyUrl() ) );
} else {
// Check if there is a download or an upload in progress.
if ( mDownloadJob ) {
emit error( i18n( "A download is still in progress." ) );
return;
}
if ( mUploadJob ) {
emit error( i18n( "Uploading of another file is still in progress." ) );
return;
}
// Write te items to the localy cached file.
if ( !writeToFile( cacheFile() ) )
return;
KGlobal::ref();
// Start a job to upload the localy cached file to the remote location.
mUploadJob = KIO::file_copy( KUrl( cacheFile() ), mCurrentUrl, -1, KIO::Overwrite | KIO::DefaultFlags );
connect( mUploadJob, SIGNAL( result( KJob * ) ),
SLOT( slotUploadJobResult( KJob * ) ) );
emit status( Running, i18n( "Uploading cached file to remote location." ) );
}
}
protected:
......
......@@ -24,6 +24,8 @@
#include <akonadi/collectiondisplayattribute.h>
#include <akonadi/itemfetchscope.h>
#include <kio/job.h>
#include <kio/jobuidelegate.h>
#include <KDebug>
#include <KDirWatch>
#include <KLocale>
......@@ -34,7 +36,7 @@
using namespace Akonadi;
SingleFileResourceBase::SingleFileResourceBase( const QString & id ) :
ResourceBase( id )
ResourceBase( id ), mDownloadJob( 0 ), mUploadJob( 0 )
{
connect( &mDirtyTimer, SIGNAL(timeout()), SLOT(writeFile()) );
mDirtyTimer.setSingleShot( true );
......@@ -48,6 +50,11 @@ SingleFileResourceBase::SingleFileResourceBase( const QString & id ) :
connect( KDirWatch::self(), SIGNAL(dirty(QString)), SLOT(fileChanged(QString)) );
}
QString SingleFileResourceBase::cacheFile() const
{
return KStandardDirs::locateLocal( "cache", "akonadi/" + identifier() );
}
void SingleFileResourceBase::setSupportedMimetypes(const QStringList & mimeTypes, const QString &icon)
{
mSupportedMimetypes = mimeTypes;
......@@ -102,4 +109,30 @@ void SingleFileResourceBase::fileChanged(const QString & fileName)
synchronize();
}
void SingleFileResourceBase::slotDownloadJobResult( KJob *job )
{
if ( job->error() ) {
static_cast<KIO::Job*>(job)->ui()->showErrorMessage();
emit status( Broken, i18n( "Could not load file '%1'.", mCurrentUrl.prettyUrl() ) );
} else {
readFromFile( KUrl( cacheFile() ).url() );
}
mDownloadJob = 0;
KGlobal::deref();
}
void SingleFileResourceBase::slotUploadJobResult( KJob *job )
{
if ( job->error() ) {
static_cast<KIO::Job*>(job)->ui()->showErrorMessage();
emit status( Broken, i18n( "Could not save file '%1'.", mCurrentUrl.prettyUrl() ) );
} else {
emit status( Idle, i18n( "Data successfully saved to '%1'.", mCurrentUrl.prettyUrl() ) );
}
mUploadJob = 0;
KGlobal::deref();
}
#include "singlefileresourcebase.moc"
......@@ -26,6 +26,11 @@
#include <QtCore/QStringList>
#include <QtCore/QTimer>
namespace KIO {
class FileCopyJob;
class Job;
}
namespace Akonadi
{
......@@ -66,14 +71,24 @@ class SingleFileResourceBase : public ResourceBase, public Akonadi::AgentBase::O
*/
virtual bool writeToFile( const QString &fileName ) = 0;
/**
* Generates the full path for the cache file in the case that a remote file
* is used.
*/
QString cacheFile() const;
protected:
QTimer mDirtyTimer;
KUrl mCurrentUrl;
QStringList mSupportedMimetypes;
QString mCollectionIcon;
KIO::FileCopyJob *mDownloadJob;
KIO::FileCopyJob *mUploadJob;
private Q_SLOTS:
void fileChanged( const QString &fileName );
void slotDownloadJobResult( KJob * );
void slotUploadJobResult( KJob * );
};
}
......
......@@ -31,6 +31,7 @@ SingleFileResourceConfigDialogBase::SingleFileResourceConfigDialogBase( WId wind
KDialog()
{
ui.setupUi( mainWidget() );
ui.kcfg_Path->setMode( KFile::File );
setButtons( Ok | Cancel );
if ( windowId )
......@@ -68,9 +69,9 @@ void SingleFileResourceConfigDialogBase::validate()
ui.kcfg_ReadOnly->setEnabled( true );
}
enableButton( Ok, true );
} else {
} else {
ui.kcfg_MonitorFile->setEnabled( false );
// ### temporary until we support remote files
enableButton( Ok, false );
// TODO: Check if remote server supports writing.
enableButton( Ok, true );
}
}
......@@ -60,7 +60,6 @@ bool VCardResource::retrieveItem( const Akonadi::Item &item, const QSet<QByteArr
void VCardResource::aboutToQuit()
{
// TODO: we need to delay termination whehn writeToFile() becomes async!
writeFile();
Settings::self()->writeConfig();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment