#include #include #include #include #include #include #include #include #include #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 = KIO::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 = KIO::file_copy( m_url, destURL, -1, true, false, false ); // handling progress ourselves m_job->setAutoErrorHandlingEnabled( true ); connect( m_job, TQT_SIGNAL( result( KIO::Job * )), TQT_SLOT( slotResult( KIO::Job * ) )); connect( m_job, TQT_SIGNAL( percent( KIO::Job *, unsigned long )), TQT_SLOT( slotProgress( KIO::Job *, unsigned long ) )); // TODO: generify background/foreground downloading? return m_job != 0L; } KuickFile::DownloadtqStatus 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...").tqarg( m_url.fileName() ) ); dialog->setLabel( i18n("Please wait while downloading\n%1").tqarg( 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( KIO::Job *job ) { if (job != m_job) { // huh? return; } m_job = 0L; if ( job->error() != 0 ) { m_currentProgress = 0; if ( job->error() != KIO::ERR_USER_CANCELED ) kdWarning() << "ERROR: KuickFile::slotResult: " << job->errorString() << endl; TQString canceledFile = static_cast(job)->destURL().path(); TQFile::remove( canceledFile ); m_progress->tqtopLevelWidget()->hide(); } else { m_localFile = static_cast(job)->destURL().path(); emit downloaded( this ); // before closing the progress dialog if ( m_progress ) { m_progress->setProgress( 100 ); #define BUGGY_VERSION KDE_MAKE_VERSION(3,5,2) if ( KDE::version() <= BUGGY_VERSION ) { m_progress->tqtopLevelWidget()->hide(); // ### workaround broken KProgressDialog } } } } void KuickFile::slotProgress( KIO::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"