Fix system-tray...
[kdenetwork.git] / kget / core / kget.cpp
blobacad703e7ec6b880e72d9029a09dbaaf4af75df4
1 /* This file is part of the KDE project
3 Copyright (C) 2005 Dario Massarin <nekkar@libero.it>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9 */
11 #include "core/kget.h"
13 #include "mainwindow.h"
14 #include "core/transfer.h"
15 #include "core/transfergroup.h"
16 #include "core/transfergrouphandler.h"
17 #include "core/transfertreemodel.h"
18 #include "core/transfertreeselectionmodel.h"
19 #include "core/plugin/plugin.h"
20 #include "core/plugin/transferfactory.h"
21 #include "core/observer.h"
22 #include "settings.h"
24 #include <kio/netaccess.h>
25 #include <kinputdialog.h>
26 #include <kfiledialog.h>
27 #include <kmessagebox.h>
28 #include <klocale.h>
29 #include <kstandarddirs.h>
30 #include <kservicetypetrader.h>
31 #include <kiconloader.h>
32 #include <kactioncollection.h>
33 #include <kio/renamedialog.h>
34 #include <KPassivePopup>
35 #include <KSystemTrayIcon>
37 #include <QDirModel>
38 #include <QTextStream>
39 #include <QDomElement>
40 #include <QApplication>
41 #include <QClipboard>
42 #include <QItemSelectionModel>
43 #include <QAbstractItemView>
45 /**
46 * This is our KGet class. This is where the user's transfers and searches are
47 * stored and organized.
48 * Use this class from the views to add or remove transfers or searches
49 * In order to organize the transfers inside categories we have a TransferGroup
50 * class. By definition, a transfer must always belong to a TransferGroup. If we
51 * don't want it to be displayed by the gui inside a specific group, we will put
52 * it in the group named "Not grouped" (better name?).
53 **/
55 KGet& KGet::self( MainWindow * mainWindow )
57 if(mainWindow)
59 m_mainWindow = mainWindow;
62 static KGet m;
63 return m;
66 void KGet::addObserver(ModelObserver * observer)
68 kDebug(5001) << "KGet::addObserver";
70 m_observers.append(observer);
72 //Update the new observer with the TransferGroups objects of the model
73 QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
74 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
76 for( ; it!=itEnd ; ++it )
78 postAddedTransferGroupEvent(*it, observer);
81 kDebug(5001) << "KGet::addObserver >>> EXITING";
84 void KGet::delObserver(ModelObserver * observer)
86 m_observers.removeAll(observer);
89 bool KGet::addGroup(const QString& groupName)
91 kDebug(5001) << "KGet::addGroup";
93 // Check if a group with that name already exists
94 if(m_transferTreeModel->findGroup(groupName))
95 return false;
97 TransferGroup * group = new TransferGroup(m_transferTreeModel, m_scheduler, groupName);
98 m_transferTreeModel->addGroup(group);
100 //post notifications
101 postAddedTransferGroupEvent(group);
103 return true;
106 void KGet::delGroup(const QString& groupName)
108 TransferGroup * group = m_transferTreeModel->findGroup(groupName);
110 if(group)
112 m_transferTreeModel->delGroup(group);
113 postRemovedTransferGroupEvent(group);
114 delete(group);
118 void KGet::renameGroup(const QString& oldName, const QString& newName)
120 TransferGroup *group = m_transferTreeModel->findGroup(oldName);
122 if(group)
124 group->handler()->setName(newName);
128 QStringList KGet::transferGroupNames()
130 QStringList names;
132 foreach(TransferGroup *group, m_transferTreeModel->transferGroups()) {
133 names << group->name();
136 return names;
139 void KGet::addTransfer(KUrl srcUrl, QString destDir, // krazy:exclude=passbyvalue
140 const QString& groupName, bool start)
142 kDebug(5001) << " addTransfer: " << srcUrl.url();
144 KUrl destUrl;
146 if ( srcUrl.isEmpty() )
148 //No src location: we let the user insert it manually
149 srcUrl = urlInputDialog();
150 if( srcUrl.isEmpty() )
151 return;
154 if ( !isValidSource( srcUrl ) )
155 return;
157 if (destDir.isEmpty())
159 if (Settings::useDefaultDirectory())
160 #ifdef Q_OS_WIN //krazy:exclude=cpp
161 destDir = Settings::defaultDirectory().remove("file:///");
162 #else
163 destDir = Settings::defaultDirectory().remove("file://");
164 #endif
166 QString checkExceptions = getSaveDirectoryFromExceptions(srcUrl);
167 if (Settings::enableExceptions() && !checkExceptions.isEmpty())
168 destDir = checkExceptions;
171 if (!isValidDestDirectory(destDir))
172 destDir = destInputDialog();
174 if( (destUrl = getValidDestUrl( destDir, srcUrl )).isEmpty() )
175 return;
177 if(m_transferTreeModel->findTransferByDestination(destUrl) != 0 || (destUrl.isLocalFile() && QFile::exists(destUrl.path()))) {
178 KIO::RenameDialog dlg( m_mainWindow, i18n("Rename transfer"), srcUrl,
179 destUrl, KIO::M_MULTI);
180 if (dlg.exec() == KIO::R_RENAME)
181 destUrl = dlg.newDestUrl();
182 else
183 return;
185 createTransfer(srcUrl, destUrl, groupName, start);
188 void KGet::addTransfer(const QDomElement& e, const QString& groupName)
190 //We need to read these attributes now in order to know which transfer
191 //plugin to use.
192 KUrl srcUrl = KUrl( e.attribute("Source") );
193 KUrl destUrl = KUrl( e.attribute("Dest") );
195 kDebug(5001) << "KGet::addTransfer src= " << srcUrl.url()
196 << " dest= " << destUrl.url()
197 << " group= "<< groupName << endl;
199 if ( srcUrl.isEmpty() || !isValidSource(srcUrl)
200 || !isValidDestDirectory(destUrl.directory()) )
201 return;
203 createTransfer(srcUrl, destUrl, groupName, false, &e);
206 void KGet::addTransfer(KUrl::List srcUrls, QString destDir, // krazy:exclude=passbyvalue
207 const QString& groupName, bool start)
209 KUrl::List urlsToDownload;
211 KUrl::List::ConstIterator it = srcUrls.begin();
212 KUrl::List::ConstIterator itEnd = srcUrls.end();
214 for(; it!=itEnd ; ++it)
216 if ( isValidSource( *it ) )
217 urlsToDownload.append( *it );
220 if ( urlsToDownload.count() == 0 )
221 return;
223 if ( urlsToDownload.count() == 1 )
225 // just one file -> ask for filename
226 addTransfer(srcUrls.first(), destDir, groupName, start);
227 return;
230 KUrl destUrl;
232 // multiple files -> ask for directory, not for every single filename
233 if (!isValidDestDirectory(destDir) && !Settings::useDefaultDirectory())
234 destDir = destInputDialog();
236 it = urlsToDownload.begin();
237 itEnd = urlsToDownload.end();
239 for ( ; it != itEnd; ++it )
241 if (destDir.isEmpty())
243 if (Settings::useDefaultDirectory())
244 #ifdef Q_OS_WIN //krazy:exclude=cpp
245 destDir = Settings::defaultDirectory().remove("file:///");
246 #else
247 destDir = Settings::defaultDirectory().remove("file://");
248 #endif
250 QString checkExceptions = getSaveDirectoryFromExceptions(*it);
251 if (Settings::enableExceptions() && !checkExceptions.isEmpty())
252 destDir = checkExceptions;
254 destUrl = getValidDestUrl(destDir, *it);
256 if(!isValidDestUrl(destUrl))
257 continue;
259 createTransfer(*it, destUrl, groupName, start);
264 void KGet::delTransfer(TransferHandler * transfer)
266 Transfer * t = transfer->m_transfer;
268 m_transferTreeModel->delTransfer(t);
270 //Here I delete the Transfer. The other possibility is to move it to a list
271 //and to delete all these transfers when kget gets closed. Obviously, after
272 //the notification to the views that the transfer has been removed, all the
273 //pointers to it are invalid.
274 transfer->postDeleteEvent();
275 // TODO: why does it crash if a download is going to be deleted which is not the last in the list?
276 // there are always no problems with the last download.
277 // delete( t );
280 void KGet::moveTransfer(TransferHandler * transfer, const QString& groupName)
282 Q_UNUSED(transfer);
283 Q_UNUSED(groupName);
286 QList<TransferHandler *> KGet::selectedTransfers()
288 // kDebug(5001) << "KGet::selectedTransfers";
290 QList<TransferHandler *> selectedTransfers;
292 QModelIndexList selectedIndexes = m_selectionModel->selectedRows();
294 foreach(QModelIndex currentIndex, selectedIndexes)
296 if(!m_transferTreeModel->isTransferGroup(currentIndex))
297 selectedTransfers.append(static_cast<TransferHandler *> (currentIndex.internalPointer()));
300 return selectedTransfers;
303 // This is the code that was used in the old selectedTransfers function
304 /* QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
305 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
307 for( ; it!=itEnd ; ++it )
309 TransferGroup::iterator it2 = (*it)->begin();
310 TransferGroup::iterator it2End = (*it)->end();
312 for( ; it2!=it2End ; ++it2 )
314 Transfer * transfer = (Transfer*) *it2;
316 if( transfer->isSelected() )
317 selectedTransfers.append( transfer->handler() );
320 return selectedTransfers;*/
323 QList<TransferGroupHandler *> KGet::selectedTransferGroups()
325 QList<TransferGroupHandler *> selectedTransferGroups;
327 QModelIndexList selectedIndexes = m_selectionModel->selectedRows();
329 foreach(QModelIndex currentIndex, selectedIndexes)
331 if(m_transferTreeModel->isTransferGroup(currentIndex))
332 selectedTransferGroups.append(static_cast<TransferGroupHandler *> (currentIndex.internalPointer()));
335 return selectedTransferGroups;
338 TransferTreeSelectionModel * KGet::selectionModel()
340 return m_selectionModel;
343 void KGet::addTransferView(QAbstractItemView * view)
345 view->setModel(m_transferTreeModel);
348 void KGet::load( QString filename ) // krazy:exclude=passbyvalue
350 kDebug(5001) << "KGet::load(" << filename << ")";
352 if(filename.isEmpty())
353 filename = KStandardDirs::locateLocal("appdata", "transfers.kgt");
355 QString tmpFile;
357 //Try to save the transferlist to a temporary location
358 if(!KIO::NetAccess::download(KUrl(filename), tmpFile, 0))
359 return;
361 QFile file(tmpFile);
362 QDomDocument doc;
364 kDebug(5001) << "KGet::load file" << filename;
366 if(doc.setContent(&file))
368 QDomElement root = doc.documentElement();
370 QDomNodeList nodeList = root.elementsByTagName("TransferGroup");
371 int nItems = nodeList.length();
373 for( int i = 0 ; i < nItems ; i++ )
375 TransferGroup * foundGroup = m_transferTreeModel->findGroup( nodeList.item(i).toElement().attribute("Name") );
377 kDebug(5001) << "KGet::load -> group = " << nodeList.item(i).toElement().attribute("Name");
379 if( !foundGroup )
381 kDebug(5001) << "KGet::load -> group not found";
383 TransferGroup * newGroup = new TransferGroup(m_transferTreeModel, m_scheduler);
385 m_transferTreeModel->addGroup(newGroup);
387 newGroup->load(nodeList.item(i).toElement());
389 //Post notifications
390 postAddedTransferGroupEvent(newGroup);
392 else
394 kDebug(5001) << "KGet::load -> group found";
396 //A group with this name already exists.
397 //Integrate the group's transfers with the ones read from file
398 foundGroup->load(nodeList.item(i).toElement());
402 else
404 kWarning(5001) << "Error reading the transfers file";
408 void KGet::save( QString filename ) // krazy:exclude=passbyvalue
410 if ( !filename.isEmpty()
411 && QFile::exists( filename )
412 && (KMessageBox::questionYesNoCancel(0,
413 i18n("The file %1 already exists.\nOverwrite?", filename),
414 i18n("Overwrite existing file?"), KStandardGuiItem::yes(),
415 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionFilenameExists" )
416 != KMessageBox::Yes) )
417 return;
419 if(filename.isEmpty())
420 filename = KStandardDirs::locateLocal("appdata", "transfers.kgt");
422 QDomDocument doc(QString("KGetTransfers"));
423 QDomElement root = doc.createElement("Transfers");
424 doc.appendChild(root);
426 QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
427 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
429 for ( ; it!=itEnd ; ++it )
431 QDomElement e = doc.createElement("TransferGroup");
432 root.appendChild(e);
433 (*it)->save(e);
435 QFile file(filename);
436 if ( !file.open( QIODevice::WriteOnly ) )
438 //kWarning(5001)<<"Unable to open output file when saving";
439 KMessageBox::error(0,
440 i18n("Unable to save to: %1", filename),
441 i18n("Error"));
442 return;
445 QTextStream stream( &file );
446 doc.save( stream, 0 );
447 file.close();
450 TransferFactory * KGet::factory(TransferHandler * transfer)
452 return transfer->m_transfer->factory();
455 KActionCollection * KGet::actionCollection()
457 return m_mainWindow->actionCollection();
460 void KGet::setSchedulerRunning(bool running)
462 if(running)
464 m_scheduler->stop(); //stopall first, to have a clean startingpoint
465 m_scheduler->start();
467 else
468 m_scheduler->stop();
471 bool KGet::schedulerRunning()
473 return (m_scheduler->countRunningJobs() > 0);
476 void KGet::setPluginsSettingsWidget(KTabWidget * widget)
478 kDebug(5001);
479 QList<TransferFactory *>::iterator it = m_transferFactories.begin();
480 QList<TransferFactory *>::iterator itEnd = m_transferFactories.end();
482 QWidget * settingsWidget;
483 for( ; it!=itEnd ; ++it)
485 KDialog *dialog = static_cast<KDialog*>(widget->parent()->parent());
486 if (!dialog)
487 return;
489 settingsWidget = (*it)->createSettingsWidget(dialog);
490 if(settingsWidget)
491 widget->addTab( settingsWidget, (*it)->displayName() );
495 QList<TransferHandler*> KGet::allTransfers()
497 QList<TransferHandler*> transfers;
499 foreach (TransferGroup *group, KGet::m_transferTreeModel->transferGroups())
501 transfers << group->handler()->transfers();
504 return transfers;
507 void KGet::setTrayDownloading(bool running)
509 m_mainWindow->setTrayDownloading(running);
512 // ------ STATIC MEMBERS INITIALIZATION ------
513 QList<ModelObserver *> KGet::m_observers;
514 TransferTreeModel * KGet::m_transferTreeModel;
515 TransferTreeSelectionModel * KGet::m_selectionModel;
516 QList<TransferFactory *> KGet::m_transferFactories;
517 QList<KLibrary *> KGet::m_pluginKLibraries;
518 Scheduler * KGet::m_scheduler = new Scheduler();
519 MainWindow * KGet::m_mainWindow = 0;
521 // ------ PRIVATE FUNCTIONS ------
522 KGet::KGet()
524 m_transferTreeModel = new TransferTreeModel(m_scheduler);
525 m_selectionModel = new TransferTreeSelectionModel(m_transferTreeModel);
527 //Load all the available plugins
528 loadPlugins();
530 //Create the default group
531 addGroup(i18n("My Downloads"));
534 KGet::~KGet()
536 unloadPlugins();
537 delete(m_scheduler);
540 void KGet::createTransfer(const KUrl &src, const KUrl &dest, const QString& groupName,
541 bool start, const QDomElement * e)
543 kDebug(5001) << "createTransfer: srcUrl= " << src.url() << " "
544 << "destUrl= " << dest.url()
545 << "group= _" << groupName << "_" << endl;
547 TransferGroup * group = m_transferTreeModel->findGroup(groupName);
548 if (group==0)
550 kDebug(5001) << "KGet::createTransfer -> group not found";
551 group = m_transferTreeModel->transferGroups().first();
553 Transfer * newTransfer;
555 QList<TransferFactory *>::iterator it = m_transferFactories.begin();
556 QList<TransferFactory *>::iterator itEnd = m_transferFactories.end();
558 for( ; it!=itEnd ; ++it)
560 kDebug(5001) << "Trying plugin n.plugins=" << m_transferFactories.size();
561 if((newTransfer = (*it)->createTransfer(src, dest, group, m_scheduler, e)))
563 // kDebug(5001) << "KGet::createTransfer -> CREATING NEW TRANSFER ON GROUP: _" << group->name() << "_";
564 m_transferTreeModel->addTransfer(newTransfer, group);
566 if(start)
567 newTransfer->handler()->start();
569 newTransfer->handler()->addObserver(new TransferFinishedObserver());
571 return;
574 kDebug(5001) << "createTransfer: Warning! No plugin found to handle the given url";
577 void KGet::postAddedTransferGroupEvent(TransferGroup * group, ModelObserver * observer)
579 kDebug(5001) << "KGet::postAddedTransferGroupEvent";
580 if(observer)
582 observer->addedTransferGroupEvent(group->handler());
583 return;
586 QList<ModelObserver *>::iterator it = m_observers.begin();
587 QList<ModelObserver *>::iterator itEnd = m_observers.end();
589 for(; it!=itEnd; ++it)
591 kDebug(5001) << "message posted";
593 (*it)->addedTransferGroupEvent(group->handler());
597 void KGet::postRemovedTransferGroupEvent(TransferGroup * group, ModelObserver * observer)
599 if(observer)
601 observer->removedTransferGroupEvent(group->handler());
602 return;
605 QList<ModelObserver *>::iterator it = m_observers.begin();
606 QList<ModelObserver *>::iterator itEnd = m_observers.end();
608 for(; it!=itEnd; ++it)
610 (*it)->removedTransferGroupEvent(group->handler());
614 KUrl KGet::urlInputDialog()
616 QString newtransfer;
617 bool ok = false;
619 KUrl clipboardUrl = KUrl(QApplication::clipboard()->text(QClipboard::Clipboard).trimmed());
620 if (clipboardUrl.isValid())
621 newtransfer = clipboardUrl.url();
623 while (!ok)
625 newtransfer = KInputDialog::getText(i18n("New Download"), i18n("Enter URL:"), newtransfer, &ok, 0);
627 if (!ok)
629 //user pressed cancel
630 return KUrl();
633 KUrl src = KUrl(newtransfer);
634 if(src.isValid())
635 return src;
636 else
637 ok = false;
639 return KUrl();
642 QString KGet::destInputDialog()
644 QString destDir = KFileDialog::getExistingDirectory(Settings::lastDirectory());
646 Settings::setLastDirectory( destDir );
647 return destDir;
650 QString KGet::getSaveDirectoryFromExceptions(const KUrl &filename)
652 QString destDir;
654 QStringList list = Settings::extensionsFolderList();
655 QStringList::Iterator it = list.begin();
656 QStringList::Iterator end = list.end();
657 while (it != end) {
658 // odd list items are regular expressions for extensions
659 QString ext = *it;
660 ++it;
661 QString path = *it;
662 ++it;
664 if (!ext.startsWith('*'))
665 ext = '*' + ext;
667 QRegExp rexp(ext);
668 rexp.setPatternSyntax(QRegExp::Wildcard);
670 if (rexp.exactMatch(filename.url())) {
671 destDir = path;
672 break;
676 #ifdef Q_OS_WIN //krazy:exclude=cpp
677 destDir = destDir.remove("file:///");
678 #endif
679 return destDir.remove("file://");
682 bool KGet::isValidSource(const KUrl &source)
684 if (!source.isValid())
686 KMessageBox::error(0,
687 i18n("Malformed URL:\n%1", source.prettyUrl()),
688 i18n("Error"));
689 return false;
691 // Check if a transfer with the same url already exists
692 Transfer * transfer = m_transferTreeModel->findTransfer( source );
693 if ( transfer )
695 if ( transfer->status() == Job::Finished )
697 // transfer is finished, ask if we want to download again
698 if (KMessageBox::questionYesNoCancel(0,
699 i18n("URL already saved:\n%1\nDownload again?", source.prettyUrl()),
700 i18n("Download URL again?"), KStandardGuiItem::yes(),
701 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionUrlAlreadySaved" )
702 == KMessageBox::Yes)
704 //TODO reimplement this
705 //transfer->slotRemove();
706 //checkQueue();
707 return true;
710 else
712 //Transfer is already in list and not finished, ...
713 return false;
715 return false;
717 return true;
720 bool KGet::isValidDestDirectory(const QString & destDir)
722 if (QFileInfo( destDir ).isWritable())
723 return (!destDir.isEmpty() && QFileInfo( destDir ).isDir() && QFileInfo( destDir ).isWritable());
724 if (!QFileInfo( destDir ).isWritable() && !destDir.isEmpty())
725 KMessageBox::error(0, i18n("Directory is not writable"));
726 return false;
729 bool KGet::isValidDestUrl(const KUrl &destUrl)
731 if(KIO::NetAccess::exists(destUrl, KIO::NetAccess::DestinationSide, 0))
733 if (KMessageBox::warningYesNoCancel(0,
734 i18n("Destination file \n%1\nalready exists.\n"
735 "Do you want to overwrite it?", destUrl.prettyUrl()))
736 == KMessageBox::Yes)
738 safeDeleteFile( destUrl );
739 return true;
741 else
742 return false;
744 return true;
746 KIO::open_RenameDlg(i18n("File already exists"),
747 (*it).url(), destUrl.url(),
748 KIO::M_MULTI);
752 KUrl KGet::getValidDestUrl(const QString& destDir, const KUrl &srcUrl)
754 if ( !isValidDestDirectory(destDir) )
755 return KUrl();
757 // create a proper destination file from destDir
758 KUrl destUrl = KUrl( destDir );
759 QString filename = srcUrl.fileName();
761 if ( filename.isEmpty() )
763 // simply use the full url as filename
764 filename = KUrl::toPercentEncoding( srcUrl.prettyUrl(), "/" );
765 kDebug(5001) << " Filename is empty. Setting to " << filename;
766 kDebug(5001) << " srcUrl = " << srcUrl.url();
767 kDebug(5001) << " prettyUrl = " << srcUrl.prettyUrl();
769 else
771 kDebug(5001) << " Filename is not empty";
772 destUrl.adjustPath( KUrl::AddTrailingSlash );
773 destUrl.setFileName( filename );
774 if (!isValidDestUrl(destUrl))
776 kDebug(5001) << " destUrl " << destUrl.path() << " is not valid";
777 return KUrl();
780 return destUrl;
783 void KGet::loadPlugins()
785 // Add versioning constraint
786 QString
787 str = "[X-KDE-KGet-framework-version] == ";
788 str += QString::number( FrameworkVersion );
789 str += " and ";
790 str += "[X-KDE-KGet-rank] > 0";
791 str += " and ";
792 str += "[X-KDE-KGet-plugintype] == ";
794 KService::List offers;
796 //TransferFactory plugins
797 offers = KServiceTypeTrader::self()->query( "KGet/Plugin", str + "'TransferFactory'" );
799 //Here we use a QMap only to easily sort the plugins by rank
800 QMap<int, KService::Ptr> services;
801 QMap<int, KService::Ptr>::iterator it;
803 for ( int i = 0; i < offers.count(); ++i )
805 services[ offers[i]->property( "X-KDE-KGet-rank" ).toInt() ] = offers[i];
806 kDebug(5001) << " TransferFactory plugin found:" << endl <<
807 " rank = " << offers[i]->property( "X-KDE-KGet-rank" ).toInt() << endl <<
808 " plugintype = " << offers[i]->property( "X-KDE-KGet-plugintype" ) << endl;
811 //I must fill this pluginList before and my m_transferFactories list after.
812 //This because calling the KLibLoader::globalLibrary() erases the static
813 //members of this class (why?), such as the m_transferFactories list.
814 QList<KGetPlugin *> pluginList;
816 for( it = services.begin(); it != services.end(); ++it )
818 KGetPlugin * plugin;
819 if( (plugin = createPluginFromService(*it)) != 0 )
821 pluginList.prepend(plugin);
822 kDebug(5001) << "TransferFactory plugin (" << (*it)->library()
823 << ") found and added to the list of available plugins" << endl;
825 else
826 kDebug(5001) << "Error loading TransferFactory plugin ("
827 << (*it)->library() << ")" << endl;
830 QList<KGetPlugin *>::iterator it2 = pluginList.begin();
831 QList<KGetPlugin *>::iterator it2End = pluginList.end();
833 for( ; it2!=it2End ; ++it2 )
834 m_transferFactories.append( static_cast<TransferFactory *>(*it2) );
836 kDebug(5001) << "Number of factories = " << m_transferFactories.size();
839 void KGet::unloadPlugins()
841 QList<KLibrary *>::iterator it = m_pluginKLibraries.begin();
842 QList<KLibrary *>::iterator itEnd = m_pluginKLibraries.end();
844 for(;it!=itEnd;++it)
846 (*it)->unload();
848 m_transferFactories.clear();
851 KGetPlugin * KGet::createPluginFromService( const KService::Ptr service )
853 //try to load the specified library
854 KLibrary *lib = new KLibrary(QFile::encodeName(service->library()));
856 if (!lib)
858 KMessageBox::error(0, i18n("<html><p>KLibLoader could not load the plugin:<br/><i>%1</i></p></html>",
859 service->library()));
860 kError(5001) << "KLibLoader could not load the plugin:" << service->library();
861 return 0;
864 KGetPlugin* (*create_plugin)() = ( KGetPlugin* (*)() ) lib->resolveFunction( "create_plugin" );
866 if ( !create_plugin )
868 kDebug(5001) << "create_plugin == NULL";
869 return 0;
872 m_pluginKLibraries.append(lib);
874 return create_plugin();
877 bool KGet::safeDeleteFile( const KUrl& url )
879 if ( url.isLocalFile() )
881 QFileInfo info( url.path() );
882 if ( info.isDir() )
884 KMessageBox::information(0L,i18n("Not deleting\n%1\nas it is a "
885 "directory.", url.prettyUrl()),
886 i18n("Not Deleted"));
887 return false;
889 KIO::NetAccess::del( url, 0L );
890 return true;
893 else
894 KMessageBox::information( 0L,
895 i18n("Not deleting\n%1\nas it is not a local"
896 " file.", url.prettyUrl()),
897 i18n("Not Deleted") );
898 return false;
901 TransferFinishedObserver::TransferFinishedObserver()
902 : TransferObserver()
906 void TransferFinishedObserver::transferChangedEvent(TransferHandler * transfer)
908 kDebug(5001);
909 if (transfer->status() == Job::Stopped)
910 checkAndUpdateSystemTray();
912 if(transfer->status() == Job::Finished)
914 if (Settings::quitAfterCompletedTransfer())
915 checkAndFinish();
916 else
917 checkAndUpdateSystemTray();
921 void TransferFinishedObserver::checkAndFinish()
923 bool quitFlag = true;
924 foreach(TransferGroup *transferGroup, KGet::m_transferTreeModel->transferGroups()) {
925 foreach(TransferHandler *transfer, transferGroup->handler()->transfers()) {
926 if(transfer->status() != Job::Finished) {
927 quitFlag = false;
932 // check if there is some unfinished transfer in scheduler queues
933 if(quitFlag) {
934 KPassivePopup *message;
935 // we have to call diferent message from kpassivePopup
936 // one with parent as QWidget for the mainWindow
937 // and another with parent as QSystemTrayIcon if the parent is a systemTray
938 // so passing the QSystemTrayIcon as QWidget don't work
939 if(Settings::enableSystemTray())
941 message = KPassivePopup::message(5000, KGET_QUIT_MESSAGE_TITLE,
942 KGET_QUIT_MESSAGE,
943 KGet::m_mainWindow->systemTray());
945 else
947 message = KPassivePopup::message(5000, KGET_QUIT_MESSAGE_TITLE,
948 KGET_QUIT_MESSAGE,
949 KGet::m_mainWindow);
952 QObject::connect(message, SIGNAL(destroyed()), KGet::m_mainWindow, SLOT(slotQuit()));
956 void TransferFinishedObserver::checkAndUpdateSystemTray()
958 kDebug(5001);
959 bool running = false;
961 foreach (TransferHandler *handler, KGet::allTransfers())
963 if (handler->status() == Job::Running)
964 running = true;
966 if (running)
968 kDebug(5001) << "Set downloading";
969 KGet::m_mainWindow->setTrayDownloading(true);
970 continue;
974 if (!running)
975 KGet::m_mainWindow->setTrayDownloading(false);