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
;
65 m_jobManager
= new KUiServerJobs(m_mainWindow
);
72 void KGet::addObserver(ModelObserver
* observer
)
76 m_observers
.append(observer
);
78 //Update the new observer with the TransferGroups objects of the model
79 QList
<TransferGroup
*>::const_iterator it
= m_transferTreeModel
->transferGroups().begin();
80 QList
<TransferGroup
*>::const_iterator itEnd
= m_transferTreeModel
->transferGroups().end();
82 for( ; it
!=itEnd
; ++it
)
84 postAddedTransferGroupEvent(*it
, observer
);
87 kDebug(5001) << " >>> EXITING";
90 void KGet::delObserver(ModelObserver
* observer
)
92 m_observers
.removeAll(observer
);
95 bool KGet::addGroup(const QString
& groupName
)
99 // Check if a group with that name already exists
100 if(m_transferTreeModel
->findGroup(groupName
))
103 TransferGroup
* group
= new TransferGroup(m_transferTreeModel
, m_scheduler
, groupName
);
104 m_transferTreeModel
->addGroup(group
);
107 postAddedTransferGroupEvent(group
);
112 void KGet::delGroup(const QString
& groupName
)
114 TransferGroup
* group
= m_transferTreeModel
->findGroup(groupName
);
118 m_transferTreeModel
->delGroup(group
);
119 postRemovedTransferGroupEvent(group
);
124 void KGet::renameGroup(const QString
& oldName
, const QString
& newName
)
126 TransferGroup
*group
= m_transferTreeModel
->findGroup(oldName
);
130 group
->handler()->setName(newName
);
134 QStringList
KGet::transferGroupNames()
138 foreach(TransferGroup
*group
, m_transferTreeModel
->transferGroups()) {
139 names
<< group
->name();
145 void KGet::addTransfer(KUrl srcUrl
, QString destDir
, // krazy:exclude=passbyvalue
146 const QString
& groupName
, bool start
)
148 kDebug(5001) << "Source:" << srcUrl
.url();
152 if ( srcUrl
.isEmpty() )
154 //No src location: we let the user insert it manually
155 srcUrl
= urlInputDialog();
156 if( srcUrl
.isEmpty() )
160 if ( !isValidSource( srcUrl
) )
163 if (destDir
.isEmpty())
165 if (Settings::useDefaultDirectory())
166 destDir
= KUrl(Settings::defaultDirectory()).path();
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::Iterator it
= srcUrls
.begin();
214 KUrl::List::Iterator 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 destDir
= KUrl(Settings::defaultDirectory()).path();
248 QString checkExceptions
= getSaveDirectoryFromExceptions(*it
);
249 if (Settings::enableExceptions() && !checkExceptions
.isEmpty())
250 destDir
= checkExceptions
;
252 destUrl
= getValidDestUrl(destDir
, *it
);
254 if(!isValidDestUrl(destUrl
))
257 createTransfer(*it
, destUrl
, groupName
, start
);
262 bool KGet::delTransfer(TransferHandler
* transfer
)
264 Transfer
* t
= transfer
->m_transfer
;
267 m_transferTreeModel
->delTransfer(t
);
269 //Here I delete the Transfer. The other possibility is to move it to a list
270 //and to delete all these transfers when kget gets closed. Obviously, after
271 //the notification to the views that the transfer has been removed, all the
272 //pointers to it are invalid.
273 transfer
->postDeleteEvent();
278 void KGet::moveTransfer(TransferHandler
* transfer
, const QString
& groupName
)
284 void KGet::redownloadTransfer(TransferHandler
* transfer
)
286 QString group
= transfer
->group()->name();
287 QString src
= transfer
->source().url();
288 QString dest
= transfer
->dest().url();
289 bool running
= false;
290 if (transfer
->status() == Job::Running
)
293 KGet::delTransfer(transfer
);
294 KGet::addTransfer(src
, dest
, group
, running
);
297 QList
<TransferHandler
*> KGet::selectedTransfers()
299 // kDebug(5001) << "KGet::selectedTransfers";
301 QList
<TransferHandler
*> selectedTransfers
;
303 QModelIndexList selectedIndexes
= m_selectionModel
->selectedRows();
305 foreach(const QModelIndex
¤tIndex
, selectedIndexes
)
307 if(!m_transferTreeModel
->isTransferGroup(currentIndex
))
308 selectedTransfers
.append(static_cast<TransferHandler
*> (currentIndex
.internalPointer()));
311 return selectedTransfers
;
314 // This is the code that was used in the old selectedTransfers function
315 /* QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
316 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
318 for( ; it!=itEnd ; ++it )
320 TransferGroup::iterator it2 = (*it)->begin();
321 TransferGroup::iterator it2End = (*it)->end();
323 for( ; it2!=it2End ; ++it2 )
325 Transfer * transfer = (Transfer*) *it2;
327 if( transfer->isSelected() )
328 selectedTransfers.append( transfer->handler() );
331 return selectedTransfers;*/
334 QList
<TransferHandler
*> KGet::finishedTransfers()
336 QList
<TransferHandler
*> finishedTransfers
;
338 foreach(TransferHandler
*transfer
, allTransfers())
340 if (transfer
->status() == Job::Finished
) {
341 finishedTransfers
<< transfer
;
344 return finishedTransfers
;
347 QList
<TransferGroupHandler
*> KGet::selectedTransferGroups()
349 QList
<TransferGroupHandler
*> selectedTransferGroups
;
351 QModelIndexList selectedIndexes
= m_selectionModel
->selectedRows();
353 foreach(const QModelIndex
¤tIndex
, selectedIndexes
)
355 if(m_transferTreeModel
->isTransferGroup(currentIndex
))
356 selectedTransferGroups
.append(static_cast<TransferGroupHandler
*> (currentIndex
.internalPointer()));
359 return selectedTransferGroups
;
362 TransferTreeSelectionModel
* KGet::selectionModel()
364 return m_selectionModel
;
367 void KGet::addTransferView(QAbstractItemView
* view
)
369 view
->setModel(m_transferTreeModel
);
372 void KGet::load( QString filename
) // krazy:exclude=passbyvalue
374 kDebug(5001) << "(" << filename
<< ")";
376 if(filename
.isEmpty())
377 filename
= KStandardDirs::locateLocal("appdata", "transfers.kgt");
381 //Try to save the transferlist to a temporary location
382 if(!KIO::NetAccess::download(KUrl(filename
), tmpFile
, 0))
388 kDebug(5001) << "file:" << filename
;
390 if(doc
.setContent(&file
))
392 QDomElement root
= doc
.documentElement();
394 QDomNodeList nodeList
= root
.elementsByTagName("TransferGroup");
395 int nItems
= nodeList
.length();
397 for( int i
= 0 ; i
< nItems
; i
++ )
399 TransferGroup
* foundGroup
= m_transferTreeModel
->findGroup( nodeList
.item(i
).toElement().attribute("Name") );
401 kDebug(5001) << "KGet::load -> group = " << nodeList
.item(i
).toElement().attribute("Name");
405 kDebug(5001) << "KGet::load -> group not found";
407 TransferGroup
* newGroup
= new TransferGroup(m_transferTreeModel
, m_scheduler
);
409 m_transferTreeModel
->addGroup(newGroup
);
411 newGroup
->load(nodeList
.item(i
).toElement());
414 postAddedTransferGroupEvent(newGroup
);
418 kDebug(5001) << "KGet::load -> group found";
420 //A group with this name already exists.
421 //Integrate the group's transfers with the ones read from file
422 foundGroup
->load(nodeList
.item(i
).toElement());
428 kWarning(5001) << "Error reading the transfers file";
431 addObserver(new GenericModelObserver());
434 void KGet::save( QString filename
, bool plain
) // krazy:exclude=passbyvalue
436 if ( !filename
.isEmpty()
437 && QFile::exists( filename
)
438 && (KMessageBox::questionYesNoCancel(0,
439 i18n("The file %1 already exists.\nOverwrite?", filename
),
440 i18n("Overwrite existing file?"), KStandardGuiItem::yes(),
441 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionFilenameExists" )
442 != KMessageBox::Yes
) )
445 if(filename
.isEmpty())
446 filename
= KStandardDirs::locateLocal("appdata", "transfers.kgt");
448 QFile
file(filename
);
449 if ( !file
.open( QIODevice::WriteOnly
) )
451 //kWarning(5001)<<"Unable to open output file when saving";
452 KMessageBox::error(0,
453 i18n("Unable to save to: %1", filename
),
460 QTextStream
out(&file
);
461 foreach(TransferHandler
*handler
, allTransfers()) {
462 out
<< handler
->source().prettyUrl() << endl
;
466 QDomDocument
doc(QString("KGetTransfers"));
467 QDomElement root
= doc
.createElement("Transfers");
468 doc
.appendChild(root
);
470 QList
<TransferGroup
*>::const_iterator it
= m_transferTreeModel
->transferGroups().begin();
471 QList
<TransferGroup
*>::const_iterator itEnd
= m_transferTreeModel
->transferGroups().end();
473 for ( ; it
!=itEnd
; ++it
)
475 QDomElement e
= doc
.createElement("TransferGroup");
480 QTextStream
stream( &file
);
481 doc
.save( stream
, 0 );
486 TransferFactory
* KGet::factory(TransferHandler
* transfer
)
488 return transfer
->m_transfer
->factory();
491 KActionCollection
* KGet::actionCollection()
493 return m_mainWindow
->actionCollection();
496 void KGet::setSchedulerRunning(bool running
)
500 m_scheduler
->stop(); //stopall first, to have a clean startingpoint
501 m_scheduler
->start();
507 bool KGet::schedulerRunning()
509 return (m_scheduler
->countRunningJobs() > 0);
512 QList
<TransferHandler
*> KGet::allTransfers()
514 QList
<TransferHandler
*> transfers
;
516 foreach (TransferGroup
*group
, KGet::m_transferTreeModel
->transferGroups())
518 transfers
<< group
->handler()->transfers();
523 QList
<TransferGroupHandler
*> KGet::allTransferGroups()
525 QList
<TransferGroupHandler
*> transfergroups
;
527 foreach (TransferGroup
*group
, KGet::m_transferTreeModel
->transferGroups())
529 transfergroups
<< group
->handler();
531 return transfergroups
;
534 TransferHandler
* KGet::findTransfer(const KUrl
&src
)
536 return KGet::m_transferTreeModel
->findTransfer(src
)->handler();
539 void KGet::checkSystemTray()
542 bool running
= false;
544 foreach (TransferHandler
*handler
, KGet::allTransfers())
546 if (handler
->status() == Job::Running
)
553 m_mainWindow
->setSystemTrayDownloading(running
);
556 void KGet::settingsChanged()
560 QList
<TransferFactory
*>::const_iterator it
= m_transferFactories
.constBegin();
561 QList
<TransferFactory
*>::const_iterator itEnd
= m_transferFactories
.constEnd();
563 for( ; it
!=itEnd
; ++it
)
565 (*it
)->settingsChanged();
569 void KGet::registerKJob(KJob
*job
)
571 m_jobManager
->registerJob(job
);
574 void KGet::unregisterKJob(KJob
*job
)
576 m_jobManager
->unregisterJob(job
);
579 void KGet::reloadKJobs()
581 m_jobManager
->reload();
584 QStringList
KGet::defaultFolders(const KUrl
&filename
, const QString
&groupname
)
586 kDebug(5001) << filename
<< groupname
;
589 const QString saveDirectoryFromExceptions
= KGet::getSaveDirectoryFromExceptions(filename
);
590 if (Settings::enableExceptions() && !saveDirectoryFromExceptions
.isEmpty())
591 list
.append(saveDirectoryFromExceptions
);
593 TransferGroup
* group
= KGet::m_transferTreeModel
->findGroup(groupname
);
595 if (!group
->defaultFolder().isEmpty())
596 list
.append(group
->defaultFolder());
598 if (Settings::useDefaultDirectory())
599 list
.append(Settings::defaultDirectory());
601 if (!Settings::lastDirectory().isEmpty() &&
602 QString::compare(Settings::lastDirectory(), Settings::defaultDirectory()) != 0)
603 list
.append(Settings::lastDirectory());
606 list
.append(QDir::homePath());//If we have no defaultDir, we return the home-dir
608 for (int i
= 0; i
< list
.size(); i
++)
610 list
[i
] = KUrl(list
[i
]).path();
615 void KGet::setGlobalDownloadLimit(int limit
)
617 m_scheduler
->setDownloadLimit(limit
);
619 m_scheduler
->calculateDownloadLimit();
622 void KGet::setGlobalUploadLimit(int limit
)
624 m_scheduler
->setUploadLimit(limit
);
626 m_scheduler
->calculateUploadLimit();
629 void KGet::calculateGlobalSpeedLimits()
631 if (m_scheduler
->downloadLimit())//TODO: Remove this and the both other hacks in the 2 upper functions with a better replacement
632 m_scheduler
->calculateDownloadLimit();
633 if (m_scheduler
->uploadLimit())
634 m_scheduler
->calculateUploadLimit();
637 void KGet::calculateGlobalDownloadLimit()
639 m_scheduler
->calculateDownloadLimit();
642 void KGet::calculateGlobalUploadLimit()
644 m_scheduler
->calculateUploadLimit();
647 // ------ STATIC MEMBERS INITIALIZATION ------
648 QList
<ModelObserver
*> KGet::m_observers
;
649 TransferTreeModel
* KGet::m_transferTreeModel
;
650 TransferTreeSelectionModel
* KGet::m_selectionModel
;
651 QList
<TransferFactory
*> KGet::m_transferFactories
;
652 TransferGroupScheduler
* KGet::m_scheduler
= new TransferGroupScheduler();
653 MainWindow
* KGet::m_mainWindow
= 0;
654 KUiServerJobs
* KGet::m_jobManager
= 0;
656 // ------ PRIVATE FUNCTIONS ------
659 m_transferTreeModel
= new TransferTreeModel(m_scheduler
);
660 m_selectionModel
= new TransferTreeSelectionModel(m_transferTreeModel
);
662 //Load all the available plugins
665 //Create the default group
666 addGroup(i18n("My Downloads"));
674 bool KGet::createTransfer(const KUrl
&src
, const KUrl
&dest
, const QString
& groupName
,
675 bool start
, const QDomElement
* e
)
677 kDebug(5001) << "srcUrl= " << src
.url() << " "
678 << "destUrl= " << dest
.url()
679 << "group= _" << groupName
<< "_" << endl
;
681 TransferGroup
* group
= m_transferTreeModel
->findGroup(groupName
);
684 kDebug(5001) << "KGet::createTransfer -> group not found";
685 group
= m_transferTreeModel
->transferGroups().first();
687 Transfer
* newTransfer
;
689 QList
<TransferFactory
*>::iterator it
= m_transferFactories
.begin();
690 QList
<TransferFactory
*>::iterator itEnd
= m_transferFactories
.end();
692 for( ; it
!=itEnd
; ++it
)
694 kDebug(5001) << "Trying plugin n.plugins=" << m_transferFactories
.size();
695 if((newTransfer
= (*it
)->createTransfer(src
, dest
, group
, m_scheduler
, e
)))
697 // kDebug(5001) << "KGet::createTransfer -> CREATING NEW TRANSFER ON GROUP: _" << group->name() << "_";
698 m_transferTreeModel
->addTransfer(newTransfer
, group
);
701 newTransfer
->handler()->start();
703 if (newTransfer->percent() != 100) //Don't add a finished observer if the Transfer has already been finished
704 newTransfer->handler()->addObserver(new GenericTransferObserver());
709 kDebug(5001) << "Warning! No plugin found to handle the given url";
713 TransferDataSource
* KGet::createTransferDataSource(const KUrl
&src
)
716 QList
<TransferFactory
*>::iterator it
= m_transferFactories
.begin();
717 QList
<TransferFactory
*>::iterator itEnd
= m_transferFactories
.end();
719 TransferDataSource
*dataSource
;
720 for( ; it
!=itEnd
; ++it
)
722 dataSource
= (*it
)->createTransferDataSource(src
);
729 void KGet::postAddedTransferGroupEvent(TransferGroup
* group
, ModelObserver
* observer
)
734 observer
->addedTransferGroupEvent(group
->handler());
738 QList
<ModelObserver
*>::iterator it
= m_observers
.begin();
739 QList
<ModelObserver
*>::iterator itEnd
= m_observers
.end();
741 for(; it
!=itEnd
; ++it
)
743 kDebug(5001) << "message posted";
745 (*it
)->addedTransferGroupEvent(group
->handler());
749 void KGet::postRemovedTransferGroupEvent(TransferGroup
* group
, ModelObserver
* observer
)
753 observer
->removedTransferGroupEvent(group
->handler());
757 QList
<ModelObserver
*>::iterator it
= m_observers
.begin();
758 QList
<ModelObserver
*>::iterator itEnd
= m_observers
.end();
760 for(; it
!=itEnd
; ++it
)
762 (*it
)->removedTransferGroupEvent(group
->handler());
766 KUrl
KGet::urlInputDialog()
771 KUrl clipboardUrl
= KUrl(QApplication::clipboard()->text(QClipboard::Clipboard
).trimmed());
772 if (clipboardUrl
.isValid())
773 newtransfer
= clipboardUrl
.url();
777 newtransfer
= KInputDialog::getText(i18n("New Download"), i18n("Enter URL:"), newtransfer
, &ok
, 0);
781 //user pressed cancel
785 KUrl src
= KUrl(newtransfer
);
794 QString
KGet::destInputDialog()
796 QString destDir
= KFileDialog::getExistingDirectory(Settings::lastDirectory());
798 Settings::setLastDirectory( destDir
);
802 QString
KGet::getSaveDirectoryFromExceptions(const KUrl
&filename
)
806 const QStringList list
= Settings::extensionsFolderList();
807 QStringList::ConstIterator it
= list
.begin();
808 const QStringList::ConstIterator end
= list
.end();
810 // odd list items are regular expressions for extensions
816 if (!ext
.startsWith('*'))
820 rexp
.setPatternSyntax(QRegExp::Wildcard
);
822 if (rexp
.exactMatch(filename
.url())) {
828 return KUrl(destDir
).path();
831 bool KGet::isValidSource(const KUrl
&source
)
833 // Check if the URL is well formed
834 if (!source
.isValid())
836 KMessageBox::error(0,
837 i18n("Malformed URL:\n%1", source
.prettyUrl()),
842 // Check if the URL contains the protocol
843 if ( source
.protocol().isEmpty() ){
845 KMessageBox::error(0, i18n("Malformed URL, protocol missing:\n%1", source
.prettyUrl()),
850 // Check if a transfer with the same url already exists
851 Transfer
* transfer
= m_transferTreeModel
->findTransfer( source
);
854 if ( transfer
->status() == Job::Finished
)
856 // transfer is finished, ask if we want to download again
857 if (KMessageBox::questionYesNoCancel(0,
858 i18n("URL already saved:\n%1\nDownload again?", source
.prettyUrl()),
859 i18n("Download URL again?"), KStandardGuiItem::yes(),
860 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionUrlAlreadySaved" )
864 TransferHandler
* th
= transfer
->handler();
865 KGet::delTransfer(th
);
871 //Transfer is already in list and not finished, ...
879 bool KGet::isValidDestDirectory(const QString
& destDir
)
881 kDebug(5001) << destDir
;
882 if (!QFileInfo(destDir
).isDir())
884 if (QFileInfo(KUrl(destDir
).directory()).isWritable())
885 return (!destDir
.isEmpty());
886 if (!QFileInfo(KUrl(destDir
).directory()).isWritable() && !destDir
.isEmpty())
887 KMessageBox::error(0, i18n("Directory is not writable"));
891 if (QFileInfo(destDir
).isWritable())
892 return (!destDir
.isEmpty());
893 if (!QFileInfo(destDir
).isWritable() && !destDir
.isEmpty())
894 KMessageBox::error(0, i18n("Directory is not writable"));
899 bool KGet::isValidDestUrl(const KUrl
&destUrl
)
901 if(KIO::NetAccess::exists(destUrl
, KIO::NetAccess::DestinationSide
, 0))
903 if (KMessageBox::warningYesNoCancel(0,
904 i18n("Destination file \n%1\nalready exists.\n"
905 "Do you want to overwrite it?", destUrl
.prettyUrl()))
908 safeDeleteFile( destUrl
);
914 if (m_transferTreeModel
->findTransferByDestination(destUrl
) || destUrl
.isEmpty())
919 KIO::open_RenameDlg(i18n("File already exists"),
920 (*it).url(), destUrl.url(),
925 KUrl
KGet::getValidDestUrl(const QString
& destDir
, const KUrl
&srcUrl
)
927 if ( !isValidDestDirectory(destDir
) )
930 // create a proper destination file from destDir
931 KUrl destUrl
= KUrl( destDir
);
932 QString filename
= srcUrl
.fileName();
934 if ( filename
.isEmpty() )
936 // simply use the full url as filename
937 filename
= KUrl::toPercentEncoding( srcUrl
.prettyUrl(), "/" );
938 kDebug(5001) << " Filename is empty. Setting to " << filename
;
939 kDebug(5001) << " srcUrl = " << srcUrl
.url();
940 kDebug(5001) << " prettyUrl = " << srcUrl
.prettyUrl();
942 if (QFileInfo(destUrl
.path()).isDir())
944 kDebug(5001) << " Filename is not empty";
945 destUrl
.adjustPath( KUrl::AddTrailingSlash
);
946 destUrl
.setFileName( filename
);
948 if (!isValidDestUrl(destUrl
))
950 kDebug(5001) << " destUrl " << destUrl
.path() << " is not valid";
956 void KGet::loadPlugins()
958 m_transferFactories
.clear();
959 // Add versioning constraint
961 str
= "[X-KDE-KGet-framework-version] == ";
962 str
+= QString::number( FrameworkVersion
);
964 str
+= "[X-KDE-KGet-rank] > 0";
966 str
+= "[X-KDE-KGet-plugintype] == ";
968 KService::List offers
;
970 //TransferFactory plugins
971 offers
= KServiceTypeTrader::self()->query( "KGet/Plugin", str
+ "'TransferFactory'" );
973 //Here we use a QMap only to easily sort the plugins by rank
974 QMap
<int, KService::Ptr
> services
;
975 QMap
<int, KService::Ptr
>::iterator it
;
977 for ( int i
= 0; i
< offers
.count(); ++i
)
979 services
[ offers
[i
]->property( "X-KDE-KGet-rank" ).toInt() ] = offers
[i
];
980 kDebug(5001) << " TransferFactory plugin found:" << endl
<<
981 " rank = " << offers
[i
]->property( "X-KDE-KGet-rank" ).toInt() << endl
<<
982 " plugintype = " << offers
[i
]->property( "X-KDE-KGet-plugintype" ) << endl
;
985 //I must fill this pluginList before and my m_transferFactories list after.
986 //This because calling the KLibLoader::globalLibrary() erases the static
987 //members of this class (why?), such as the m_transferFactories list.
988 QList
<KGetPlugin
*> pluginList
;
990 KConfigGroup plugins
= KConfigGroup(KGlobal::config(), "Plugins");
992 for( it
= services
.begin(); it
!= services
.end(); ++it
)
994 KPluginInfo
info(*it
);
997 if( !info
.isPluginEnabled() ) {
998 kDebug(5001) << "TransferFactory plugin (" << (*it
)->library()
999 << ") found, but not enabled";
1003 KGetPlugin
* plugin
;
1004 if( (plugin
= createPluginFromService(*it
)) != 0 )
1006 QString pluginName
= info
.name();
1008 pluginList
.prepend(plugin
);
1009 kDebug(5001) << "TransferFactory plugin (" << (*it
)->library()
1010 << ") found and added to the list of available plugins";
1014 kDebug(5001) << "Error loading TransferFactory plugin ("
1015 << (*it
)->library() << ")";
1018 QList
<KGetPlugin
*>::iterator it2
= pluginList
.begin();
1019 QList
<KGetPlugin
*>::iterator it2End
= pluginList
.end();
1021 for( ; it2
!=it2End
; ++it2
)
1022 m_transferFactories
.append( qobject_cast
<TransferFactory
*>(*it2
) );
1024 kDebug(5001) << "Number of factories = " << m_transferFactories
.size();
1027 KGetPlugin
* KGet::createPluginFromService( const KService::Ptr
&service
)
1029 //try to load the specified library
1030 KPluginFactory
*factory
= KPluginLoader(service
->library()).factory();
1034 KMessageBox::error(0, i18n("<html><p>Plugin loader could not load the plugin:<br/><i>%1</i></p></html>",
1035 service
->library()));
1036 kError(5001) << "KPluginFactory could not load the plugin:" << service
->library();
1039 KGetPlugin
* plugin
= factory
->create
< TransferFactory
>(KGet::m_mainWindow
);
1044 bool KGet::safeDeleteFile( const KUrl
& url
)
1046 if ( url
.isLocalFile() )
1048 QFileInfo
info( url
.path() );
1051 KGet::showNotification(m_mainWindow
, KNotification::Notification
,
1052 i18n("Not deleting\n%1\nas it is a directory.", url
.prettyUrl()),
1056 KIO::NetAccess::del( url
, 0L );
1061 KGet::showNotification(m_mainWindow
, KNotification::Notification
,
1062 i18n("Not deleting\n%1\nas it is not a local file.", url
.prettyUrl()),
1067 void KGet::showNotification(QWidget
*parent
, KNotification::StandardEvent eventId
,
1068 const QString
&text
, const QString
&icon
)
1070 KNotification::event(eventId
, text
, KIcon(icon
).pixmap(KIconLoader::Small
), parent
);
1073 GenericModelObserver::GenericModelObserver(QObject
*parent
) : QObject(parent
)
1075 m_groupObserver
= new GenericTransferGroupObserver();
1078 GenericModelObserver::~GenericModelObserver()
1080 delete m_groupObserver
;
1083 void GenericModelObserver::addedTransferGroupEvent(TransferGroupHandler
* group
)
1086 kDebug() << "OBSERVER :: Adding group " << group
;
1087 group
->addObserver(m_groupObserver
);
1089 // we need to do this to add the genericTransfer to all the transfers under the group
1090 m_groupObserver
->addTransferGroup(group
);
1095 void GenericModelObserver::removedTransferGroupEvent(TransferGroupHandler
* group
)
1098 group
->delObserver(m_groupObserver
);