*Move TransferFinishedObserver to TransferHandler.cpp
[kdenetwork.git] / kget / core / kget.cpp
blob0c03e670b5513507a48ae2d6515d9f5a882895ee
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"
26 #include "settings.h"
28 #include <kio/netaccess.h>
29 #include <kinputdialog.h>
30 #include <kfiledialog.h>
31 #include <kmessagebox.h>
32 #include <klocale.h>
33 #include <kstandarddirs.h>
34 #include <kservicetypetrader.h>
35 #include <kiconloader.h>
36 #include <kactioncollection.h>
37 #include <kio/renamedialog.h>
38 #include <KSystemTrayIcon>
40 #include <QTextStream>
41 #include <QDomElement>
42 #include <QApplication>
43 #include <QClipboard>
44 #include <QAbstractItemView>
46 /**
47 * This is our KGet class. This is where the user's transfers and searches are
48 * stored and organized.
49 * Use this class from the views to add or remove transfers or searches
50 * In order to organize the transfers inside categories we have a TransferGroup
51 * class. By definition, a transfer must always belong to a TransferGroup. If we
52 * don't want it to be displayed by the gui inside a specific group, we will put
53 * it in the group named "Not grouped" (better name?).
54 **/
56 KGet& KGet::self( MainWindow * mainWindow )
58 if(mainWindow)
60 m_mainWindow = mainWindow;
63 static KGet m;
64 return m;
67 void KGet::addObserver(ModelObserver * observer)
69 kDebug(5001);
71 m_observers.append(observer);
73 //Update the new observer with the TransferGroups objects of the model
74 QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
75 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
77 for( ; it!=itEnd ; ++it )
79 postAddedTransferGroupEvent(*it, observer);
82 kDebug(5001) << " >>> EXITING";
85 void KGet::delObserver(ModelObserver * observer)
87 m_observers.removeAll(observer);
90 bool KGet::addGroup(const QString& groupName)
92 kDebug(5001);
94 // Check if a group with that name already exists
95 if(m_transferTreeModel->findGroup(groupName))
96 return false;
98 TransferGroup * group = new TransferGroup(m_transferTreeModel, m_scheduler, groupName);
99 m_transferTreeModel->addGroup(group);
101 //post notifications
102 postAddedTransferGroupEvent(group);
104 return true;
107 void KGet::delGroup(const QString& groupName)
109 TransferGroup * group = m_transferTreeModel->findGroup(groupName);
111 if(group)
113 m_transferTreeModel->delGroup(group);
114 postRemovedTransferGroupEvent(group);
115 delete(group);
119 void KGet::renameGroup(const QString& oldName, const QString& newName)
121 TransferGroup *group = m_transferTreeModel->findGroup(oldName);
123 if(group)
125 group->handler()->setName(newName);
129 QStringList KGet::transferGroupNames()
131 QStringList names;
133 foreach(TransferGroup *group, m_transferTreeModel->transferGroups()) {
134 names << group->name();
137 return names;
140 void KGet::addTransfer(KUrl srcUrl, QString destDir, // krazy:exclude=passbyvalue
141 const QString& groupName, bool start)
143 kDebug(5001) << "Source:" << srcUrl.url();
145 KUrl destUrl;
147 if ( srcUrl.isEmpty() )
149 //No src location: we let the user insert it manually
150 srcUrl = urlInputDialog();
151 if( srcUrl.isEmpty() )
152 return;
155 if ( !isValidSource( srcUrl ) )
156 return;
158 if (destDir.isEmpty())
160 if (Settings::useDefaultDirectory())
161 #ifdef Q_OS_WIN //krazy:exclude=cpp
162 destDir = Settings::defaultDirectory().remove("file:///");
163 #else
164 destDir = Settings::defaultDirectory().remove("file://");
165 #endif
167 QString checkExceptions = getSaveDirectoryFromExceptions(srcUrl);
168 if (Settings::enableExceptions() && !checkExceptions.isEmpty())
169 destDir = checkExceptions;
172 if (!isValidDestDirectory(destDir))
173 destDir = destInputDialog();
175 if( (destUrl = getValidDestUrl( destDir, srcUrl )).isEmpty() )
176 return;
178 if(m_transferTreeModel->findTransferByDestination(destUrl) != 0 || (destUrl.isLocalFile() && QFile::exists(destUrl.path()))) {
179 KIO::RenameDialog dlg( m_mainWindow, i18n("Rename transfer"), srcUrl,
180 destUrl, KIO::M_MULTI);
181 if (dlg.exec() == KIO::R_RENAME)
182 destUrl = dlg.newDestUrl();
183 else
184 return;
186 createTransfer(srcUrl, destUrl, groupName, start);
189 void KGet::addTransfer(const QDomElement& e, const QString& groupName)
191 //We need to read these attributes now in order to know which transfer
192 //plugin to use.
193 KUrl srcUrl = KUrl( e.attribute("Source") );
194 KUrl destUrl = KUrl( e.attribute("Dest") );
196 kDebug(5001) << " src= " << srcUrl.url()
197 << " dest= " << destUrl.url()
198 << " group= "<< groupName << endl;
200 if ( srcUrl.isEmpty() || !isValidSource(srcUrl)
201 || !isValidDestDirectory(destUrl.directory()) )
202 return;
204 createTransfer(srcUrl, destUrl, groupName, false, &e);
207 void KGet::addTransfer(KUrl::List srcUrls, QString destDir, // krazy:exclude=passbyvalue
208 const QString& groupName, bool start)
210 KUrl::List urlsToDownload;
212 KUrl::List::ConstIterator it = srcUrls.begin();
213 KUrl::List::ConstIterator itEnd = srcUrls.end();
215 for(; it!=itEnd ; ++it)
217 if ( isValidSource( *it ) )
218 urlsToDownload.append( *it );
221 if ( urlsToDownload.count() == 0 )
222 return;
224 if ( urlsToDownload.count() == 1 )
226 // just one file -> ask for filename
227 addTransfer(srcUrls.first(), destDir + srcUrls.first().fileName(), groupName, start);
228 return;
231 KUrl destUrl;
233 // multiple files -> ask for directory, not for every single filename
234 if (!isValidDestDirectory(destDir) && !Settings::useDefaultDirectory())
235 destDir = destInputDialog();
237 it = urlsToDownload.begin();
238 itEnd = urlsToDownload.end();
240 for ( ; it != itEnd; ++it )
242 if (destDir.isEmpty())
244 if (Settings::useDefaultDirectory())
245 #ifdef Q_OS_WIN //krazy:exclude=cpp
246 destDir = Settings::defaultDirectory().remove("file:///");
247 #else
248 destDir = Settings::defaultDirectory().remove("file://");
249 #endif
251 QString checkExceptions = getSaveDirectoryFromExceptions(*it);
252 if (Settings::enableExceptions() && !checkExceptions.isEmpty())
253 destDir = checkExceptions;
255 destUrl = getValidDestUrl(destDir, *it);
257 if(!isValidDestUrl(destUrl))
258 continue;
260 createTransfer(*it, destUrl, groupName, start);
265 bool KGet::delTransfer(TransferHandler * transfer)
267 Transfer * t = transfer->m_transfer;
268 t->stop();
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.
279 // delete( t );
280 return true;
283 void KGet::moveTransfer(TransferHandler * transfer, const QString& groupName)
285 Q_UNUSED(transfer);
286 Q_UNUSED(groupName);
289 void KGet::redownloadTransfer(TransferHandler * transfer)
291 QString group = transfer->group()->name();
292 QString src = transfer->source().url();
293 QString dest = transfer->dest().url();
294 bool running = false;
295 if (transfer->status() == Job::Running)
296 running = true;
298 KGet::delTransfer(transfer);
299 KGet::addTransfer(src, dest, group, running);
302 QList<TransferHandler *> KGet::selectedTransfers()
304 // kDebug(5001) << "KGet::selectedTransfers";
306 QList<TransferHandler *> selectedTransfers;
308 QModelIndexList selectedIndexes = m_selectionModel->selectedRows();
310 foreach(QModelIndex currentIndex, selectedIndexes)
312 if(!m_transferTreeModel->isTransferGroup(currentIndex))
313 selectedTransfers.append(static_cast<TransferHandler *> (currentIndex.internalPointer()));
316 return selectedTransfers;
319 // This is the code that was used in the old selectedTransfers function
320 /* QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
321 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
323 for( ; it!=itEnd ; ++it )
325 TransferGroup::iterator it2 = (*it)->begin();
326 TransferGroup::iterator it2End = (*it)->end();
328 for( ; it2!=it2End ; ++it2 )
330 Transfer * transfer = (Transfer*) *it2;
332 if( transfer->isSelected() )
333 selectedTransfers.append( transfer->handler() );
336 return selectedTransfers;*/
339 QList<TransferGroupHandler *> KGet::selectedTransferGroups()
341 QList<TransferGroupHandler *> selectedTransferGroups;
343 QModelIndexList selectedIndexes = m_selectionModel->selectedRows();
345 foreach(QModelIndex currentIndex, selectedIndexes)
347 if(m_transferTreeModel->isTransferGroup(currentIndex))
348 selectedTransferGroups.append(static_cast<TransferGroupHandler *> (currentIndex.internalPointer()));
351 return selectedTransferGroups;
354 TransferTreeSelectionModel * KGet::selectionModel()
356 return m_selectionModel;
359 void KGet::addTransferView(QAbstractItemView * view)
361 view->setModel(m_transferTreeModel);
364 void KGet::load( QString filename ) // krazy:exclude=passbyvalue
366 kDebug(5001) << "(" << filename << ")";
368 if(filename.isEmpty())
369 filename = KStandardDirs::locateLocal("appdata", "transfers.kgt");
371 QString tmpFile;
373 //Try to save the transferlist to a temporary location
374 if(!KIO::NetAccess::download(KUrl(filename), tmpFile, 0))
375 return;
377 QFile file(tmpFile);
378 QDomDocument doc;
380 kDebug(5001) << "file:" << filename;
382 if(doc.setContent(&file))
384 QDomElement root = doc.documentElement();
386 QDomNodeList nodeList = root.elementsByTagName("TransferGroup");
387 int nItems = nodeList.length();
389 for( int i = 0 ; i < nItems ; i++ )
391 TransferGroup * foundGroup = m_transferTreeModel->findGroup( nodeList.item(i).toElement().attribute("Name") );
393 kDebug(5001) << "KGet::load -> group = " << nodeList.item(i).toElement().attribute("Name");
395 if( !foundGroup )
397 kDebug(5001) << "KGet::load -> group not found";
399 TransferGroup * newGroup = new TransferGroup(m_transferTreeModel, m_scheduler);
401 m_transferTreeModel->addGroup(newGroup);
403 newGroup->load(nodeList.item(i).toElement());
405 //Post notifications
406 postAddedTransferGroupEvent(newGroup);
408 else
410 kDebug(5001) << "KGet::load -> group found";
412 //A group with this name already exists.
413 //Integrate the group's transfers with the ones read from file
414 foundGroup->load(nodeList.item(i).toElement());
418 else
420 kWarning(5001) << "Error reading the transfers file";
424 void KGet::save( QString filename ) // krazy:exclude=passbyvalue
426 if ( !filename.isEmpty()
427 && QFile::exists( filename )
428 && (KMessageBox::questionYesNoCancel(0,
429 i18n("The file %1 already exists.\nOverwrite?", filename),
430 i18n("Overwrite existing file?"), KStandardGuiItem::yes(),
431 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionFilenameExists" )
432 != KMessageBox::Yes) )
433 return;
435 if(filename.isEmpty())
436 filename = KStandardDirs::locateLocal("appdata", "transfers.kgt");
438 QDomDocument doc(QString("KGetTransfers"));
439 QDomElement root = doc.createElement("Transfers");
440 doc.appendChild(root);
442 QList<TransferGroup *>::const_iterator it = m_transferTreeModel->transferGroups().begin();
443 QList<TransferGroup *>::const_iterator itEnd = m_transferTreeModel->transferGroups().end();
445 for ( ; it!=itEnd ; ++it )
447 QDomElement e = doc.createElement("TransferGroup");
448 root.appendChild(e);
449 (*it)->save(e);
451 QFile file(filename);
452 if ( !file.open( QIODevice::WriteOnly ) )
454 //kWarning(5001)<<"Unable to open output file when saving";
455 KMessageBox::error(0,
456 i18n("Unable to save to: %1", filename),
457 i18n("Error"));
458 return;
461 QTextStream stream( &file );
462 doc.save( stream, 0 );
463 file.close();
466 TransferFactory * KGet::factory(TransferHandler * transfer)
468 return transfer->m_transfer->factory();
471 KActionCollection * KGet::actionCollection()
473 return m_mainWindow->actionCollection();
476 void KGet::setSchedulerRunning(bool running)
478 if(running)
480 m_scheduler->stop(); //stopall first, to have a clean startingpoint
481 m_scheduler->start();
483 else
484 m_scheduler->stop();
487 bool KGet::schedulerRunning()
489 return (m_scheduler->countRunningJobs() > 0);
492 void KGet::setPluginsSettingsWidget(KTabWidget * widget)
494 kDebug(5001);
495 QList<TransferFactory *>::iterator it = m_transferFactories.begin();
496 QList<TransferFactory *>::iterator itEnd = m_transferFactories.end();
498 QWidget * settingsWidget;
499 for( ; it!=itEnd ; ++it)
501 KDialog *dialog = static_cast<KDialog*>(widget->parent()->parent());
502 if (!dialog)
503 return;
505 settingsWidget = (*it)->createSettingsWidget(dialog);
506 if(settingsWidget)
507 widget->addTab( settingsWidget, (*it)->displayName() );
511 QList<TransferHandler*> KGet::allTransfers()
513 QList<TransferHandler*> transfers;
515 foreach (TransferGroup *group, KGet::m_transferTreeModel->transferGroups())
517 transfers << group->handler()->transfers();
520 return transfers;
523 void KGet::checkSystemTray()
525 kDebug(5001);
526 bool running = false;
528 foreach (TransferHandler *handler, KGet::allTransfers())
530 if (handler->status() == Job::Running)
531 running = true;
533 if (running)
534 continue;
537 m_mainWindow->setSystemTrayDownloading(running);
540 void KGet::settingsChanged()
542 kDebug(5001);
544 QList<TransferFactory*>::const_iterator it = m_transferFactories.begin();
545 QList<TransferFactory*>::const_iterator itEnd = m_transferFactories.end();
547 for( ; it!=itEnd ; ++it )
549 (*it)->settingsChanged();
553 void KGet::registerKJob(KJob *job)
555 m_jobManager->registerJob(job);
558 void KGet::unregisterKJob(KJob *job)
560 m_jobManager->unregisterJob(job);
563 void KGet::reloadKJobs()
565 m_jobManager->reload();
568 QStringList KGet::defaultFolders(const KUrl &filename, const QString &groupname)
570 kDebug(5001) << filename << groupname;
572 QStringList list;
573 if (Settings::enableExceptions() && !KGet::getSaveDirectoryFromExceptions(filename).isEmpty())
574 list.append(KGet::getSaveDirectoryFromExceptions(filename));
576 TransferGroup * group = KGet::m_transferTreeModel->findGroup(groupname);
578 if (!group->defaultFolder().isEmpty())
579 list.append(group->defaultFolder());
581 if (Settings::useDefaultDirectory())
582 list.append(Settings::defaultDirectory());
584 if (!Settings::lastDirectory().isEmpty() &&
585 QString::compare(Settings::lastDirectory(), Settings::defaultDirectory()) != 0)
586 list.append(Settings::lastDirectory());
588 foreach(QString string, list)
590 #ifdef Q_OS_WIN //krazy:exclude=cpp
591 string.remove("file:///");
592 #else
593 string.remove("file://");
594 #endif
597 return list;
600 // ------ STATIC MEMBERS INITIALIZATION ------
601 QList<ModelObserver *> KGet::m_observers;
602 TransferTreeModel * KGet::m_transferTreeModel;
603 TransferTreeSelectionModel * KGet::m_selectionModel;
604 QList<TransferFactory *> KGet::m_transferFactories;
605 Scheduler * KGet::m_scheduler = new Scheduler();
606 MainWindow * KGet::m_mainWindow = 0;
607 KUiServerJobs * KGet::m_jobManager = new KUiServerJobs();
609 // ------ PRIVATE FUNCTIONS ------
610 KGet::KGet()
612 m_transferTreeModel = new TransferTreeModel(m_scheduler);
613 m_selectionModel = new TransferTreeSelectionModel(m_transferTreeModel);
615 //Load all the available plugins
616 loadPlugins();
618 //Create the default group
619 addGroup(i18n("My Downloads"));
622 KGet::~KGet()
624 delete m_scheduler;
627 bool KGet::createTransfer(const KUrl &src, const KUrl &dest, const QString& groupName,
628 bool start, const QDomElement * e)
630 kDebug(5001) << "srcUrl= " << src.url() << " "
631 << "destUrl= " << dest.url()
632 << "group= _" << groupName << "_" << endl;
634 TransferGroup * group = m_transferTreeModel->findGroup(groupName);
635 if (group==0)
637 kDebug(5001) << "KGet::createTransfer -> group not found";
638 group = m_transferTreeModel->transferGroups().first();
640 Transfer * newTransfer;
642 QList<TransferFactory *>::iterator it = m_transferFactories.begin();
643 QList<TransferFactory *>::iterator itEnd = m_transferFactories.end();
645 for( ; it!=itEnd ; ++it)
647 kDebug(5001) << "Trying plugin n.plugins=" << m_transferFactories.size();
648 if((newTransfer = (*it)->createTransfer(src, dest, group, m_scheduler, e)))
650 // kDebug(5001) << "KGet::createTransfer -> CREATING NEW TRANSFER ON GROUP: _" << group->name() << "_";
651 m_transferTreeModel->addTransfer(newTransfer, group);
653 if(start)
654 newTransfer->handler()->start();
656 if (newTransfer->percent() != 100) //Don't add a finished observer if the Transfer has already been finished
657 newTransfer->handler()->addObserver(new GenericTransferObserver());
659 return true;
662 kDebug(5001) << "Warning! No plugin found to handle the given url";
663 return false;
666 TransferDataSource * KGet::createTransferDataSource(const KUrl &src)
668 kDebug(5001);
669 QList<TransferFactory *>::iterator it = m_transferFactories.begin();
670 QList<TransferFactory *>::iterator itEnd = m_transferFactories.end();
672 TransferDataSource *dataSource;
673 for( ; it!=itEnd ; ++it)
675 dataSource = (*it)->createTransferDataSource(src);
676 if(dataSource)
677 return dataSource;
679 return 0;
682 void KGet::postAddedTransferGroupEvent(TransferGroup * group, ModelObserver * observer)
684 kDebug(5001);
685 if(observer)
687 observer->addedTransferGroupEvent(group->handler());
688 return;
691 QList<ModelObserver *>::iterator it = m_observers.begin();
692 QList<ModelObserver *>::iterator itEnd = m_observers.end();
694 for(; it!=itEnd; ++it)
696 kDebug(5001) << "message posted";
698 (*it)->addedTransferGroupEvent(group->handler());
702 void KGet::postRemovedTransferGroupEvent(TransferGroup * group, ModelObserver * observer)
704 if(observer)
706 observer->removedTransferGroupEvent(group->handler());
707 return;
710 QList<ModelObserver *>::iterator it = m_observers.begin();
711 QList<ModelObserver *>::iterator itEnd = m_observers.end();
713 for(; it!=itEnd; ++it)
715 (*it)->removedTransferGroupEvent(group->handler());
719 KUrl KGet::urlInputDialog()
721 QString newtransfer;
722 bool ok = false;
724 KUrl clipboardUrl = KUrl(QApplication::clipboard()->text(QClipboard::Clipboard).trimmed());
725 if (clipboardUrl.isValid())
726 newtransfer = clipboardUrl.url();
728 while (!ok)
730 newtransfer = KInputDialog::getText(i18n("New Download"), i18n("Enter URL:"), newtransfer, &ok, 0);
732 if (!ok)
734 //user pressed cancel
735 return KUrl();
738 KUrl src = KUrl(newtransfer);
739 if(src.isValid())
740 return src;
741 else
742 ok = false;
744 return KUrl();
747 QString KGet::destInputDialog()
749 QString destDir = KFileDialog::getExistingDirectory(Settings::lastDirectory());
751 Settings::setLastDirectory( destDir );
752 return destDir;
755 QString KGet::getSaveDirectoryFromExceptions(const KUrl &filename)
757 QString destDir;
759 QStringList list = Settings::extensionsFolderList();
760 QStringList::Iterator it = list.begin();
761 QStringList::Iterator end = list.end();
762 while (it != end) {
763 // odd list items are regular expressions for extensions
764 QString ext = *it;
765 ++it;
766 QString path = *it;
767 ++it;
769 if (!ext.startsWith('*'))
770 ext = '*' + ext;
772 QRegExp rexp(ext);
773 rexp.setPatternSyntax(QRegExp::Wildcard);
775 if (rexp.exactMatch(filename.url())) {
776 destDir = path;
777 break;
781 #ifdef Q_OS_WIN //krazy:exclude=cpp
782 destDir = destDir.remove("file:///");
783 #endif
784 return destDir.remove("file://");
787 bool KGet::isValidSource(const KUrl &source)
789 if (!source.isValid())
791 KMessageBox::error(0,
792 i18n("Malformed URL:\n%1", source.prettyUrl()),
793 i18n("Error"));
794 return false;
796 // Check if a transfer with the same url already exists
797 Transfer * transfer = m_transferTreeModel->findTransfer( source );
798 if ( transfer )
800 if ( transfer->status() == Job::Finished )
802 // transfer is finished, ask if we want to download again
803 if (KMessageBox::questionYesNoCancel(0,
804 i18n("URL already saved:\n%1\nDownload again?", source.prettyUrl()),
805 i18n("Download URL again?"), KStandardGuiItem::yes(),
806 KStandardGuiItem::no(), KStandardGuiItem::cancel(), "QuestionUrlAlreadySaved" )
807 == KMessageBox::Yes)
809 //TODO reimplement this
810 //transfer->slotRemove();
811 //checkQueue();
812 return true;
815 else
817 //Transfer is already in list and not finished, ...
818 return false;
820 return false;
822 return true;
825 bool KGet::isValidDestDirectory(const QString & destDir)
827 kDebug(5001) << destDir;
828 if (!QFileInfo(destDir).isDir())
830 if (QFileInfo(KUrl(destDir).directory()).isWritable())
831 return (!destDir.isEmpty());
832 if (!QFileInfo(KUrl(destDir).directory()).isWritable() && !destDir.isEmpty())
833 KMessageBox::error(0, i18n("Directory is not writable"));
835 else
837 if (QFileInfo(destDir).isWritable())
838 return (!destDir.isEmpty());
839 if (!QFileInfo(destDir).isWritable() && !destDir.isEmpty())
840 KMessageBox::error(0, i18n("Directory is not writable"));
842 return false;
845 bool KGet::isValidDestUrl(const KUrl &destUrl)
847 if(KIO::NetAccess::exists(destUrl, KIO::NetAccess::DestinationSide, 0))
849 if (KMessageBox::warningYesNoCancel(0,
850 i18n("Destination file \n%1\nalready exists.\n"
851 "Do you want to overwrite it?", destUrl.prettyUrl()))
852 == KMessageBox::Yes)
854 safeDeleteFile( destUrl );
855 return true;
857 else
858 return false;
860 if (m_transferTreeModel->findTransferByDestination(destUrl) || destUrl.isEmpty())
861 return false;
863 return true;
865 KIO::open_RenameDlg(i18n("File already exists"),
866 (*it).url(), destUrl.url(),
867 KIO::M_MULTI);
871 KUrl KGet::getValidDestUrl(const QString& destDir, const KUrl &srcUrl)
873 if ( !isValidDestDirectory(destDir) )
874 return KUrl();
876 // create a proper destination file from destDir
877 KUrl destUrl = KUrl( destDir );
878 QString filename = srcUrl.fileName();
880 if ( filename.isEmpty() )
882 // simply use the full url as filename
883 filename = KUrl::toPercentEncoding( srcUrl.prettyUrl(), "/" );
884 kDebug(5001) << " Filename is empty. Setting to " << filename;
885 kDebug(5001) << " srcUrl = " << srcUrl.url();
886 kDebug(5001) << " prettyUrl = " << srcUrl.prettyUrl();
888 if (QFileInfo(destUrl.path()).isDir())
890 kDebug(5001) << " Filename is not empty";
891 destUrl.adjustPath( KUrl::AddTrailingSlash );
892 destUrl.setFileName( filename );
894 if (!isValidDestUrl(destUrl))
896 kDebug(5001) << " destUrl " << destUrl.path() << " is not valid";
897 return KUrl();
899 return destUrl;
902 void KGet::loadPlugins()
904 // Add versioning constraint
905 QString
906 str = "[X-KDE-KGet-framework-version] == ";
907 str += QString::number( FrameworkVersion );
908 str += " and ";
909 str += "[X-KDE-KGet-rank] > 0";
910 str += " and ";
911 str += "[X-KDE-KGet-plugintype] == ";
913 KService::List offers;
915 //TransferFactory plugins
916 offers = KServiceTypeTrader::self()->query( "KGet/Plugin", str + "'TransferFactory'" );
918 //Here we use a QMap only to easily sort the plugins by rank
919 QMap<int, KService::Ptr> services;
920 QMap<int, KService::Ptr>::iterator it;
922 for ( int i = 0; i < offers.count(); ++i )
924 services[ offers[i]->property( "X-KDE-KGet-rank" ).toInt() ] = offers[i];
925 kDebug(5001) << " TransferFactory plugin found:" << endl <<
926 " rank = " << offers[i]->property( "X-KDE-KGet-rank" ).toInt() << endl <<
927 " plugintype = " << offers[i]->property( "X-KDE-KGet-plugintype" ) << endl;
930 //I must fill this pluginList before and my m_transferFactories list after.
931 //This because calling the KLibLoader::globalLibrary() erases the static
932 //members of this class (why?), such as the m_transferFactories list.
933 QList<KGetPlugin *> pluginList;
935 for( it = services.begin(); it != services.end(); ++it )
937 KGetPlugin * plugin;
938 if( (plugin = createPluginFromService(*it)) != 0 )
940 pluginList.prepend(plugin);
941 kDebug(5001) << "TransferFactory plugin (" << (*it)->library()
942 << ") found and added to the list of available plugins" << endl;
944 else
945 kDebug(5001) << "Error loading TransferFactory plugin ("
946 << (*it)->library() << ")" << endl;
949 QList<KGetPlugin *>::iterator it2 = pluginList.begin();
950 QList<KGetPlugin *>::iterator it2End = pluginList.end();
952 for( ; it2!=it2End ; ++it2 )
953 m_transferFactories.append( static_cast<TransferFactory *>(*it2) );
955 kDebug(5001) << "Number of factories = " << m_transferFactories.size();
958 KGetPlugin * KGet::createPluginFromService( const KService::Ptr &service )
960 //try to load the specified library
961 KPluginFactory *factory = KPluginLoader(service->library()).factory();
963 if (!factory)
965 KMessageBox::error(0, i18n("<html><p>KPluginFactory could not load the plugin:<br/><i>%1</i></p></html>",
966 service->library()));
967 kError(5001) << "KPluginFactory could not load the plugin:" << service->library();
968 return 0;
970 KGetPlugin * plugin = factory->create< TransferFactory >(0);
972 return plugin;
975 bool KGet::safeDeleteFile( const KUrl& url )
977 if ( url.isLocalFile() )
979 QFileInfo info( url.path() );
980 if ( info.isDir() )
982 KMessageBox::information(0L,i18n("Not deleting\n%1\nas it is a "
983 "directory.", url.prettyUrl()),
984 i18n("Not Deleted"));
985 return false;
987 KIO::NetAccess::del( url, 0L );
988 return true;
991 else
992 KMessageBox::information( 0L,
993 i18n("Not deleting\n%1\nas it is not a local"
994 " file.", url.prettyUrl()),
995 i18n("Not Deleted") );
996 return false;