#include #include #include #include #include #include #include DownloadItem::DownloadItem() { } DownloadItem::~DownloadItem() { dequeue(); } bool DownloadItem::isDownloaded() const { return true; } TQString DownloadItem::localFilename() const { return mLocalFilename; } void DownloadItem::setLocalFilename(const TQString &filename) { mLocalFilename=filename; } void DownloadItem::downloadFinished() { } void DownloadItem::downloaded(int ) { } void DownloadItem::downloadTimeout() { } bool DownloadItem::enqueue(const KURL &url) { if (url.isLocalFile()) { setLocalFilename(url.path()); return false; } else { napp->downloader()->enqueue(this, url); return true; } } void DownloadItem::dequeue() { napp->downloader()->dequeue(this); } Downloader::Downloader(TQObject *parent) : TQObject(parent), localfile(0), current(0), mJob(0), mTimeout(0) { mStarted=false; mUnstartedQueue=new TQPtrList; } Downloader::~Downloader() { } void Downloader::start() { assert(!mStarted); mStarted=true; if (current) emit enqueued(current->notifier, current->file); for (TQPtrListIterator i(*mUnstartedQueue); i.current(); ++i) { (*i)->notifier->mLocalFilename = (*i)->local; mQueue.append(*i); emit enqueued((*i)->notifier, (*i)->file); } delete mUnstartedQueue; mUnstartedQueue=0; TQTimer::singleShot(0, this, TQT_SLOT(getNext())); } static TQString nonExistantFile(const TQString &file) { if (file.right(1)=="/") return i18n("Unknown"); int i=0; TQString f(file); while (TQFile(f).exists()) { i++; f=file; f.insert(f.findRev('.'), '_'+TQString::number(i)); } return f; } TQString Downloader::enqueue(DownloadItem *notifier, const KURL &file) { if (file.isLocalFile()) return 0; QueueItem *i=new QueueItem; i->notifier=notifier; i->file=file; if (!mStarted) { i->local=notifier->mLocalFilename; if (!notifier->localFilename().length()) { i->local = nonExistantFile(napp->saveDirectory()+'/'+file.fileName()); } mUnstartedQueue->append(i); return i->local; } if (!notifier->localFilename().length()) { notifier->mLocalFilename= i->local = nonExistantFile(napp->saveDirectory()+'/'+file.fileName()); } else { i->local = notifier->mLocalFilename; } mQueue.append(i); TQTimer::singleShot(0, this, TQT_SLOT(getNext())); emit enqueued(notifier, file); return i->local; } void Downloader::dequeue(DownloadItem *notifier) { if (current && notifier==current->notifier) { mJob->kill(); jobDone(mJob); return; } for (TQPtrListIterator i(mQueue); i.current(); ++i) { if ((*i)->notifier==notifier) { mQueue.removeRef(*i); if (mStarted) emit dequeued(notifier); delete *i; return; } } } void Downloader::getNext() { if (current) return; if (!mStarted) return; if (mQueue.isEmpty()) return; current=mQueue.take(0); // open the TQFile localfile=new TQFile(current->local); localfile->open(IO_ReadWrite | IO_Append); mJob= TDEIO::get(current->file, true, false); connect(mJob, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)), TQT_SLOT(data(TDEIO::Job*, const TQByteArray&))); connect(mJob, TQT_SIGNAL(result(TDEIO::Job*)), TQT_SLOT(jobDone(TDEIO::Job*))); connect(mJob, TQT_SIGNAL(percent(TDEIO::Job*, unsigned long)), TQT_SLOT(percent(TDEIO::Job*, unsigned long))); if (mTimeout) delete mTimeout; mTimeout=new TQTimer(this); mTimeout->start(30000, true); connect(mTimeout, TQT_SIGNAL(timeout()), TQT_SLOT(giveUpWithThisDownloadServerIsRunningNT())); } void Downloader::data(TDEIO::Job *, const TQByteArray &data) { localfile->writeBlock(data); localfile->flush(); delete mTimeout; mTimeout=0; } void Downloader::jobDone(TDEIO::Job *) { delete mTimeout; mTimeout=0; current->notifier->downloadFinished(); if (mStarted) emit dequeued(current->notifier); delete current; current=0; mJob=0; getNext(); } void Downloader::giveUpWithThisDownloadServerIsRunningNT() { delete mTimeout; mTimeout=0; if (!current) return; DownloadItem *old=current->notifier; if (!old) return; old->downloadTimeout(); current=0; mJob=0; delete old; getNext(); } void Downloader::percent( TDEIO::Job *, unsigned long percent) { if (current && current->notifier) current->notifier->downloaded((int)percent); } #include "downloader.moc"