1 /* This file is part of the KDE project
3 Copyright (C) 2005 Dario Massarin <nekkar@libero.it>
4 Copyright (C) 2007-2008 Lukas Appelhans <l.appelhans@gmx.de>
5 Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
6 Copyright (C) 2008 Dario Freddi <drf54321@gmail.com>
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
14 #include "core/kget.h"
16 #include "mainwindow.h"
17 #include "core/transfer.h"
18 #include "core/transferdatasource.h"
19 #include "core/transfergroup.h"
20 #include "core/transfergrouphandler.h"
21 #include "core/transfertreemodel.h"
22 #include "core/transfertreeselectionmodel.h"
23 #include "core/plugin/plugin.h"
24 #include "core/plugin/transferfactory.h"
25 #include "core/observer.h"
26 #include "core/kuiserverjobs.h"
27 #include "core/transfergroupscheduler.h"
30 #include <kio/netaccess.h>
31 #include <kinputdialog.h>
32 #include <kfiledialog.h>
33 #include <kmessagebox.h>
35 #include <kstandarddirs.h>
36 #include <kservicetypetrader.h>
37 #include <kiconloader.h>
38 #include <kactioncollection.h>
39 #include <kio/renamedialog.h>
40 #include <KSystemTrayIcon>
41 #include <KSharedConfig>
42 #include <KPluginInfo>
44 #include <QTextStream>
45 #include <QDomElement>
46 #include <QApplication>
48 #include <QAbstractItemView>
51 * This is our KGet class. This is where the user's transfers and searches are
52 * stored and organized.
53 * Use this class from the views to add or remove transfers or searches
54 * In order to organize the transfers inside categories we have a TransferGroup
55 * class. By definition, a transfer must always belong to a TransferGroup. If we
56 * don't want it to be displayed by the gui inside a specific group, we will put
57 * it in the group named "Not grouped" (better name?).
60 KGet
& KGet::self( MainWindow
* mainWindow
)
64 m_mainWindow
= mainWindow
;
71 void KGet::addObserver(ModelObserver
* observer
)
75 m_observers
.append(observer
);
77 //Update the new observer with the TransferGroups objects of the model
78 QList
<TransferGroup
*>::const_iterator it
= m_transferTreeModel
->transferGroups().begin();
79 QList
<TransferGroup
*>::const_iterator itEnd
= m_transferTreeModel
->transferGroups().end();
81 for( ; it
!=itEnd
; ++it
)
83 postAddedTransferGroupEvent(*it
, observer
);
86 kDebug(5001) << " >>> EXITING";
89 void KGet::delObserver(ModelObserver
* observer
)
91 m_observers
.removeAll(observer
);
94 bool KGet::addGroup(const QString
& groupName
)
98 // Check if a group with that name already exists
99 if(m_transferTreeModel
->findGroup(groupName
))
102 TransferGroup
* group
= new TransferGroup(m_transferTreeModel
, m_scheduler
, groupName
);
103 m_transferTreeModel
->addGroup(group
);
106 postAddedTransferGroupEvent(group
);
111 void KGet::delGroup(const QString
& groupName
)
113 TransferGroup
* group
= m_transferTreeModel
->findGroup(groupName
);
117 m_transferTreeModel
->delGroup(group
);
118 postRemovedTransferGroupEvent(group
);
123 void KGet::renameGroup(const QString
& oldName
, const QString
& newName
)
125 TransferGroup
*group
= m_transferTreeModel
->findGroup(oldName
);
129 group
->handler()->setName(newName
);
133 QStringList
KGet::transferGroupNames()
137 foreach(TransferGroup
*group
, m_transferTreeModel
->transferGroups()) {
138 names
<< group
->name();
144 void KGet::addTransfer(KUrl srcUrl
, QString destDir
, // krazy:exclude=passbyvalue
145 const QString
& groupName
, bool start
)
147 kDebug(5001) << "Source:" << srcUrl
.url();
151 if ( srcUrl
.isEmpty() )
153 //No src location: we let the user insert it manually
154 srcUrl
= urlInputDialog();
155 if( srcUrl
.isEmpty() )
159 if ( !isValidSource( srcUrl
) )
162 if (destDir
.isEmpty())
164 if (Settings::useDefaultDirectory())
165 #ifdef Q_OS_WIN //krazy:exclude=cpp
166 destDir
= Settings::defaultDirectory().remove("file:///");
168 destDir
= Settings::defaultDirectory().remove("file://");
171 QString checkExceptions
= getSaveDirectoryFromExceptions(srcUrl
);
172 if (Settings::enableExceptions() && !checkExceptions
.isEmpty())
173 destDir
= checkExceptions
;
176 if (!isValidDestDirectory(destDir
))
177 destDir
= destInputDialog();
179 if( (destUrl
= getValidDestUrl( destDir
, srcUrl
)).isEmpty() )
182 if(m_transferTreeModel
->findTransferByDestination(destUrl
) != 0 || (destUrl
.isLocalFile() && QFile::exists(destUrl
.path()))) {
183 KIO::RenameDialog
dlg( m_mainWindow
, i18n("Rename transfer"), srcUrl
,
184 destUrl
, KIO::M_MULTI
);
185 if (dlg
.exec() == KIO::R_RENAME
)
186 destUrl
= dlg
.newDestUrl();
190 createTransfer(srcUrl
, destUrl
, groupName
, start
);
193 void KGet::addTransfer(const QDomElement
& e
, const QString
& groupName
)
195 //We need to read these attributes now in order to know which transfer
197 KUrl srcUrl
= KUrl( e
.attribute("Source") );
198 KUrl destUrl
= KUrl( e
.attribute("Dest") );
200 kDebug(5001) << " src= " << srcUrl
.url()
201 << " dest= " << destUrl
.url()
202 << " group= "<< groupName
<< endl
;
204 if ( srcUrl
.isEmpty() || !isValidSource(srcUrl
)
205 || !isValidDestDirectory(destUrl
.directory()) )
208 createTransfer(srcUrl
, destUrl
, groupName
, false, &e
);
211 void KGet::addTransfer(KUrl::List srcUrls
, QString destDir
, // krazy:exclude=passbyvalue
212 const QString
& groupName
, bool start
)
214 KUrl::List urlsToDownload
;
216 KUrl::List::Iterator it
= srcUrls
.begin();
217 KUrl::List::Iterator itEnd
= srcUrls
.end();
219 for(; it
!=itEnd
; ++it
)
221 if ( isValidSource( *it
) )
222 urlsToDownload
.append( *it
);
225 if ( urlsToDownload
.count() == 0 )
228 if ( urlsToDownload
.count() == 1 )
230 // just one file -> ask for filename
231 addTransfer(srcUrls
.first(), destDir
+ srcUrls
.first().fileName(), groupName
, start
);
237 // multiple files -> ask for directory, not for every single filename
238 if (!isValidDestDirectory(destDir
) && !Settings::useDefaultDirectory())
239 destDir
= destInputDialog();
241 it
= urlsToDownload
.begin();
242 itEnd
= urlsToDownload
.end();
244 for ( ; it
!= itEnd
; ++it
)
246 if (destDir
.isEmpty())
248 if (Settings::useDefaultDirectory())
249 #ifdef Q_OS_WIN //krazy:exclude=cpp
250 destDir
= Settings::defaultDirectory().remove("file:///");
252 destDir
= Settings::defaultDirectory().remove("file://");
255 QString checkExceptions
= getSaveDirectoryFromExceptions(*it
);
256 if (Settings::enableExceptions() && !checkExceptions
.isEmpty())
257 destDir
= checkExceptions
;
259 destUrl
= getValidDestUrl(destDir
, *it
);
261 if(!isValidDestUrl(destUrl
))
264 createTransfer(*it
, destUrl
, groupName
, start
);
269 bool KGet::delTransfer(TransferHandler
* transfer
)
271 Transfer
* t
= transfer
->m_transfer
;
274 m_transferTreeModel
->delTransfer(t
);
276 //Here I delete the Transfer. The other possibility is to move it to a list
277 //and to delete all these transfers when kget gets closed. Obviously, after
278 //the notification to the views that the transfer has been removed, all the
279 //pointers to it are invalid.
280 transfer
->postDeleteEvent();
285 void KGet::moveTransfer(TransferHandler
* transfer
, const QString
& groupName
)
291 void KGet::redownloadTransfer(TransferHandler
* transfer
)
293 QString group
= transfer
->group()->name();
294 QString src
= transfer
->source().url();
295 QString dest
= transfer
->dest().url();
296 bool running
= false;
297 if (transfer
->status() == Job::Running
)
300 KGet::delTransfer(transfer
);
301 KGet::addTransfer(src
, dest
, group
, running
);
304 QList
<TransferHandler
*> KGet::selectedTransfers()
306 // kDebug(5001) << "KGet::selectedTransfers";
308 QList
<TransferHandler
*> selectedTransfers
;
310 QModelIndexList selectedIndexes
= m_selectionModel
->selectedRows();
312 foreach(const QModelIndex
¤tIndex
, selectedIndexes
)
314 if(!m_transferTreeModel
->isTransferGroup(currentIndex
))
315 selectedTransfers
.append(static_cast<TransferHandler
*> (currentIndex
.internalPointer()));
318 return selectedTransfers
;
321 // This is the code that was used in the old selectedTransfers function
322 /* QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
323 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
325 for( ; it!=itEnd ; ++it )
327 TransferGroup::iterator it2 = (*it)->begin();
328 TransferGroup::iterator it2End = (*it)->end();
330 for( ; it2!=it2End ; ++it2 )
332 Transfer * transfer = (Transfer*) *it2;
334 if( transfer->isSelected() )
335 selectedTransfers.append( transfer->handler() );
338 return selectedTransfers;*/
341 QList
<TransferHandler
*> KGet::finishedTransfers()
343 QList
<TransferHandler
*> finishedTransfers
;
345 foreach(TransferHandler
*transfer
, allTransfers())
347 if (transfer
->status() == Job::Finished
) {
348 finishedTransfers
<< transfer
;
351 return finishedTransfers
;
354 QList
<TransferGroupHandler
*> KGet::selectedTransferGroups()
356 QList
<TransferGroupHandler
*> selectedTransferGroups
;
358 QModelIndexList selectedIndexes
= m_selectionModel
->selectedRows();
360 foreach(const QModelIndex
¤tIndex
, selectedIndexes
)
362 if(m_transferTreeModel
->isTransferGroup(currentIndex
))
363 selectedTransferGroups
.append(static_cast<TransferGroupHandler
*> (currentIndex
.internalPointer()));
366 return selectedTransferGroups
;
369 TransferTreeSelectionModel
* KGet::selectionModel()
371 return m_selectionModel
;
374 void KGet::addTransferView(QAbstractItemView
* view
)
376 view
->setModel(m_transferTreeModel
);
379 void KGet::load( QString filename
) // krazy:exclude=passbyvalue
381 kDebug(5001) << "(" << filename
<< ")";
383 if(filename
.isEmpty())
384 filename
= KStandardDirs::locateLocal("appdata", "transfers.kgt");
388 //Try to save the transferlist to a temporary location
389 if(!KIO::NetAccess::download(KUrl(filename
), tmpFile
, 0))
395 kDebug(5001) << "file:" << filename
;
397 if(doc
.setContent(&file
))
399 QDomElement root
= doc
.documentElement();
401 QDomNodeList nodeList
= root
.elementsByTagName("TransferGroup");
402 int nItems
= nodeList
.length();
404 for( int i
= 0 ; i
< nItems
; i
++ )
406 TransferGroup
* foundGroup
= m_transferTreeModel
->findGroup( nodeList
.item(i
).toElement().attribute("Name") );
408 kDebug(5001) << "KGet::load -> group = " << nodeList
.item(i
).toElement().attribute("Name");
412 kDebug(5001) << "KGet::load -> group not found";
414 TransferGroup
* newGroup
= new TransferGroup(m_transferTreeModel
, m_scheduler
);
416 m_transferTreeModel
->addGroup(newGroup
);
418 newGroup
->load(nodeList
.item(i
).toElement());
421 postAddedTransferGroupEvent(newGroup
);
425 kDebug(5001) << "KGet::load -> group found";
427 //A group with this name already exists.
428 //Integrate the group's transfers with the ones read from file
429 foundGroup
->load(nodeList
.item(i
).toElement());
435 kWarning(5001) << "Error reading the transfers file";
438 addObserver(new GenericModelObserver());
441 void KGet::save( QString filename
, bool plain
) // krazy:exclude=passbyvalue
443 if ( !filename
.isEmpty()
444 && QFile::exists( filename
)
445 && (KMessageBox::questionYesNoCancel(0,
446 i18n("The file %1 already exists.\nOverwrite?", filename
),
447 i18n("Overwrite existing file?"), KStandardGuiItem::yes(),
448 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionFilenameExists" )
449 != KMessageBox::Yes
) )
452 if(filename
.isEmpty())
453 filename
= KStandardDirs::locateLocal("appdata", "transfers.kgt");
455 QFile
file(filename
);
456 if ( !file
.open( QIODevice::WriteOnly
) )
458 //kWarning(5001)<<"Unable to open output file when saving";
459 KMessageBox::error(0,
460 i18n("Unable to save to: %1", filename
),
467 QTextStream
out(&file
);
468 foreach(TransferHandler
*handler
, allTransfers()) {
469 out
<< handler
->source().prettyUrl() << endl
;
473 QDomDocument
doc(QString("KGetTransfers"));
474 QDomElement root
= doc
.createElement("Transfers");
475 doc
.appendChild(root
);
477 QList
<TransferGroup
*>::const_iterator it
= m_transferTreeModel
->transferGroups().begin();
478 QList
<TransferGroup
*>::const_iterator itEnd
= m_transferTreeModel
->transferGroups().end();
480 for ( ; it
!=itEnd
; ++it
)
482 QDomElement e
= doc
.createElement("TransferGroup");
487 QTextStream
stream( &file
);
488 doc
.save( stream
, 0 );
493 TransferFactory
* KGet::factory(TransferHandler
* transfer
)
495 return transfer
->m_transfer
->factory();
498 KActionCollection
* KGet::actionCollection()
500 return m_mainWindow
->actionCollection();
503 void KGet::setSchedulerRunning(bool running
)
507 m_scheduler
->stop(); //stopall first, to have a clean startingpoint
508 m_scheduler
->start();
514 bool KGet::schedulerRunning()
516 return (m_scheduler
->countRunningJobs() > 0);
519 QList
<TransferHandler
*> KGet::allTransfers()
521 QList
<TransferHandler
*> transfers
;
523 foreach (TransferGroup
*group
, KGet::m_transferTreeModel
->transferGroups())
525 transfers
<< group
->handler()->transfers();
530 QList
<TransferGroupHandler
*> KGet::allTransferGroups()
532 QList
<TransferGroupHandler
*> transfergroups
;
534 foreach (TransferGroup
*group
, KGet::m_transferTreeModel
->transferGroups())
536 transfergroups
<< group
->handler();
538 return transfergroups
;
541 TransferHandler
* KGet::findTransfer(const KUrl
&src
)
543 return KGet::m_transferTreeModel
->findTransfer(src
)->handler();
546 void KGet::checkSystemTray()
549 bool running
= false;
551 foreach (TransferHandler
*handler
, KGet::allTransfers())
553 if (handler
->status() == Job::Running
)
560 m_mainWindow
->setSystemTrayDownloading(running
);
563 void KGet::settingsChanged()
567 QList
<TransferFactory
*>::const_iterator it
= m_transferFactories
.constBegin();
568 QList
<TransferFactory
*>::const_iterator itEnd
= m_transferFactories
.constEnd();
570 for( ; it
!=itEnd
; ++it
)
572 (*it
)->settingsChanged();
576 void KGet::registerKJob(KJob
*job
)
578 m_jobManager
->registerJob(job
);
581 void KGet::unregisterKJob(KJob
*job
)
583 m_jobManager
->unregisterJob(job
);
586 void KGet::reloadKJobs()
588 m_jobManager
->reload();
591 QStringList
KGet::defaultFolders(const KUrl
&filename
, const QString
&groupname
)
593 kDebug(5001) << filename
<< groupname
;
596 const QString saveDirectoryFromExceptions
= KGet::getSaveDirectoryFromExceptions(filename
);
597 if (Settings::enableExceptions() && !saveDirectoryFromExceptions
.isEmpty())
598 list
.append(saveDirectoryFromExceptions
);
600 TransferGroup
* group
= KGet::m_transferTreeModel
->findGroup(groupname
);
602 if (!group
->defaultFolder().isEmpty())
603 list
.append(group
->defaultFolder());
605 if (Settings::useDefaultDirectory())
606 list
.append(Settings::defaultDirectory());
608 if (!Settings::lastDirectory().isEmpty() &&
609 QString::compare(Settings::lastDirectory(), Settings::defaultDirectory()) != 0)
610 list
.append(Settings::lastDirectory());
613 list
.append(QDir::homePath());//If we have no defaultDir, we return the home-dir
615 for (int i
= 0; i
< list
.size(); i
++)
617 #ifdef Q_OS_WIN //krazy:exclude=cpp
618 list
[i
] = list
[i
].remove("file:///");
620 list
[i
] = list
[i
].remove("file://");
626 void KGet::setGlobalDownloadLimit(int limit
)
628 m_scheduler
->setDownloadLimit(limit
);
630 m_scheduler
->calculateDownloadLimit();
633 void KGet::setGlobalUploadLimit(int limit
)
635 m_scheduler
->setUploadLimit(limit
);
637 m_scheduler
->calculateUploadLimit();
640 void KGet::calculateGlobalSpeedLimits()
642 if (m_scheduler
->downloadLimit())//TODO: Remove this and the both other hacks in the 2 upper functions with a better replacement
643 m_scheduler
->calculateDownloadLimit();
644 if (m_scheduler
->uploadLimit())
645 m_scheduler
->calculateUploadLimit();
648 void KGet::calculateGlobalDownloadLimit()
650 m_scheduler
->calculateDownloadLimit();
653 void KGet::calculateGlobalUploadLimit()
655 m_scheduler
->calculateUploadLimit();
658 // ------ STATIC MEMBERS INITIALIZATION ------
659 QList
<ModelObserver
*> KGet::m_observers
;
660 TransferTreeModel
* KGet::m_transferTreeModel
;
661 TransferTreeSelectionModel
* KGet::m_selectionModel
;
662 QList
<TransferFactory
*> KGet::m_transferFactories
;
663 TransferGroupScheduler
* KGet::m_scheduler
= new TransferGroupScheduler();
664 MainWindow
* KGet::m_mainWindow
= 0;
665 KUiServerJobs
* KGet::m_jobManager
= new KUiServerJobs();
667 // ------ PRIVATE FUNCTIONS ------
670 m_transferTreeModel
= new TransferTreeModel(m_scheduler
);
671 m_selectionModel
= new TransferTreeSelectionModel(m_transferTreeModel
);
673 //Load all the available plugins
676 //Create the default group
677 addGroup(i18n("My Downloads"));
685 bool KGet::createTransfer(const KUrl
&src
, const KUrl
&dest
, const QString
& groupName
,
686 bool start
, const QDomElement
* e
)
688 kDebug(5001) << "srcUrl= " << src
.url() << " "
689 << "destUrl= " << dest
.url()
690 << "group= _" << groupName
<< "_" << endl
;
692 TransferGroup
* group
= m_transferTreeModel
->findGroup(groupName
);
695 kDebug(5001) << "KGet::createTransfer -> group not found";
696 group
= m_transferTreeModel
->transferGroups().first();
698 Transfer
* newTransfer
;
700 QList
<TransferFactory
*>::iterator it
= m_transferFactories
.begin();
701 QList
<TransferFactory
*>::iterator itEnd
= m_transferFactories
.end();
703 for( ; it
!=itEnd
; ++it
)
705 kDebug(5001) << "Trying plugin n.plugins=" << m_transferFactories
.size();
706 if((newTransfer
= (*it
)->createTransfer(src
, dest
, group
, m_scheduler
, e
)))
708 // kDebug(5001) << "KGet::createTransfer -> CREATING NEW TRANSFER ON GROUP: _" << group->name() << "_";
709 m_transferTreeModel
->addTransfer(newTransfer
, group
);
712 newTransfer
->handler()->start();
714 if (newTransfer->percent() != 100) //Don't add a finished observer if the Transfer has already been finished
715 newTransfer->handler()->addObserver(new GenericTransferObserver());
720 kDebug(5001) << "Warning! No plugin found to handle the given url";
724 TransferDataSource
* KGet::createTransferDataSource(const KUrl
&src
)
727 QList
<TransferFactory
*>::iterator it
= m_transferFactories
.begin();
728 QList
<TransferFactory
*>::iterator itEnd
= m_transferFactories
.end();
730 TransferDataSource
*dataSource
;
731 for( ; it
!=itEnd
; ++it
)
733 dataSource
= (*it
)->createTransferDataSource(src
);
740 void KGet::postAddedTransferGroupEvent(TransferGroup
* group
, ModelObserver
* observer
)
745 observer
->addedTransferGroupEvent(group
->handler());
749 QList
<ModelObserver
*>::iterator it
= m_observers
.begin();
750 QList
<ModelObserver
*>::iterator itEnd
= m_observers
.end();
752 for(; it
!=itEnd
; ++it
)
754 kDebug(5001) << "message posted";
756 (*it
)->addedTransferGroupEvent(group
->handler());
760 void KGet::postRemovedTransferGroupEvent(TransferGroup
* group
, ModelObserver
* observer
)
764 observer
->removedTransferGroupEvent(group
->handler());
768 QList
<ModelObserver
*>::iterator it
= m_observers
.begin();
769 QList
<ModelObserver
*>::iterator itEnd
= m_observers
.end();
771 for(; it
!=itEnd
; ++it
)
773 (*it
)->removedTransferGroupEvent(group
->handler());
777 KUrl
KGet::urlInputDialog()
782 KUrl clipboardUrl
= KUrl(QApplication::clipboard()->text(QClipboard::Clipboard
).trimmed());
783 if (clipboardUrl
.isValid())
784 newtransfer
= clipboardUrl
.url();
788 newtransfer
= KInputDialog::getText(i18n("New Download"), i18n("Enter URL:"), newtransfer
, &ok
, 0);
792 //user pressed cancel
796 KUrl src
= KUrl(newtransfer
);
805 QString
KGet::destInputDialog()
807 QString destDir
= KFileDialog::getExistingDirectory(Settings::lastDirectory());
809 Settings::setLastDirectory( destDir
);
813 QString
KGet::getSaveDirectoryFromExceptions(const KUrl
&filename
)
817 const QStringList list
= Settings::extensionsFolderList();
818 QStringList::ConstIterator it
= list
.begin();
819 const QStringList::ConstIterator end
= list
.end();
821 // odd list items are regular expressions for extensions
827 if (!ext
.startsWith('*'))
831 rexp
.setPatternSyntax(QRegExp::Wildcard
);
833 if (rexp
.exactMatch(filename
.url())) {
839 #ifdef Q_OS_WIN //krazy:exclude=cpp
840 destDir
= destDir
.remove("file:///");
842 return destDir
.remove("file://");
845 bool KGet::isValidSource(const KUrl
&source
)
847 // Check if the URL is well formed
848 if (!source
.isValid())
850 KMessageBox::error(0,
851 i18n("Malformed URL:\n%1", source
.prettyUrl()),
856 // Check if the URL contains the protocol
857 if ( source
.protocol().isEmpty() ){
859 KMessageBox::error(0, i18n("Malformed URL, protocol missing:\n%1", source
.prettyUrl()),
864 // Check if a transfer with the same url already exists
865 Transfer
* transfer
= m_transferTreeModel
->findTransfer( source
);
868 if ( transfer
->status() == Job::Finished
)
870 // transfer is finished, ask if we want to download again
871 if (KMessageBox::questionYesNoCancel(0,
872 i18n("URL already saved:\n%1\nDownload again?", source
.prettyUrl()),
873 i18n("Download URL again?"), KStandardGuiItem::yes(),
874 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionUrlAlreadySaved" )
878 TransferHandler
* th
= transfer
->handler();
879 //TODO If the transfer is expanded, it crash.
880 // transfer should be collapsed before.
881 // Is correct close it from the KGet class or should it
882 // be handled in the viewscontainer?
883 // KGet class should be generic, it shouldn't
884 // interfere with the UI
885 KGet::delTransfer(th
);
891 //Transfer is already in list and not finished, ...
899 bool KGet::isValidDestDirectory(const QString
& destDir
)
901 kDebug(5001) << destDir
;
902 if (!QFileInfo(destDir
).isDir())
904 if (QFileInfo(KUrl(destDir
).directory()).isWritable())
905 return (!destDir
.isEmpty());
906 if (!QFileInfo(KUrl(destDir
).directory()).isWritable() && !destDir
.isEmpty())
907 KMessageBox::error(0, i18n("Directory is not writable"));
911 if (QFileInfo(destDir
).isWritable())
912 return (!destDir
.isEmpty());
913 if (!QFileInfo(destDir
).isWritable() && !destDir
.isEmpty())
914 KMessageBox::error(0, i18n("Directory is not writable"));
919 bool KGet::isValidDestUrl(const KUrl
&destUrl
)
921 if(KIO::NetAccess::exists(destUrl
, KIO::NetAccess::DestinationSide
, 0))
923 if (KMessageBox::warningYesNoCancel(0,
924 i18n("Destination file \n%1\nalready exists.\n"
925 "Do you want to overwrite it?", destUrl
.prettyUrl()))
928 safeDeleteFile( destUrl
);
934 if (m_transferTreeModel
->findTransferByDestination(destUrl
) || destUrl
.isEmpty())
939 KIO::open_RenameDlg(i18n("File already exists"),
940 (*it).url(), destUrl.url(),
945 KUrl
KGet::getValidDestUrl(const QString
& destDir
, const KUrl
&srcUrl
)
947 if ( !isValidDestDirectory(destDir
) )
950 // create a proper destination file from destDir
951 KUrl destUrl
= KUrl( destDir
);
952 QString filename
= srcUrl
.fileName();
954 if ( filename
.isEmpty() )
956 // simply use the full url as filename
957 filename
= KUrl::toPercentEncoding( srcUrl
.prettyUrl(), "/" );
958 kDebug(5001) << " Filename is empty. Setting to " << filename
;
959 kDebug(5001) << " srcUrl = " << srcUrl
.url();
960 kDebug(5001) << " prettyUrl = " << srcUrl
.prettyUrl();
962 if (QFileInfo(destUrl
.path()).isDir())
964 kDebug(5001) << " Filename is not empty";
965 destUrl
.adjustPath( KUrl::AddTrailingSlash
);
966 destUrl
.setFileName( filename
);
968 if (!isValidDestUrl(destUrl
))
970 kDebug(5001) << " destUrl " << destUrl
.path() << " is not valid";
976 void KGet::loadPlugins()
978 m_transferFactories
.clear();
979 // Add versioning constraint
981 str
= "[X-KDE-KGet-framework-version] == ";
982 str
+= QString::number( FrameworkVersion
);
984 str
+= "[X-KDE-KGet-rank] > 0";
986 str
+= "[X-KDE-KGet-plugintype] == ";
988 KService::List offers
;
990 //TransferFactory plugins
991 offers
= KServiceTypeTrader::self()->query( "KGet/Plugin", str
+ "'TransferFactory'" );
993 //Here we use a QMap only to easily sort the plugins by rank
994 QMap
<int, KService::Ptr
> services
;
995 QMap
<int, KService::Ptr
>::iterator it
;
997 for ( int i
= 0; i
< offers
.count(); ++i
)
999 services
[ offers
[i
]->property( "X-KDE-KGet-rank" ).toInt() ] = offers
[i
];
1000 kDebug(5001) << " TransferFactory plugin found:" << endl
<<
1001 " rank = " << offers
[i
]->property( "X-KDE-KGet-rank" ).toInt() << endl
<<
1002 " plugintype = " << offers
[i
]->property( "X-KDE-KGet-plugintype" ) << endl
;
1005 //I must fill this pluginList before and my m_transferFactories list after.
1006 //This because calling the KLibLoader::globalLibrary() erases the static
1007 //members of this class (why?), such as the m_transferFactories list.
1008 QList
<KGetPlugin
*> pluginList
;
1010 KConfigGroup plugins
= KConfigGroup(KGlobal::config(), "Plugins");
1012 for( it
= services
.begin(); it
!= services
.end(); ++it
)
1014 KPluginInfo
info(*it
);
1017 if( !info
.isPluginEnabled() ) {
1018 kDebug(5001) << "TransferFactory plugin (" << (*it
)->library()
1019 << ") found, but not enabled";
1023 KGetPlugin
* plugin
;
1024 if( (plugin
= createPluginFromService(*it
)) != 0 )
1026 QString pluginName
= info
.name();
1028 pluginList
.prepend(plugin
);
1029 kDebug(5001) << "TransferFactory plugin (" << (*it
)->library()
1030 << ") found and added to the list of available plugins";
1034 kDebug(5001) << "Error loading TransferFactory plugin ("
1035 << (*it
)->library() << ")";
1038 QList
<KGetPlugin
*>::iterator it2
= pluginList
.begin();
1039 QList
<KGetPlugin
*>::iterator it2End
= pluginList
.end();
1041 for( ; it2
!=it2End
; ++it2
)
1042 m_transferFactories
.append( qobject_cast
<TransferFactory
*>(*it2
) );
1044 kDebug(5001) << "Number of factories = " << m_transferFactories
.size();
1047 KGetPlugin
* KGet::createPluginFromService( const KService::Ptr
&service
)
1049 //try to load the specified library
1050 KPluginFactory
*factory
= KPluginLoader(service
->library()).factory();
1054 KMessageBox::error(0, i18n("<html><p>Plugin loader could not load the plugin:<br/><i>%1</i></p></html>",
1055 service
->library()));
1056 kError(5001) << "KPluginFactory could not load the plugin:" << service
->library();
1059 KGetPlugin
* plugin
= factory
->create
< TransferFactory
>(KGet::m_mainWindow
);
1064 bool KGet::safeDeleteFile( const KUrl
& url
)
1066 if ( url
.isLocalFile() )
1068 QFileInfo
info( url
.path() );
1071 KGet::showNotification(m_mainWindow
, KNotification::Notification
,
1072 i18n("Not deleting\n%1\nas it is a directory.", url
.prettyUrl()),
1076 KIO::NetAccess::del( url
, 0L );
1081 KGet::showNotification(m_mainWindow
, KNotification::Notification
,
1082 i18n("Not deleting\n%1\nas it is not a local file.", url
.prettyUrl()),
1087 void KGet::showNotification(QWidget
*parent
, KNotification::StandardEvent eventId
,
1088 const QString
&text
, const QString
&icon
)
1090 KNotification::event(eventId
, text
, KIcon(icon
).pixmap(KIconLoader::Small
), parent
);
1093 GenericModelObserver::GenericModelObserver(QObject
*parent
) : QObject(parent
)
1095 m_groupObserver
= new GenericTransferGroupObserver();
1098 GenericModelObserver::~GenericModelObserver()
1100 delete m_groupObserver
;
1103 void GenericModelObserver::addedTransferGroupEvent(TransferGroupHandler
* group
)
1106 kDebug() << "OBSERVER :: Adding group " << group
;
1107 group
->addObserver(m_groupObserver
);
1109 // we need to do this to add the genericTransfer to all the transfers under the group
1110 m_groupObserver
->addTransferGroup(group
);
1115 void GenericModelObserver::removedTransferGroupEvent(TransferGroupHandler
* group
)
1118 group
->delObserver(m_groupObserver
);