|
|
|
#include <tqfile.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tdeversion.h>
|
|
|
|
#include <kinstance.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kprogress.h>
|
|
|
|
#include <tdeio/job.h>
|
|
|
|
#include <tdeio/netaccess.h>
|
|
|
|
#include <ktempfile.h>
|
|
|
|
|
|
|
|
#include "filecache.h"
|
|
|
|
#include "kuickfile.h"
|
|
|
|
|
|
|
|
KuickFile::KuickFile(const KURL& url)
|
|
|
|
: TQObject(),
|
|
|
|
m_url( url ),
|
|
|
|
m_job( 0L ),
|
|
|
|
m_progress( 0L ),
|
|
|
|
m_currentProgress( 0 )
|
|
|
|
{
|
|
|
|
if ( m_url.isLocalFile())
|
|
|
|
m_localFile = m_url.path();
|
|
|
|
else {
|
|
|
|
const KURL& mostLocal = TDEIO::NetAccess::mostLocalURL( m_url, 0L );
|
|
|
|
if ( mostLocal.isValid() && mostLocal.isLocalFile() )
|
|
|
|
m_localFile = mostLocal.path();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KuickFile::~KuickFile()
|
|
|
|
{
|
|
|
|
delete m_job;
|
|
|
|
|
|
|
|
if ( hasDownloaded() )
|
|
|
|
TQFile::remove( m_localFile );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KuickFile::localFile() const
|
|
|
|
{
|
|
|
|
// Note: never call isAvailable() from here, directly or indirectly
|
|
|
|
|
|
|
|
if ( isDownloading() )
|
|
|
|
return TQString();
|
|
|
|
|
|
|
|
return m_localFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KuickFile::hasDownloaded() const
|
|
|
|
{
|
|
|
|
return !m_url.isLocalFile() && isAvailable() && m_job != 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ### need an API for refreshing the file?
|
|
|
|
bool KuickFile::download()
|
|
|
|
{
|
|
|
|
if ( m_url.isLocalFile() || isAvailable() )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if ( isDownloading() )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// reinitialize
|
|
|
|
m_localFile = TQString();
|
|
|
|
m_currentProgress = 0;
|
|
|
|
|
|
|
|
|
|
|
|
TQString ext;
|
|
|
|
TQString fileName = m_url.fileName();
|
|
|
|
int extIndex = fileName.findRev('.');
|
|
|
|
if ( extIndex > 0 )
|
|
|
|
ext = fileName.mid( extIndex + 1 );
|
|
|
|
|
|
|
|
TQString tempDir = FileCache::self()->tempDir();
|
|
|
|
KTempFile tempFile( tempDir, ext );
|
|
|
|
tempFile.setAutoDelete( tempDir.isNull() ); // in case there is no proper tempdir, make sure to delete those files!
|
|
|
|
if ( tempFile.status() != 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
tempFile.close();
|
|
|
|
if ( tempFile.status() != 0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
KURL destURL;
|
|
|
|
destURL.setPath( tempFile.name() );
|
|
|
|
|
|
|
|
m_job = TDEIO::file_copy( m_url, destURL, -1, true, false, false ); // handling progress ourselves
|
|
|
|
m_job->setAutoErrorHandlingEnabled( true );
|
|
|
|
connect( m_job, TQT_SIGNAL( result( TDEIO::Job * )), TQT_SLOT( slotResult( TDEIO::Job * ) ));
|
|
|
|
connect( m_job, TQT_SIGNAL( percent( TDEIO::Job *, unsigned long )), TQT_SLOT( slotProgress( TDEIO::Job *, unsigned long ) ));
|
|
|
|
|
|
|
|
// TODO: generify background/foreground downloading?
|
|
|
|
|
|
|
|
return m_job != 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
KuickFile::DownloadStatus KuickFile::waitForDownload( TQWidget *parent )
|
|
|
|
{
|
|
|
|
if ( isAvailable() )
|
|
|
|
return OK;
|
|
|
|
|
|
|
|
if ( !isDownloading() ) {
|
|
|
|
if ( !download() )
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
KProgressDialog *dialog = new KProgressDialog( parent );
|
|
|
|
dialog->setModal( true );
|
|
|
|
dialog->setCaption( i18n("Downloading %1...").arg( m_url.fileName() ) );
|
|
|
|
dialog->setLabel( i18n("Please wait while downloading\n%1").arg( m_url.prettyURL() ));
|
|
|
|
dialog->setAllowCancel( true );
|
|
|
|
dialog->setAutoClose( true );
|
|
|
|
|
|
|
|
m_progress = dialog->progressBar();
|
|
|
|
m_progress->setTotalSteps( 100 ); // percent
|
|
|
|
m_progress->setProgress( m_currentProgress );
|
|
|
|
dialog->exec();
|
|
|
|
bool canceled = dialog->wasCancelled();
|
|
|
|
delete dialog;
|
|
|
|
m_progress = 0L;
|
|
|
|
|
|
|
|
if ( canceled && m_job ) {
|
|
|
|
m_job->kill();
|
|
|
|
m_job = 0L;
|
|
|
|
m_currentProgress = 0;
|
|
|
|
}
|
|
|
|
// ### when aborted, remove KuickImage from FileCache?
|
|
|
|
|
|
|
|
if ( canceled )
|
|
|
|
return CANCELED;
|
|
|
|
|
|
|
|
if ( !isAvailable() )
|
|
|
|
return ERROR;
|
|
|
|
|
|
|
|
// ### use custom progress dialog with OK, SKIP, CANCEL?
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KuickFile::slotResult( TDEIO::Job *job )
|
|
|
|
{
|
|
|
|
if (job != m_job) { // huh?
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_job = 0L;
|
|
|
|
|
|
|
|
if ( job->error() != 0 ) {
|
|
|
|
m_currentProgress = 0;
|
|
|
|
|
|
|
|
if ( job->error() != TDEIO::ERR_USER_CANCELED )
|
|
|
|
kdWarning() << "ERROR: KuickFile::slotResult: " << job->errorString() << endl;
|
|
|
|
|
|
|
|
TQString canceledFile = static_cast<TDEIO::FileCopyJob*>(job)->destURL().path();
|
|
|
|
TQFile::remove( canceledFile );
|
|
|
|
m_progress->topLevelWidget()->hide();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_localFile = static_cast<TDEIO::FileCopyJob*>(job)->destURL().path();
|
|
|
|
emit downloaded( this ); // before closing the progress dialog
|
|
|
|
|
|
|
|
if ( m_progress ) {
|
|
|
|
m_progress->setProgress( 100 );
|
|
|
|
#define BUGGY_VERSION TDE_MAKE_VERSION(3,5,2)
|
|
|
|
if ( KDE::version() <= BUGGY_VERSION ) {
|
|
|
|
m_progress->topLevelWidget()->hide(); // ### workaround broken KProgressDialog
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KuickFile::slotProgress( TDEIO::Job *job, unsigned long percent )
|
|
|
|
{
|
|
|
|
if (job != m_job) { // huh?
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_currentProgress = percent;
|
|
|
|
|
|
|
|
if ( !m_progress )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// only set 100% in slotResult. Otherwise, the progress dialog would be closed
|
|
|
|
// before slotResult() is called.
|
|
|
|
if ( percent >= 100 )
|
|
|
|
percent = 99;
|
|
|
|
|
|
|
|
m_progress->setProgress( (int) percent );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==( const KuickFile& first, const KuickFile& second ) {
|
|
|
|
return first.url().equals( second.url() );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "kuickfile.moc"
|