• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdenetwork
  • Sitemap
  • Contact Us
 

kget

kget.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002 
00003    Copyright (C) 2005 Dario Massarin <nekkar@libero.it>
00004    Copyright (C) 2007 Lukas Appelhans <l.appelhans@gmx.de>
00005 
00006    This program is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 */
00011 
00012 #include "core/kget.h"
00013 
00014 #include "mainwindow.h"
00015 #include "core/transfer.h"
00016 #include "core/transfergroup.h"
00017 #include "core/transfergrouphandler.h"
00018 #include "core/transfertreemodel.h"
00019 #include "core/transfertreeselectionmodel.h"
00020 #include "core/plugin/plugin.h"
00021 #include "core/plugin/transferfactory.h"
00022 #include "core/observer.h"
00023 #include "settings.h"
00024 
00025 #include <kio/netaccess.h>
00026 #include <kinputdialog.h>
00027 #include <kfiledialog.h>
00028 #include <kmessagebox.h>
00029 #include <klocale.h>
00030 #include <kstandarddirs.h>
00031 #include <kservicetypetrader.h>
00032 #include <kiconloader.h>
00033 #include <kactioncollection.h>
00034 #include <kio/renamedialog.h>
00035 #include <KPassivePopup>
00036 #include <KSystemTrayIcon>
00037 
00038 #include <QTextStream>
00039 #include <QDomElement>
00040 #include <QApplication>
00041 #include <QClipboard>
00042 #include <QAbstractItemView>
00043 
00054 KGet& KGet::self( MainWindow * mainWindow )
00055 {
00056     if(mainWindow)
00057     {
00058         m_mainWindow = mainWindow;
00059     }
00060 
00061     static KGet m;
00062     return m;
00063 }
00064 
00065 void KGet::addObserver(ModelObserver * observer)
00066 {
00067     kDebug(5001);
00068 
00069     m_observers.append(observer);
00070 
00071     //Update the new observer with the TransferGroups objects of the model
00072     QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
00073     QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
00074 
00075     for( ; it!=itEnd ; ++it )
00076     {
00077         postAddedTransferGroupEvent(*it, observer);
00078     }
00079 
00080     kDebug(5001) << " >>> EXITING";
00081 }
00082 
00083 void KGet::delObserver(ModelObserver * observer)
00084 {
00085     m_observers.removeAll(observer);
00086 }
00087 
00088 bool KGet::addGroup(const QString& groupName)
00089 {
00090     kDebug(5001);
00091 
00092     // Check if a group with that name already exists
00093     if(m_transferTreeModel->findGroup(groupName))
00094         return false;
00095 
00096     TransferGroup * group = new TransferGroup(m_transferTreeModel, m_scheduler, groupName);
00097     m_transferTreeModel->addGroup(group);
00098 
00099     //post notifications
00100     postAddedTransferGroupEvent(group);
00101 
00102     return true;
00103 }
00104 
00105 void KGet::delGroup(const QString& groupName)
00106 {
00107     TransferGroup * group = m_transferTreeModel->findGroup(groupName);
00108 
00109     if(group)
00110     {
00111         m_transferTreeModel->delGroup(group);
00112         postRemovedTransferGroupEvent(group);
00113         delete(group);
00114     }
00115 }
00116 
00117 void KGet::renameGroup(const QString& oldName, const QString& newName)
00118 {
00119     TransferGroup *group = m_transferTreeModel->findGroup(oldName);
00120 
00121     if(group)
00122     {
00123         group->handler()->setName(newName);
00124     }
00125 }
00126 
00127 QStringList KGet::transferGroupNames()
00128 {
00129     QStringList names;
00130 
00131     foreach(TransferGroup *group, m_transferTreeModel->transferGroups()) {
00132         names << group->name();
00133     }
00134 
00135     return names;
00136 }
00137 
00138 void KGet::addTransfer(KUrl srcUrl, QString destDir, // krazy:exclude=passbyvalue
00139                        const QString& groupName, bool start)
00140 {
00141     kDebug(5001) << "Source:" << srcUrl.url();
00142 
00143     KUrl destUrl;
00144 
00145     if ( srcUrl.isEmpty() )
00146     {
00147         //No src location: we let the user insert it manually
00148         srcUrl = urlInputDialog();
00149         if( srcUrl.isEmpty() )
00150             return;
00151     }
00152 
00153     if ( !isValidSource( srcUrl ) )
00154         return;
00155 
00156     if (destDir.isEmpty())
00157     {
00158         if (Settings::useDefaultDirectory())
00159 #ifdef Q_OS_WIN //krazy:exclude=cpp
00160             destDir = Settings::defaultDirectory().remove("file:///");
00161 #else
00162             destDir = Settings::defaultDirectory().remove("file://");
00163 #endif
00164 
00165         QString checkExceptions = getSaveDirectoryFromExceptions(srcUrl);
00166         if (Settings::enableExceptions() && !checkExceptions.isEmpty())
00167             destDir = checkExceptions;
00168     }
00169 
00170     if (!isValidDestDirectory(destDir))
00171         destDir = destInputDialog();
00172 
00173     if( (destUrl = getValidDestUrl( destDir, srcUrl )).isEmpty() )
00174         return;
00175 
00176     if(m_transferTreeModel->findTransferByDestination(destUrl) != 0 || (destUrl.isLocalFile() && QFile::exists(destUrl.path()))) {
00177         KIO::RenameDialog dlg( m_mainWindow, i18n("Rename transfer"), srcUrl,
00178                                destUrl, KIO::M_MULTI);
00179         if (dlg.exec() == KIO::R_RENAME)
00180             destUrl = dlg.newDestUrl();
00181         else
00182             return;
00183     }
00184     createTransfer(srcUrl, destUrl, groupName, start);
00185 }
00186 
00187 void KGet::addTransfer(const QDomElement& e, const QString& groupName)
00188 {
00189     //We need to read these attributes now in order to know which transfer
00190     //plugin to use.
00191     KUrl srcUrl = KUrl( e.attribute("Source") );
00192     KUrl destUrl = KUrl( e.attribute("Dest") );
00193 
00194     kDebug(5001) << " src= " << srcUrl.url()
00195               << " dest= " << destUrl.url() 
00196               << " group= "<< groupName << endl;
00197 
00198     if ( srcUrl.isEmpty() || !isValidSource(srcUrl) 
00199          || !isValidDestDirectory(destUrl.directory()) )
00200         return;
00201 
00202     createTransfer(srcUrl, destUrl, groupName, false, &e);
00203 }
00204 
00205 void KGet::addTransfer(KUrl::List srcUrls, QString destDir, // krazy:exclude=passbyvalue
00206                        const QString& groupName, bool start)
00207 {
00208     KUrl::List urlsToDownload;
00209 
00210     KUrl::List::ConstIterator it = srcUrls.begin();
00211     KUrl::List::ConstIterator itEnd = srcUrls.end();
00212 
00213     for(; it!=itEnd ; ++it)
00214     {
00215         if ( isValidSource( *it ) )
00216             urlsToDownload.append( *it );
00217     }
00218 
00219     if ( urlsToDownload.count() == 0 )
00220         return;
00221 
00222     if ( urlsToDownload.count() == 1 )
00223     {
00224         // just one file -> ask for filename
00225         addTransfer(srcUrls.first(), destDir, groupName, start);
00226         return;
00227     }
00228 
00229     KUrl destUrl;
00230 
00231     // multiple files -> ask for directory, not for every single filename
00232     if (!isValidDestDirectory(destDir) && !Settings::useDefaultDirectory())
00233         destDir = destInputDialog();
00234 
00235     it = urlsToDownload.begin();
00236     itEnd = urlsToDownload.end();
00237 
00238     for ( ; it != itEnd; ++it )
00239     {
00240         if (destDir.isEmpty())
00241         {
00242             if (Settings::useDefaultDirectory())
00243 #ifdef Q_OS_WIN //krazy:exclude=cpp
00244                 destDir = Settings::defaultDirectory().remove("file:///");
00245 #else
00246                 destDir = Settings::defaultDirectory().remove("file://");
00247 #endif
00248 
00249             QString checkExceptions = getSaveDirectoryFromExceptions(*it);
00250             if (Settings::enableExceptions() && !checkExceptions.isEmpty())
00251                 destDir = checkExceptions;
00252         }
00253         destUrl = getValidDestUrl(destDir, *it);
00254 
00255         if(!isValidDestUrl(destUrl))
00256             continue;
00257 
00258         createTransfer(*it, destUrl, groupName, start);
00259     }
00260 }
00261 
00262 
00263 void KGet::delTransfer(TransferHandler * transfer)
00264 {
00265     Transfer * t = transfer->m_transfer;
00266 
00267     m_transferTreeModel->delTransfer(t);
00268 
00269     if (t->status() != Job::Finished)//if the transfer is not finished, we delete the *.part-file
00270     {
00271         QString dest = t->dest().url() + ".part";
00272         kDebug(5001) << dest;
00273         QFile destFile(dest.remove("file://"));
00274         destFile.remove();
00275     }//TODO: Ask the user if he/she wants to delete the *.part-file? To discuss (boom1992)
00276 
00277     //Here I delete the Transfer. The other possibility is to move it to a list
00278     //and to delete all these transfers when kget gets closed. Obviously, after
00279     //the notification to the views that the transfer has been removed, all the
00280     //pointers to it are invalid.
00281     transfer->postDeleteEvent();
00282 // TODO: why does it crash if a download is going to be deleted which is not the last in the list?
00283 // there are always no problems with the last download.
00284 //     delete( t );
00285 }
00286 
00287 void KGet::moveTransfer(TransferHandler * transfer, const QString& groupName)
00288 {
00289   Q_UNUSED(transfer);
00290   Q_UNUSED(groupName);
00291 }
00292 
00293 QList<TransferHandler *> KGet::selectedTransfers()
00294 {
00295 //     kDebug(5001) << "KGet::selectedTransfers";
00296 
00297     QList<TransferHandler *> selectedTransfers;
00298 
00299     QModelIndexList selectedIndexes = m_selectionModel->selectedRows();
00300 
00301     foreach(QModelIndex currentIndex, selectedIndexes)
00302     {
00303         if(!m_transferTreeModel->isTransferGroup(currentIndex))
00304             selectedTransfers.append(static_cast<TransferHandler *> (currentIndex.internalPointer()));
00305     }
00306 
00307     return selectedTransfers;
00308 
00309 
00310 // This is the code that was used in the old selectedTransfers function
00311 /*    QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
00312     QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
00313 
00314     for( ; it!=itEnd ; ++it )
00315     {
00316         TransferGroup::iterator it2 = (*it)->begin();
00317         TransferGroup::iterator it2End = (*it)->end();
00318 
00319         for( ; it2!=it2End ; ++it2 )
00320         {
00321             Transfer * transfer = (Transfer*) *it2;
00322 
00323             if( transfer->isSelected() )
00324                 selectedTransfers.append( transfer->handler() );
00325         }
00326     }
00327     return selectedTransfers;*/
00328 }
00329 
00330 QList<TransferGroupHandler *> KGet::selectedTransferGroups()
00331 {
00332     QList<TransferGroupHandler *> selectedTransferGroups;
00333 
00334     QModelIndexList selectedIndexes = m_selectionModel->selectedRows();
00335 
00336     foreach(QModelIndex currentIndex, selectedIndexes)
00337     {
00338         if(m_transferTreeModel->isTransferGroup(currentIndex))
00339             selectedTransferGroups.append(static_cast<TransferGroupHandler *> (currentIndex.internalPointer()));
00340     }
00341 
00342     return selectedTransferGroups;
00343 }
00344 
00345 TransferTreeSelectionModel * KGet::selectionModel()
00346 {
00347     return m_selectionModel;
00348 }
00349 
00350 void KGet::addTransferView(QAbstractItemView * view)
00351 {
00352     view->setModel(m_transferTreeModel);
00353 }
00354 
00355 void KGet::load( QString filename ) // krazy:exclude=passbyvalue
00356 {
00357     kDebug(5001) << "(" << filename << ")";
00358 
00359     if(filename.isEmpty())
00360         filename = KStandardDirs::locateLocal("appdata", "transfers.kgt");
00361 
00362     QString tmpFile;
00363 
00364     //Try to save the transferlist to a temporary location
00365     if(!KIO::NetAccess::download(KUrl(filename), tmpFile, 0))
00366         return;
00367 
00368     QFile file(tmpFile);
00369     QDomDocument doc;
00370 
00371     kDebug(5001) << "file:" << filename;
00372 
00373     if(doc.setContent(&file))
00374     {
00375         QDomElement root = doc.documentElement();
00376 
00377         QDomNodeList nodeList = root.elementsByTagName("TransferGroup");
00378         int nItems = nodeList.length();
00379 
00380         for( int i = 0 ; i < nItems ; i++ )
00381         {
00382             TransferGroup * foundGroup = m_transferTreeModel->findGroup( nodeList.item(i).toElement().attribute("Name") );
00383 
00384             kDebug(5001) << "KGet::load  -> group = " << nodeList.item(i).toElement().attribute("Name");
00385 
00386             if( !foundGroup )
00387             {
00388                 kDebug(5001) << "KGet::load  -> group not found";
00389 
00390                 TransferGroup * newGroup = new TransferGroup(m_transferTreeModel, m_scheduler);
00391 
00392                 m_transferTreeModel->addGroup(newGroup);
00393 
00394                 newGroup->load(nodeList.item(i).toElement());
00395 
00396                 //Post notifications
00397                 postAddedTransferGroupEvent(newGroup);
00398             }
00399             else
00400             {
00401                 kDebug(5001) << "KGet::load  -> group found";
00402 
00403                 //A group with this name already exists.
00404                 //Integrate the group's transfers with the ones read from file
00405                 foundGroup->load(nodeList.item(i).toElement());
00406             }
00407         }
00408     }
00409     else
00410     {
00411         kWarning(5001) << "Error reading the transfers file";
00412     }
00413 }
00414 
00415 void KGet::save( QString filename ) // krazy:exclude=passbyvalue
00416 {
00417     if ( !filename.isEmpty()
00418         && QFile::exists( filename )
00419         && (KMessageBox::questionYesNoCancel(0,
00420                 i18n("The file %1 already exists.\nOverwrite?", filename),
00421                 i18n("Overwrite existing file?"), KStandardGuiItem::yes(),
00422                 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionFilenameExists" )
00423                 != KMessageBox::Yes) )
00424         return;
00425 
00426     if(filename.isEmpty())
00427         filename = KStandardDirs::locateLocal("appdata", "transfers.kgt");
00428 
00429     QDomDocument doc(QString("KGetTransfers"));
00430     QDomElement root = doc.createElement("Transfers");
00431     doc.appendChild(root);
00432 
00433     QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
00434     QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
00435 
00436     for ( ; it!=itEnd ; ++it )
00437     {
00438         QDomElement e = doc.createElement("TransferGroup");
00439         root.appendChild(e);
00440         (*it)->save(e);
00441     }
00442     QFile file(filename);
00443     if ( !file.open( QIODevice::WriteOnly ) )
00444     {
00445         //kWarning(5001)<<"Unable to open output file when saving";
00446         KMessageBox::error(0,
00447                            i18n("Unable to save to: %1", filename),
00448                            i18n("Error"));
00449         return;
00450     }
00451 
00452     QTextStream stream( &file );
00453     doc.save( stream, 0 );
00454     file.close();
00455 }
00456 
00457 TransferFactory * KGet::factory(TransferHandler * transfer)
00458 {
00459     return transfer->m_transfer->factory();
00460 }
00461 
00462 KActionCollection * KGet::actionCollection()
00463 {
00464     return m_mainWindow->actionCollection();
00465 }
00466 
00467 void KGet::setSchedulerRunning(bool running)
00468 {
00469     if(running)
00470     {
00471         m_scheduler->stop(); //stopall first, to have a clean startingpoint
00472     m_scheduler->start();
00473     }
00474     else
00475     m_scheduler->stop();
00476 }
00477 
00478 bool KGet::schedulerRunning()
00479 {
00480     return (m_scheduler->countRunningJobs() > 0);
00481 }
00482 
00483 void KGet::setPluginsSettingsWidget(KTabWidget * widget)
00484 {
00485     kDebug(5001);
00486     QList<TransferFactory *>::iterator it = m_transferFactories.begin();
00487     QList<TransferFactory *>::iterator itEnd = m_transferFactories.end();
00488 
00489     QWidget * settingsWidget;
00490     for( ; it!=itEnd ; ++it)
00491     {
00492         KDialog *dialog = static_cast<KDialog*>(widget->parent()->parent());
00493         if (!dialog)
00494             return;
00495 
00496         settingsWidget = (*it)->createSettingsWidget(dialog);
00497         if(settingsWidget)
00498             widget->addTab( settingsWidget, (*it)->displayName() );
00499     }
00500 }
00501 
00502 QList<TransferHandler*> KGet::allTransfers()
00503 {
00504     QList<TransferHandler*> transfers;
00505 
00506     foreach (TransferGroup *group, KGet::m_transferTreeModel->transferGroups())
00507     {
00508         transfers << group->handler()->transfers();
00509         
00510     }
00511     return transfers;
00512 }
00513 
00514 void KGet::checkSystemTray()
00515 {
00516     kDebug(5001);
00517     bool running = false;
00518 
00519     foreach (TransferHandler *handler, KGet::allTransfers())
00520     {
00521         if (handler->status() == Job::Running)
00522             running = true;
00523 
00524         if (running)
00525             continue;
00526     }
00527 
00528     m_mainWindow->setSystemTrayDownloading(running);
00529 }
00530 
00531 // ------ STATIC MEMBERS INITIALIZATION ------
00532 QList<ModelObserver *> KGet::m_observers;
00533 TransferTreeModel * KGet::m_transferTreeModel;
00534 TransferTreeSelectionModel * KGet::m_selectionModel;
00535 QList<TransferFactory *> KGet::m_transferFactories;
00536 QList<KLibrary *> KGet::m_pluginKLibraries;
00537 Scheduler * KGet::m_scheduler = new Scheduler();
00538 MainWindow * KGet::m_mainWindow = 0;
00539 
00540 // ------ PRIVATE FUNCTIONS ------
00541 KGet::KGet()
00542 {
00543     m_transferTreeModel = new TransferTreeModel(m_scheduler);
00544     m_selectionModel = new TransferTreeSelectionModel(m_transferTreeModel);
00545 
00546     //Load all the available plugins
00547     loadPlugins();
00548 
00549     //Create the default group
00550     addGroup(i18n("My Downloads"));
00551 }
00552 
00553 KGet::~KGet()
00554 {
00555     unloadPlugins();
00556     delete(m_scheduler);
00557 }
00558 
00559 void KGet::createTransfer(const KUrl &src, const KUrl &dest, const QString& groupName, 
00560                           bool start, const QDomElement * e)
00561 {
00562     kDebug(5001) << "srcUrl= " << src.url() << "  " 
00563                              << "destUrl= " << dest.url() 
00564                              << "group= _" << groupName << "_" << endl;
00565 
00566     TransferGroup * group = m_transferTreeModel->findGroup(groupName);
00567     if (group==0)
00568     {
00569         kDebug(5001) << "KGet::createTransfer  -> group not found";
00570         group = m_transferTreeModel->transferGroups().first();
00571     }
00572     Transfer * newTransfer;
00573 
00574     QList<TransferFactory *>::iterator it = m_transferFactories.begin();
00575     QList<TransferFactory *>::iterator itEnd = m_transferFactories.end();
00576 
00577     for( ; it!=itEnd ; ++it)
00578     {
00579         kDebug(5001) << "Trying plugin   n.plugins=" << m_transferFactories.size();
00580         if((newTransfer = (*it)->createTransfer(src, dest, group, m_scheduler, e)))
00581         {
00582 //             kDebug(5001) << "KGet::createTransfer   ->   CREATING NEW TRANSFER ON GROUP: _" << group->name() << "_";
00583             m_transferTreeModel->addTransfer(newTransfer, group);
00584 
00585             if(start)
00586                 newTransfer->handler()->start();
00587 
00588             if (newTransfer->percent() != 100) //Don't add a finished observer if the Transfer has already been finished
00589                 newTransfer->handler()->addObserver(new TransferFinishedObserver());
00590 
00591             return;
00592         }
00593     }
00594     kDebug(5001) << "Warning! No plugin found to handle the given url";
00595 }
00596 
00597 void KGet::postAddedTransferGroupEvent(TransferGroup * group, ModelObserver * observer)
00598 {
00599     kDebug(5001);
00600     if(observer)
00601     {
00602         observer->addedTransferGroupEvent(group->handler());
00603         return;
00604     }
00605 
00606     QList<ModelObserver *>::iterator it = m_observers.begin();
00607     QList<ModelObserver *>::iterator itEnd = m_observers.end();
00608 
00609     for(; it!=itEnd; ++it)
00610     {
00611         kDebug(5001) << "message posted";
00612 
00613         (*it)->addedTransferGroupEvent(group->handler());
00614     }
00615 }
00616 
00617 void KGet::postRemovedTransferGroupEvent(TransferGroup * group, ModelObserver * observer)
00618 {
00619     if(observer)
00620     {
00621         observer->removedTransferGroupEvent(group->handler());
00622         return;
00623     }
00624 
00625     QList<ModelObserver *>::iterator it = m_observers.begin();
00626     QList<ModelObserver *>::iterator itEnd = m_observers.end();
00627 
00628     for(; it!=itEnd; ++it)
00629     {
00630         (*it)->removedTransferGroupEvent(group->handler());
00631     }
00632 }
00633 
00634 KUrl KGet::urlInputDialog()
00635 {
00636     QString newtransfer;
00637     bool ok = false;
00638 
00639     KUrl clipboardUrl = KUrl(QApplication::clipboard()->text(QClipboard::Clipboard).trimmed());
00640     if (clipboardUrl.isValid())
00641         newtransfer = clipboardUrl.url();
00642 
00643     while (!ok)
00644     {
00645         newtransfer = KInputDialog::getText(i18n("New Download"), i18n("Enter URL:"), newtransfer, &ok, 0);
00646 
00647         if (!ok)
00648         {
00649             //user pressed cancel
00650             return KUrl();
00651         }
00652 
00653         KUrl src = KUrl(newtransfer);
00654         if(src.isValid())
00655             return src;
00656         else
00657             ok = false;
00658     }
00659     return KUrl();
00660 }
00661 
00662 QString KGet::destInputDialog()
00663 {
00664     QString destDir = KFileDialog::getExistingDirectory(Settings::lastDirectory());
00665 
00666     Settings::setLastDirectory( destDir );
00667     return destDir;
00668 }
00669 
00670 QString KGet::getSaveDirectoryFromExceptions(const KUrl &filename)
00671 {
00672     QString destDir;
00673 
00674     QStringList list = Settings::extensionsFolderList();
00675     QStringList::Iterator it = list.begin();
00676     QStringList::Iterator end = list.end();
00677     while (it != end) {
00678         // odd list items are regular expressions for extensions
00679         QString ext = *it;
00680         ++it;
00681         QString path = *it;
00682         ++it;
00683 
00684         if (!ext.startsWith('*'))
00685             ext = '*' + ext;
00686 
00687         QRegExp rexp(ext);
00688         rexp.setPatternSyntax(QRegExp::Wildcard);
00689 
00690         if (rexp.exactMatch(filename.url())) {
00691             destDir = path;
00692             break;
00693         }
00694     }
00695 
00696 #ifdef Q_OS_WIN //krazy:exclude=cpp
00697     destDir = destDir.remove("file:///");
00698 #endif
00699     return destDir.remove("file://");
00700 }
00701 
00702 bool KGet::isValidSource(const KUrl &source)
00703 {
00704     if (!source.isValid())
00705     {
00706         KMessageBox::error(0,
00707                            i18n("Malformed URL:\n%1", source.prettyUrl()),
00708                            i18n("Error"));
00709         return false;
00710     }
00711     // Check if a transfer with the same url already exists
00712     Transfer * transfer = m_transferTreeModel->findTransfer( source );
00713     if ( transfer )
00714     {
00715         if ( transfer->status() == Job::Finished )
00716         {
00717             // transfer is finished, ask if we want to download again
00718             if (KMessageBox::questionYesNoCancel(0,
00719                 i18n("URL already saved:\n%1\nDownload again?", source.prettyUrl()),
00720                 i18n("Download URL again?"), KStandardGuiItem::yes(),
00721                 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionUrlAlreadySaved" )
00722                 == KMessageBox::Yes)
00723             {
00724                 //TODO reimplement this
00725                 //transfer->slotRemove();
00726                 //checkQueue();
00727                 return true;
00728             }
00729         }
00730         else
00731         {
00732             //Transfer is already in list and not finished, ...
00733             return false;
00734         }
00735         return false;
00736     }
00737     return true;
00738 }
00739 
00740 bool KGet::isValidDestDirectory(const QString & destDir)
00741 {
00742     if (QFileInfo( destDir ).isWritable())
00743         return (!destDir.isEmpty() && QFileInfo( destDir ).isDir() && QFileInfo( destDir ).isWritable());
00744     if (!QFileInfo( destDir ).isWritable() && !destDir.isEmpty())
00745          KMessageBox::error(0, i18n("Directory is not writable"));
00746     return false;
00747 }
00748 
00749 bool KGet::isValidDestUrl(const KUrl &destUrl)
00750 {
00751     if(KIO::NetAccess::exists(destUrl, KIO::NetAccess::DestinationSide, 0))
00752     {
00753         if (KMessageBox::warningYesNoCancel(0,
00754             i18n("Destination file \n%1\nalready exists.\n"
00755                  "Do you want to overwrite it?", destUrl.prettyUrl()))
00756             == KMessageBox::Yes)
00757         {
00758             safeDeleteFile( destUrl );
00759             return true;
00760         }
00761         else
00762             return false;
00763     }
00764     return true;
00765    /*
00766     KIO::open_RenameDlg(i18n("File already exists"), 
00767     (*it).url(), destUrl.url(),
00768     KIO::M_MULTI);
00769    */
00770 }
00771 
00772 KUrl KGet::getValidDestUrl(const QString& destDir, const KUrl &srcUrl)
00773 {
00774     if ( !isValidDestDirectory(destDir) )
00775         return KUrl();
00776 
00777     // create a proper destination file from destDir
00778     KUrl destUrl = KUrl( destDir );
00779     QString filename = srcUrl.fileName();
00780 
00781     if ( filename.isEmpty() )
00782     {
00783         // simply use the full url as filename
00784         filename = KUrl::toPercentEncoding( srcUrl.prettyUrl(), "/" );
00785         kDebug(5001) << " Filename is empty. Setting to  " << filename;
00786         kDebug(5001) << "   srcUrl = " << srcUrl.url();
00787         kDebug(5001) << "   prettyUrl = " << srcUrl.prettyUrl();
00788     }
00789     else
00790     {
00791         kDebug(5001) << " Filename is not empty";
00792         destUrl.adjustPath( KUrl::AddTrailingSlash );
00793         destUrl.setFileName( filename );
00794         if (!isValidDestUrl(destUrl))
00795         {
00796             kDebug(5001) << "   destUrl " << destUrl.path() << " is not valid";
00797             return KUrl();
00798         }
00799     }
00800     return destUrl;
00801 }
00802 
00803 void KGet::loadPlugins()
00804 {
00805     // Add versioning constraint
00806     QString
00807     str  = "[X-KDE-KGet-framework-version] == ";
00808     str += QString::number( FrameworkVersion );
00809     str += " and ";
00810     str += "[X-KDE-KGet-rank] > 0";
00811     str += " and ";
00812     str += "[X-KDE-KGet-plugintype] == ";
00813 
00814     KService::List offers;
00815 
00816     //TransferFactory plugins
00817     offers = KServiceTypeTrader::self()->query( "KGet/Plugin", str + "'TransferFactory'" );
00818 
00819     //Here we use a QMap only to easily sort the plugins by rank
00820     QMap<int, KService::Ptr> services;
00821     QMap<int, KService::Ptr>::iterator it;
00822 
00823     for ( int i = 0; i < offers.count(); ++i )
00824     {
00825         services[ offers[i]->property( "X-KDE-KGet-rank" ).toInt() ] = offers[i];
00826         kDebug(5001) << " TransferFactory plugin found:" << endl <<
00827          "  rank = " << offers[i]->property( "X-KDE-KGet-rank" ).toInt() << endl <<
00828          "  plugintype = " << offers[i]->property( "X-KDE-KGet-plugintype" ) << endl;
00829     }
00830 
00831     //I must fill this pluginList before and my m_transferFactories list after.
00832     //This because calling the KLibLoader::globalLibrary() erases the static
00833     //members of this class (why?), such as the m_transferFactories list.
00834     QList<KGetPlugin *> pluginList;
00835 
00836     for( it = services.begin(); it != services.end(); ++it )
00837     {
00838         KGetPlugin * plugin;
00839         if( (plugin = createPluginFromService(*it)) != 0 )
00840         {
00841             pluginList.prepend(plugin);
00842             kDebug(5001) << "TransferFactory plugin (" << (*it)->library() 
00843                       << ") found and added to the list of available plugins" << endl;
00844         }
00845         else
00846             kDebug(5001) << "Error loading TransferFactory plugin (" 
00847                       << (*it)->library() << ")" << endl;
00848     }
00849 
00850     QList<KGetPlugin *>::iterator it2 = pluginList.begin();
00851     QList<KGetPlugin *>::iterator it2End = pluginList.end();
00852 
00853     for( ; it2!=it2End ; ++it2 )
00854         m_transferFactories.append( static_cast<TransferFactory *>(*it2) );
00855 
00856     kDebug(5001) << "Number of factories = " << m_transferFactories.size();
00857 }
00858 
00859 void KGet::unloadPlugins()
00860 {
00861     QList<KLibrary *>::iterator it = m_pluginKLibraries.begin();
00862     QList<KLibrary *>::iterator itEnd = m_pluginKLibraries.end();
00863 
00864     for(;it!=itEnd;++it)
00865     {
00866         (*it)->unload();
00867     }
00868     m_transferFactories.clear();
00869 }
00870 
00871 KGetPlugin * KGet::createPluginFromService( const KService::Ptr service )
00872 {
00873     //try to load the specified library
00874     KLibrary *lib = new KLibrary(QFile::encodeName(service->library()));
00875 
00876     if (!lib)
00877     {
00878         KMessageBox::error(0, i18n("<html><p>KLibLoader could not load the plugin:<br/><i>%1</i></p></html>",
00879                                    service->library()));
00880         kError(5001) << "KLibLoader could not load the plugin:" << service->library();
00881         return 0;
00882     }
00883 
00884     KGetPlugin* (*create_plugin)() = ( KGetPlugin* (*)() ) lib->resolveFunction( "create_plugin" );
00885 
00886     if ( !create_plugin ) 
00887     {
00888         kDebug(5001) << "create_plugin == NULL";
00889         return 0;
00890     }
00891 
00892     m_pluginKLibraries.append(lib);
00893 
00894     return create_plugin();
00895 }
00896 
00897 bool KGet::safeDeleteFile( const KUrl& url )
00898 {
00899     if ( url.isLocalFile() )
00900     {
00901         QFileInfo info( url.path() );
00902         if ( info.isDir() )
00903         {
00904             KMessageBox::information(0L,i18n("Not deleting\n%1\nas it is a "
00905                                      "directory.", url.prettyUrl()),
00906                                      i18n("Not Deleted"));
00907             return false;
00908         }
00909         KIO::NetAccess::del( url, 0L );
00910         return true;
00911     }
00912 
00913     else
00914         KMessageBox::information( 0L,
00915                                   i18n("Not deleting\n%1\nas it is not a local"
00916                                           " file.", url.prettyUrl()),
00917                                   i18n("Not Deleted") );
00918     return false;
00919 }
00920 
00921 TransferFinishedObserver::TransferFinishedObserver()
00922      : TransferObserver()
00923 {
00924 }
00925 
00926 void TransferFinishedObserver::transferChangedEvent(TransferHandler * transfer)
00927 {
00928     kDebug(5001);
00929 
00930     if (transfer->status() == Job::Finished && Settings::quitAfterCompletedTransfer()) 
00931     {
00932         checkAndFinish();
00933     }
00934 
00935     if (prevStatus != transfer->statusText())//FIXME: HACK: better: check statusFlags if it contains Tc_Status (flags & Transfer::Tc_Status <-doesn't work)
00936     {
00937         prevStatus = transfer->statusText();
00938         KGet::checkSystemTray();
00939     }
00940 }
00941 
00942 void TransferFinishedObserver::checkAndFinish()
00943 {
00944     bool quitFlag = true;
00945     foreach(TransferGroup *transferGroup, KGet::m_transferTreeModel->transferGroups()) {
00946         foreach(TransferHandler *transfer, transferGroup->handler()->transfers()) {
00947             if(transfer->status() != Job::Finished) {
00948                 quitFlag = false;
00949             }
00950         }
00951     }
00952 
00953     // check if there is some unfinished transfer in scheduler queues
00954     if(quitFlag) {
00955         KPassivePopup *message;
00956         // we have to call diferent message from kpassivePopup
00957         // one with parent as QWidget for the mainWindow
00958         // and another with parent as QSystemTrayIcon if the parent is a systemTray
00959         // so passing the QSystemTrayIcon as QWidget don't work
00960         if(Settings::enableSystemTray()) 
00961         {
00962             message = KPassivePopup::message(5000, KGET_QUIT_MESSAGE_TITLE,
00963                     KGET_QUIT_MESSAGE,
00964                     KGet::m_mainWindow->systemTray());
00965         }
00966         else 
00967         {
00968             message = KPassivePopup::message(5000, KGET_QUIT_MESSAGE_TITLE,
00969                     KGET_QUIT_MESSAGE,
00970                     KGet::m_mainWindow);
00971         }
00972 
00973         QObject::connect(message, SIGNAL(destroyed()), KGet::m_mainWindow, SLOT(slotQuit()));
00974     }
00975 }

kget

Skip menu "kget"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdenetwork

Skip menu "kdenetwork"
  • kget
  • kopete
  •   kopete
  •   libkopete
  •       libpapillon
  • krfb
Generated for kdenetwork by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal