1 /* This file is part of the KDE project
3 Copyright (C) 2005 Dario Massarin <nekkar@libero.it>
4 Copyright (C) 2007 Lukas Appelhans <l.appelhans@gmx.de>
5 Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
13 #include "core/kget.h"
15 #include "mainwindow.h"
16 #include "core/transfer.h"
17 #include "core/transferdatasource.h"
18 #include "core/transfergroup.h"
19 #include "core/transfergrouphandler.h"
20 #include "core/transfertreemodel.h"
21 #include "core/transfertreeselectionmodel.h"
22 #include "core/plugin/plugin.h"
23 #include "core/plugin/transferfactory.h"
24 #include "core/observer.h"
25 #include "core/kuiserverjobs.h"
28 #include <kio/netaccess.h>
29 #include <kinputdialog.h>
30 #include <kfiledialog.h>
31 #include <kmessagebox.h>
33 #include <kstandarddirs.h>
34 #include <kservicetypetrader.h>
35 #include <kiconloader.h>
36 #include <kactioncollection.h>
37 #include <kio/renamedialog.h>
38 #include <KPassivePopup>
39 #include <KSystemTrayIcon>
41 #include <QTextStream>
42 #include <QDomElement>
43 #include <QApplication>
45 #include <QAbstractItemView>
48 * This is our KGet class. This is where the user's transfers and searches are
49 * stored and organized.
50 * Use this class from the views to add or remove transfers or searches
51 * In order to organize the transfers inside categories we have a TransferGroup
52 * class. By definition, a transfer must always belong to a TransferGroup. If we
53 * don't want it to be displayed by the gui inside a specific group, we will put
54 * it in the group named "Not grouped" (better name?).
57 KGet
& KGet::self( MainWindow
* mainWindow
)
61 m_mainWindow
= mainWindow
;
68 void KGet::addObserver(ModelObserver
* observer
)
72 m_observers
.append(observer
);
74 //Update the new observer with the TransferGroups objects of the model
75 QList
<TransferGroup
*>::const_iterator it
= m_transferTreeModel
->transferGroups().begin();
76 QList
<TransferGroup
*>::const_iterator itEnd
= m_transferTreeModel
->transferGroups().end();
78 for( ; it
!=itEnd
; ++it
)
80 postAddedTransferGroupEvent(*it
, observer
);
83 kDebug(5001) << " >>> EXITING";
86 void KGet::delObserver(ModelObserver
* observer
)
88 m_observers
.removeAll(observer
);
91 bool KGet::addGroup(const QString
& groupName
)
95 // Check if a group with that name already exists
96 if(m_transferTreeModel
->findGroup(groupName
))
99 TransferGroup
* group
= new TransferGroup(m_transferTreeModel
, m_scheduler
, groupName
);
100 m_transferTreeModel
->addGroup(group
);
103 postAddedTransferGroupEvent(group
);
108 void KGet::delGroup(const QString
& groupName
)
110 TransferGroup
* group
= m_transferTreeModel
->findGroup(groupName
);
114 m_transferTreeModel
->delGroup(group
);
115 postRemovedTransferGroupEvent(group
);
120 void KGet::renameGroup(const QString
& oldName
, const QString
& newName
)
122 TransferGroup
*group
= m_transferTreeModel
->findGroup(oldName
);
126 group
->handler()->setName(newName
);
130 QStringList
KGet::transferGroupNames()
134 foreach(TransferGroup
*group
, m_transferTreeModel
->transferGroups()) {
135 names
<< group
->name();
141 void KGet::addTransfer(KUrl srcUrl
, QString destDir
, // krazy:exclude=passbyvalue
142 const QString
& groupName
, bool start
)
144 kDebug(5001) << "Source:" << srcUrl
.url();
148 if ( srcUrl
.isEmpty() )
150 //No src location: we let the user insert it manually
151 srcUrl
= urlInputDialog();
152 if( srcUrl
.isEmpty() )
156 if ( !isValidSource( srcUrl
) )
159 if (destDir
.isEmpty())
161 if (Settings::useDefaultDirectory())
162 #ifdef Q_OS_WIN //krazy:exclude=cpp
163 destDir
= Settings::defaultDirectory().remove("file:///");
165 destDir
= Settings::defaultDirectory().remove("file://");
168 QString checkExceptions
= getSaveDirectoryFromExceptions(srcUrl
);
169 if (Settings::enableExceptions() && !checkExceptions
.isEmpty())
170 destDir
= checkExceptions
;
173 if (!isValidDestDirectory(destDir
))
174 destDir
= destInputDialog();
176 if( (destUrl
= getValidDestUrl( destDir
, srcUrl
)).isEmpty() )
179 if(m_transferTreeModel
->findTransferByDestination(destUrl
) != 0 || (destUrl
.isLocalFile() && QFile::exists(destUrl
.path()))) {
180 KIO::RenameDialog
dlg( m_mainWindow
, i18n("Rename transfer"), srcUrl
,
181 destUrl
, KIO::M_MULTI
);
182 if (dlg
.exec() == KIO::R_RENAME
)
183 destUrl
= dlg
.newDestUrl();
187 createTransfer(srcUrl
, destUrl
, groupName
, start
);
190 void KGet::addTransfer(const QDomElement
& e
, const QString
& groupName
)
192 //We need to read these attributes now in order to know which transfer
194 KUrl srcUrl
= KUrl( e
.attribute("Source") );
195 KUrl destUrl
= KUrl( e
.attribute("Dest") );
197 kDebug(5001) << " src= " << srcUrl
.url()
198 << " dest= " << destUrl
.url()
199 << " group= "<< groupName
<< endl
;
201 if ( srcUrl
.isEmpty() || !isValidSource(srcUrl
)
202 || !isValidDestDirectory(destUrl
.directory()) )
205 createTransfer(srcUrl
, destUrl
, groupName
, false, &e
);
208 void KGet::addTransfer(KUrl::List srcUrls
, QString destDir
, // krazy:exclude=passbyvalue
209 const QString
& groupName
, bool start
)
211 KUrl::List urlsToDownload
;
213 KUrl::List::ConstIterator it
= srcUrls
.begin();
214 KUrl::List::ConstIterator itEnd
= srcUrls
.end();
216 for(; it
!=itEnd
; ++it
)
218 if ( isValidSource( *it
) )
219 urlsToDownload
.append( *it
);
222 if ( urlsToDownload
.count() == 0 )
225 if ( urlsToDownload
.count() == 1 )
227 // just one file -> ask for filename
228 addTransfer(srcUrls
.first(), destDir
+ srcUrls
.first().fileName(), groupName
, start
);
234 // multiple files -> ask for directory, not for every single filename
235 if (!isValidDestDirectory(destDir
) && !Settings::useDefaultDirectory())
236 destDir
= destInputDialog();
238 it
= urlsToDownload
.begin();
239 itEnd
= urlsToDownload
.end();
241 for ( ; it
!= itEnd
; ++it
)
243 if (destDir
.isEmpty())
245 if (Settings::useDefaultDirectory())
246 #ifdef Q_OS_WIN //krazy:exclude=cpp
247 destDir
= Settings::defaultDirectory().remove("file:///");
249 destDir
= Settings::defaultDirectory().remove("file://");
252 QString checkExceptions
= getSaveDirectoryFromExceptions(*it
);
253 if (Settings::enableExceptions() && !checkExceptions
.isEmpty())
254 destDir
= checkExceptions
;
256 destUrl
= getValidDestUrl(destDir
, *it
);
258 if(!isValidDestUrl(destUrl
))
261 createTransfer(*it
, destUrl
, groupName
, start
);
266 void KGet::delTransfer(TransferHandler
* transfer
)
268 Transfer
* t
= transfer
->m_transfer
;
270 m_transferTreeModel
->delTransfer(t
);
272 //Here I delete the Transfer. The other possibility is to move it to a list
273 //and to delete all these transfers when kget gets closed. Obviously, after
274 //the notification to the views that the transfer has been removed, all the
275 //pointers to it are invalid.
276 transfer
->postDeleteEvent();
277 // TODO: why does it crash if a download is going to be deleted which is not the last in the list?
278 // there are always no problems with the last download.
282 void KGet::moveTransfer(TransferHandler
* transfer
, const QString
& groupName
)
288 QList
<TransferHandler
*> KGet::selectedTransfers()
290 // kDebug(5001) << "KGet::selectedTransfers";
292 QList
<TransferHandler
*> selectedTransfers
;
294 QModelIndexList selectedIndexes
= m_selectionModel
->selectedRows();
296 foreach(QModelIndex currentIndex
, selectedIndexes
)
298 if(!m_transferTreeModel
->isTransferGroup(currentIndex
))
299 selectedTransfers
.append(static_cast<TransferHandler
*> (currentIndex
.internalPointer()));
302 return selectedTransfers
;
305 // This is the code that was used in the old selectedTransfers function
306 /* QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
307 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
309 for( ; it!=itEnd ; ++it )
311 TransferGroup::iterator it2 = (*it)->begin();
312 TransferGroup::iterator it2End = (*it)->end();
314 for( ; it2!=it2End ; ++it2 )
316 Transfer * transfer = (Transfer*) *it2;
318 if( transfer->isSelected() )
319 selectedTransfers.append( transfer->handler() );
322 return selectedTransfers;*/
325 QList
<TransferGroupHandler
*> KGet::selectedTransferGroups()
327 QList
<TransferGroupHandler
*> selectedTransferGroups
;
329 QModelIndexList selectedIndexes
= m_selectionModel
->selectedRows();
331 foreach(QModelIndex currentIndex
, selectedIndexes
)
333 if(m_transferTreeModel
->isTransferGroup(currentIndex
))
334 selectedTransferGroups
.append(static_cast<TransferGroupHandler
*> (currentIndex
.internalPointer()));
337 return selectedTransferGroups
;
340 TransferTreeSelectionModel
* KGet::selectionModel()
342 return m_selectionModel
;
345 void KGet::addTransferView(QAbstractItemView
* view
)
347 view
->setModel(m_transferTreeModel
);
350 void KGet::load( QString filename
) // krazy:exclude=passbyvalue
352 kDebug(5001) << "(" << filename
<< ")";
354 if(filename
.isEmpty())
355 filename
= KStandardDirs::locateLocal("appdata", "transfers.kgt");
359 //Try to save the transferlist to a temporary location
360 if(!KIO::NetAccess::download(KUrl(filename
), tmpFile
, 0))
366 kDebug(5001) << "file:" << filename
;
368 if(doc
.setContent(&file
))
370 QDomElement root
= doc
.documentElement();
372 QDomNodeList nodeList
= root
.elementsByTagName("TransferGroup");
373 int nItems
= nodeList
.length();
375 for( int i
= 0 ; i
< nItems
; i
++ )
377 TransferGroup
* foundGroup
= m_transferTreeModel
->findGroup( nodeList
.item(i
).toElement().attribute("Name") );
379 kDebug(5001) << "KGet::load -> group = " << nodeList
.item(i
).toElement().attribute("Name");
383 kDebug(5001) << "KGet::load -> group not found";
385 TransferGroup
* newGroup
= new TransferGroup(m_transferTreeModel
, m_scheduler
);
387 m_transferTreeModel
->addGroup(newGroup
);
389 newGroup
->load(nodeList
.item(i
).toElement());
392 postAddedTransferGroupEvent(newGroup
);
396 kDebug(5001) << "KGet::load -> group found";
398 //A group with this name already exists.
399 //Integrate the group's transfers with the ones read from file
400 foundGroup
->load(nodeList
.item(i
).toElement());
406 kWarning(5001) << "Error reading the transfers file";
410 void KGet::save( QString filename
) // krazy:exclude=passbyvalue
412 if ( !filename
.isEmpty()
413 && QFile::exists( filename
)
414 && (KMessageBox::questionYesNoCancel(0,
415 i18n("The file %1 already exists.\nOverwrite?", filename
),
416 i18n("Overwrite existing file?"), KStandardGuiItem::yes(),
417 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionFilenameExists" )
418 != KMessageBox::Yes
) )
421 if(filename
.isEmpty())
422 filename
= KStandardDirs::locateLocal("appdata", "transfers.kgt");
424 QDomDocument
doc(QString("KGetTransfers"));
425 QDomElement root
= doc
.createElement("Transfers");
426 doc
.appendChild(root
);
428 QList
<TransferGroup
*>::const_iterator it
= m_transferTreeModel
->transferGroups().begin();
429 QList
<TransferGroup
*>::const_iterator itEnd
= m_transferTreeModel
->transferGroups().end();
431 for ( ; it
!=itEnd
; ++it
)
433 QDomElement e
= doc
.createElement("TransferGroup");
437 QFile
file(filename
);
438 if ( !file
.open( QIODevice::WriteOnly
) )
440 //kWarning(5001)<<"Unable to open output file when saving";
441 KMessageBox::error(0,
442 i18n("Unable to save to: %1", filename
),
447 QTextStream
stream( &file
);
448 doc
.save( stream
, 0 );
452 TransferFactory
* KGet::factory(TransferHandler
* transfer
)
454 return transfer
->m_transfer
->factory();
457 KActionCollection
* KGet::actionCollection()
459 return m_mainWindow
->actionCollection();
462 void KGet::setSchedulerRunning(bool running
)
466 m_scheduler
->stop(); //stopall first, to have a clean startingpoint
467 m_scheduler
->start();
473 bool KGet::schedulerRunning()
475 return (m_scheduler
->countRunningJobs() > 0);
478 void KGet::setPluginsSettingsWidget(KTabWidget
* widget
)
481 QList
<TransferFactory
*>::iterator it
= m_transferFactories
.begin();
482 QList
<TransferFactory
*>::iterator itEnd
= m_transferFactories
.end();
484 QWidget
* settingsWidget
;
485 for( ; it
!=itEnd
; ++it
)
487 KDialog
*dialog
= static_cast<KDialog
*>(widget
->parent()->parent());
491 settingsWidget
= (*it
)->createSettingsWidget(dialog
);
493 widget
->addTab( settingsWidget
, (*it
)->displayName() );
497 QList
<TransferHandler
*> KGet::allTransfers()
499 QList
<TransferHandler
*> transfers
;
501 foreach (TransferGroup
*group
, KGet::m_transferTreeModel
->transferGroups())
503 transfers
<< group
->handler()->transfers();
509 void KGet::checkSystemTray()
512 bool running
= false;
514 foreach (TransferHandler
*handler
, KGet::allTransfers())
516 if (handler
->status() == Job::Running
)
523 m_mainWindow
->setSystemTrayDownloading(running
);
526 void KGet::settingsChanged()
530 QList
<TransferFactory
*>::const_iterator it
= m_transferFactories
.begin();
531 QList
<TransferFactory
*>::const_iterator itEnd
= m_transferFactories
.end();
533 for( ; it
!=itEnd
; ++it
)
535 (*it
)->settingsChanged();
539 void KGet::registerKJob(KJob
*job
)
541 m_jobManager
->registerJob(job
);
544 void KGet::unregisterKJob(KJob
*job
)
546 m_jobManager
->unregisterJob(job
);
549 void KGet::reloadKJobs()
551 m_jobManager
->reload();
554 QStringList
KGet::defaultFolders(const KUrl
&filename
, const QString
&groupname
)
556 kDebug(5001) << filename
<< groupname
;
559 if (Settings::enableExceptions())
560 list
.append(KGet::getSaveDirectoryFromExceptions(filename
));
562 TransferGroup
* group
= KGet::m_transferTreeModel
->findGroup(groupname
);
564 if (!group
->defaultFolder().isEmpty())
565 list
.append(group
->defaultFolder());
567 if (Settings::useDefaultDirectory())
568 list
.append(Settings::defaultDirectory());
570 if (!Settings::lastDirectory().isEmpty() &&
571 QString::compare(Settings::lastDirectory(), Settings::defaultDirectory()) != 0)
572 list
.append(Settings::lastDirectory());
574 foreach(QString string
, list
)
576 #ifdef Q_OS_WIN //krazy:exclude=cpp
577 string
.remove("file:///");
579 string
.remove("file://");
586 // ------ STATIC MEMBERS INITIALIZATION ------
587 QList
<ModelObserver
*> KGet::m_observers
;
588 TransferTreeModel
* KGet::m_transferTreeModel
;
589 TransferTreeSelectionModel
* KGet::m_selectionModel
;
590 QList
<TransferFactory
*> KGet::m_transferFactories
;
591 Scheduler
* KGet::m_scheduler
= new Scheduler();
592 MainWindow
* KGet::m_mainWindow
= 0;
593 KUiServerJobs
* KGet::m_jobManager
= new KUiServerJobs();
595 // ------ PRIVATE FUNCTIONS ------
598 m_transferTreeModel
= new TransferTreeModel(m_scheduler
);
599 m_selectionModel
= new TransferTreeSelectionModel(m_transferTreeModel
);
601 //Load all the available plugins
604 //Create the default group
605 addGroup(i18n("My Downloads"));
613 bool KGet::createTransfer(const KUrl
&src
, const KUrl
&dest
, const QString
& groupName
,
614 bool start
, const QDomElement
* e
)
616 kDebug(5001) << "srcUrl= " << src
.url() << " "
617 << "destUrl= " << dest
.url()
618 << "group= _" << groupName
<< "_" << endl
;
620 TransferGroup
* group
= m_transferTreeModel
->findGroup(groupName
);
623 kDebug(5001) << "KGet::createTransfer -> group not found";
624 group
= m_transferTreeModel
->transferGroups().first();
626 Transfer
* newTransfer
;
628 QList
<TransferFactory
*>::iterator it
= m_transferFactories
.begin();
629 QList
<TransferFactory
*>::iterator itEnd
= m_transferFactories
.end();
631 for( ; it
!=itEnd
; ++it
)
633 kDebug(5001) << "Trying plugin n.plugins=" << m_transferFactories
.size();
634 if((newTransfer
= (*it
)->createTransfer(src
, dest
, group
, m_scheduler
, e
)))
636 // kDebug(5001) << "KGet::createTransfer -> CREATING NEW TRANSFER ON GROUP: _" << group->name() << "_";
637 m_transferTreeModel
->addTransfer(newTransfer
, group
);
640 newTransfer
->handler()->start();
642 if (newTransfer
->percent() != 100) //Don't add a finished observer if the Transfer has already been finished
643 newTransfer
->handler()->addObserver(new TransferFinishedObserver());
648 kDebug(5001) << "Warning! No plugin found to handle the given url";
652 TransferDataSource
* KGet::createTransferDataSource(const KUrl
&src
)
655 QList
<TransferFactory
*>::iterator it
= m_transferFactories
.begin();
656 QList
<TransferFactory
*>::iterator itEnd
= m_transferFactories
.end();
658 TransferDataSource
*dataSource
;
659 for( ; it
!=itEnd
; ++it
)
661 dataSource
= (*it
)->createTransferDataSource(src
);
668 void KGet::postAddedTransferGroupEvent(TransferGroup
* group
, ModelObserver
* observer
)
673 observer
->addedTransferGroupEvent(group
->handler());
677 QList
<ModelObserver
*>::iterator it
= m_observers
.begin();
678 QList
<ModelObserver
*>::iterator itEnd
= m_observers
.end();
680 for(; it
!=itEnd
; ++it
)
682 kDebug(5001) << "message posted";
684 (*it
)->addedTransferGroupEvent(group
->handler());
688 void KGet::postRemovedTransferGroupEvent(TransferGroup
* group
, ModelObserver
* observer
)
692 observer
->removedTransferGroupEvent(group
->handler());
696 QList
<ModelObserver
*>::iterator it
= m_observers
.begin();
697 QList
<ModelObserver
*>::iterator itEnd
= m_observers
.end();
699 for(; it
!=itEnd
; ++it
)
701 (*it
)->removedTransferGroupEvent(group
->handler());
705 KUrl
KGet::urlInputDialog()
710 KUrl clipboardUrl
= KUrl(QApplication::clipboard()->text(QClipboard::Clipboard
).trimmed());
711 if (clipboardUrl
.isValid())
712 newtransfer
= clipboardUrl
.url();
716 newtransfer
= KInputDialog::getText(i18n("New Download"), i18n("Enter URL:"), newtransfer
, &ok
, 0);
720 //user pressed cancel
724 KUrl src
= KUrl(newtransfer
);
733 QString
KGet::destInputDialog()
735 QString destDir
= KFileDialog::getExistingDirectory(Settings::lastDirectory());
737 Settings::setLastDirectory( destDir
);
741 QString
KGet::getSaveDirectoryFromExceptions(const KUrl
&filename
)
745 QStringList list
= Settings::extensionsFolderList();
746 QStringList::Iterator it
= list
.begin();
747 QStringList::Iterator end
= list
.end();
749 // odd list items are regular expressions for extensions
755 if (!ext
.startsWith('*'))
759 rexp
.setPatternSyntax(QRegExp::Wildcard
);
761 if (rexp
.exactMatch(filename
.url())) {
767 #ifdef Q_OS_WIN //krazy:exclude=cpp
768 destDir
= destDir
.remove("file:///");
770 return destDir
.remove("file://");
773 bool KGet::isValidSource(const KUrl
&source
)
775 if (!source
.isValid())
777 KMessageBox::error(0,
778 i18n("Malformed URL:\n%1", source
.prettyUrl()),
782 // Check if a transfer with the same url already exists
783 Transfer
* transfer
= m_transferTreeModel
->findTransfer( source
);
786 if ( transfer
->status() == Job::Finished
)
788 // transfer is finished, ask if we want to download again
789 if (KMessageBox::questionYesNoCancel(0,
790 i18n("URL already saved:\n%1\nDownload again?", source
.prettyUrl()),
791 i18n("Download URL again?"), KStandardGuiItem::yes(),
792 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionUrlAlreadySaved" )
795 //TODO reimplement this
796 //transfer->slotRemove();
803 //Transfer is already in list and not finished, ...
811 bool KGet::isValidDestDirectory(const QString
& destDir
)
813 kDebug(5001) << destDir
;
814 if (!QFileInfo(destDir
).isDir())
816 if (QFileInfo(KUrl(destDir
).directory()).isWritable())
817 return (!destDir
.isEmpty());
818 if (!QFileInfo(KUrl(destDir
).directory()).isWritable() && !destDir
.isEmpty())
819 KMessageBox::error(0, i18n("Directory is not writable"));
823 if (QFileInfo(destDir
).isWritable())
824 return (!destDir
.isEmpty());
825 if (!QFileInfo(destDir
).isWritable() && !destDir
.isEmpty())
826 KMessageBox::error(0, i18n("Directory is not writable"));
831 bool KGet::isValidDestUrl(const KUrl
&destUrl
)
833 if(KIO::NetAccess::exists(destUrl
, KIO::NetAccess::DestinationSide
, 0))
835 if (KMessageBox::warningYesNoCancel(0,
836 i18n("Destination file \n%1\nalready exists.\n"
837 "Do you want to overwrite it?", destUrl
.prettyUrl()))
840 safeDeleteFile( destUrl
);
846 if (m_transferTreeModel
->findTransferByDestination(destUrl
) || destUrl
.isEmpty())
851 KIO::open_RenameDlg(i18n("File already exists"),
852 (*it).url(), destUrl.url(),
857 KUrl
KGet::getValidDestUrl(const QString
& destDir
, const KUrl
&srcUrl
)
859 if ( !isValidDestDirectory(destDir
) )
862 // create a proper destination file from destDir
863 KUrl destUrl
= KUrl( destDir
);
864 QString filename
= srcUrl
.fileName();
866 if ( filename
.isEmpty() )
868 // simply use the full url as filename
869 filename
= KUrl::toPercentEncoding( srcUrl
.prettyUrl(), "/" );
870 kDebug(5001) << " Filename is empty. Setting to " << filename
;
871 kDebug(5001) << " srcUrl = " << srcUrl
.url();
872 kDebug(5001) << " prettyUrl = " << srcUrl
.prettyUrl();
874 if (QFileInfo(destUrl
.path()).isDir())
876 kDebug(5001) << " Filename is not empty";
877 destUrl
.adjustPath( KUrl::AddTrailingSlash
);
878 destUrl
.setFileName( filename
);
880 if (!isValidDestUrl(destUrl
))
882 kDebug(5001) << " destUrl " << destUrl
.path() << " is not valid";
888 void KGet::loadPlugins()
890 // Add versioning constraint
892 str
= "[X-KDE-KGet-framework-version] == ";
893 str
+= QString::number( FrameworkVersion
);
895 str
+= "[X-KDE-KGet-rank] > 0";
897 str
+= "[X-KDE-KGet-plugintype] == ";
899 KService::List offers
;
901 //TransferFactory plugins
902 offers
= KServiceTypeTrader::self()->query( "KGet/Plugin", str
+ "'TransferFactory'" );
904 //Here we use a QMap only to easily sort the plugins by rank
905 QMap
<int, KService::Ptr
> services
;
906 QMap
<int, KService::Ptr
>::iterator it
;
908 for ( int i
= 0; i
< offers
.count(); ++i
)
910 services
[ offers
[i
]->property( "X-KDE-KGet-rank" ).toInt() ] = offers
[i
];
911 kDebug(5001) << " TransferFactory plugin found:" << endl
<<
912 " rank = " << offers
[i
]->property( "X-KDE-KGet-rank" ).toInt() << endl
<<
913 " plugintype = " << offers
[i
]->property( "X-KDE-KGet-plugintype" ) << endl
;
916 //I must fill this pluginList before and my m_transferFactories list after.
917 //This because calling the KLibLoader::globalLibrary() erases the static
918 //members of this class (why?), such as the m_transferFactories list.
919 QList
<KGetPlugin
*> pluginList
;
921 for( it
= services
.begin(); it
!= services
.end(); ++it
)
924 if( (plugin
= createPluginFromService(*it
)) != 0 )
926 pluginList
.prepend(plugin
);
927 kDebug(5001) << "TransferFactory plugin (" << (*it
)->library()
928 << ") found and added to the list of available plugins" << endl
;
931 kDebug(5001) << "Error loading TransferFactory plugin ("
932 << (*it
)->library() << ")" << endl
;
935 QList
<KGetPlugin
*>::iterator it2
= pluginList
.begin();
936 QList
<KGetPlugin
*>::iterator it2End
= pluginList
.end();
938 for( ; it2
!=it2End
; ++it2
)
939 m_transferFactories
.append( static_cast<TransferFactory
*>(*it2
) );
941 kDebug(5001) << "Number of factories = " << m_transferFactories
.size();
944 KGetPlugin
* KGet::createPluginFromService( const KService::Ptr
&service
)
946 //try to load the specified library
947 KPluginFactory
*factory
= KPluginLoader(service
->library()).factory();
951 KMessageBox::error(0, i18n("<html><p>KPluginFactory could not load the plugin:<br/><i>%1</i></p></html>",
952 service
->library()));
953 kError(5001) << "KPluginFactory could not load the plugin:" << service
->library();
956 KGetPlugin
* plugin
= factory
->create
< TransferFactory
>(0);
961 bool KGet::safeDeleteFile( const KUrl
& url
)
963 if ( url
.isLocalFile() )
965 QFileInfo
info( url
.path() );
968 KMessageBox::information(0L,i18n("Not deleting\n%1\nas it is a "
969 "directory.", url
.prettyUrl()),
970 i18n("Not Deleted"));
973 KIO::NetAccess::del( url
, 0L );
978 KMessageBox::information( 0L,
979 i18n("Not deleting\n%1\nas it is not a local"
980 " file.", url
.prettyUrl()),
981 i18n("Not Deleted") );
985 TransferFinishedObserver::TransferFinishedObserver()
990 void TransferFinishedObserver::transferChangedEvent(TransferHandler
* transfer
)
994 if (transfer
->status() == Job::Finished
&& Settings::quitAfterCompletedTransfer())
999 if (prevStatus
!= transfer
->statusText())//FIXME: HACK: better: check statusFlags if it
1000 { //contains Tc_Status (flags & Transfer::Tc_Status <-doesn't work)
1001 prevStatus
= transfer
->statusText();
1002 KGet::checkSystemTray();
1006 void TransferFinishedObserver::checkAndFinish()
1008 bool quitFlag
= true;
1009 foreach(TransferGroup
*transferGroup
, KGet::m_transferTreeModel
->transferGroups()) {
1010 foreach(TransferHandler
*transfer
, transferGroup
->handler()->transfers()) {
1011 if(transfer
->status() != Job::Finished
) {
1017 // check if there is some unfinished transfer in scheduler queues
1019 KPassivePopup
*message
;
1020 // we have to call diferent message from kpassivePopup
1021 // one with parent as QWidget for the mainWindow
1022 // and another with parent as QSystemTrayIcon if the parent is a systemTray
1023 // so passing the QSystemTrayIcon as QWidget don't work
1024 if(Settings::enableSystemTray())
1026 message
= KPassivePopup::message(5000, KGET_QUIT_MESSAGE_TITLE
,
1028 KGet::m_mainWindow
->systemTray());
1032 message
= KPassivePopup::message(5000, KGET_QUIT_MESSAGE_TITLE
,
1034 KGet::m_mainWindow
);
1037 QObject::connect(message
, SIGNAL(destroyed()), KGet::m_mainWindow
, SLOT(slotQuit()));