1 /* This file is part of the KDE project
3 Copyright (C) 2005 Dario Massarin <nekkar@libero.it>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
11 #include "core/transferhandler.h"
14 #include "core/jobqueue.h"
15 #include "core/transfergroup.h"
16 #include "core/transfergrouphandler.h"
17 #include "core/transfertreemodel.h"
18 #include "core/plugin/transferfactory.h"
19 #include "core/observer.h"
21 #include "mainwindow.h"
25 #include <KPassivePopup>
29 #ifdef HAVE_KWORKSPACE
30 #include <kworkspace/kworkspace.h>
33 TransferHandler::TransferHandler(Transfer
* transfer
, Scheduler
* scheduler
)
40 TransferHandler::~TransferHandler()
42 // qDeleteAll(m_observers);
45 void TransferHandler::addObserver(TransferObserver
* observer
)
47 m_observers
.push_back(observer
);
48 m_changesFlags
[observer
]=0xFFFFFFFF;
49 kDebug(5001) << "TransferHandler: OBSERVERS++ = " << m_observers
.size();
52 void TransferHandler::delObserver(TransferObserver
* observer
)
54 m_observers
.removeAll(observer
);
55 m_changesFlags
.remove(observer
);
56 kDebug(5001) << "TransferHandler: OBSERVERS-- = " << m_observers
.size();
59 void TransferHandler::start()
61 if(m_transfer
->group()->status() == JobQueue::Running
)
63 m_transfer
->setPolicy(Job::None
);
64 m_transfer
->group()->move(m_transfer
, 0);
68 m_transfer
->setPolicy(Job::Start
);
72 void TransferHandler::stop()
74 if (m_transfer
->group()->status() == JobQueue::Stopped
)
76 m_transfer
->setPolicy(Job::None
);
80 m_transfer
->setPolicy(Job::Stop
);
84 int TransferHandler::elapsedTime() const
86 return m_transfer
->elapsedTime();
89 int TransferHandler::remainingTime() const
91 return m_transfer
->remainingTime();
94 bool TransferHandler::isResumable() const
96 return m_transfer
->isResumable();
99 KIO::filesize_t
TransferHandler::totalSize() const
101 return m_transfer
->totalSize();
104 KIO::filesize_t
TransferHandler::downloadedSize() const
106 return m_transfer
->downloadedSize();
109 KIO::filesize_t
TransferHandler::uploadedSize() const
111 return m_transfer
->uploadedSize();
114 int TransferHandler::percent() const
116 return m_transfer
->percent();
119 int TransferHandler::downloadSpeed() const
121 return m_transfer
->downloadSpeed();
124 int TransferHandler::uploadSpeed() const
126 return m_transfer
->uploadSpeed();
129 QVariant
TransferHandler::data(int column
)
131 // kDebug(5001) << "TransferHandler::data(" << column << ")";
136 return dest().fileName();
140 if (totalSize() != 0)
141 return KIO::convertSize(totalSize());
143 return i18nc("not available", "n/a");
145 // return QString::number(percent())+'%'; // display progressbar instead
148 if (downloadSpeed()==0)
150 if (status() == Job::Running
)
151 return i18n("Stalled");
156 return i18n("%1/s", KIO::convertSize(downloadSpeed()));
158 if (status() == Job::Running
)
159 return KIO::convertSeconds(remainingTime());
167 void TransferHandler::setSelected( bool select
)
169 if( (select
&& !isSelected()) || (!select
&& isSelected()) )
171 m_transfer
->m_isSelected
= select
;
172 setTransferChange( Transfer::Tc_Selection
, true );
176 bool TransferHandler::isSelected() const
178 return m_transfer
->m_isSelected
;
181 Transfer::ChangesFlags
TransferHandler::changesFlags(TransferObserver
* observer
) const
183 if( m_changesFlags
.find(observer
) != m_changesFlags
.end() )
184 return m_changesFlags
[observer
];
187 kDebug(5001) << " TransferHandler::changesFlags() doesn't see you as an observer! ";
193 void TransferHandler::resetChangesFlags(TransferObserver
* observer
)
195 if( m_changesFlags
.find(observer
) != m_changesFlags
.end() )
196 m_changesFlags
[observer
] = 0;
198 kDebug(5001) << " TransferHandler::resetChangesFlags() doesn't see you as an observer! ";
201 void TransferHandler::setTransferChange(ChangesFlags change
, bool postEvent
)
203 QMap
<TransferObserver
*, ChangesFlags
>::Iterator it
= m_changesFlags
.begin();
204 QMap
<TransferObserver
*, ChangesFlags
>::Iterator itEnd
= m_changesFlags
.end();
206 for( ; it
!=itEnd
; ++it
)
210 postTransferChangedEvent();
213 void TransferHandler::postTransferChangedEvent()
215 // kDebug(5001) << "TransferHandler::postTransferChangedEvent() ENTERING";
217 // Here we have to copy the list and iterate on the copy itself, because
218 // a view can remove itself as a view while we are iterating over the
219 // observers list and this leads to crashes.
220 QList
<TransferObserver
*> observers
= m_observers
;
222 QList
<TransferObserver
*>::iterator it
= observers
.begin();
223 QList
<TransferObserver
*>::iterator itEnd
= observers
.end();
225 // Notify the observers
226 for(; it
!=itEnd
; ++it
)
229 (*it
)->transferChangedEvent(this);
233 m_transfer
->group()->transferChangedEvent(m_transfer
);
235 // Notify the TransferTreeModel
236 m_transfer
->model()->postDataChangedEvent(this);
238 //kDebug(5001) << "TransferHandler::postTransferChangedEvent() LEAVING";
241 void TransferHandler::postDeleteEvent()
243 kDebug(5001) << "TransferHandler::postDeleteEvent() ENTERING";
245 m_transfer
->postDeleteEvent();//First inform the transfer itself
247 //Here we have to copy the list and iterate on the copy itself, because
248 //a view can remove itself as a view while we are iterating over the
249 //observers list and this leads to crashes.
250 QList
<TransferObserver
*> observers
= m_observers
;
252 QList
<TransferObserver
*>::iterator it
= observers
.begin();
253 QList
<TransferObserver
*>::iterator itEnd
= observers
.end();
255 for(; it
!=itEnd
; ++it
)
257 if(*it
&& *it
!= dynamic_cast<TransferObserver
*>(m_transfer
))
258 (*it
)->deleteEvent(this);
260 kDebug(5001) << "TransferHandler::postDeleteEvent() LEAVING";
263 QList
<QAction
*> TransferHandler::contextActions()
265 QList
<QAction
*> actions
;
266 if (status() != Job::Finished
)
268 actions
<< KGet::actionCollection()->action("start_selected_download")
269 << KGet::actionCollection()->action("stop_selected_download");
271 actions
<< KGet::actionCollection()->action("delete_selected_download")
272 << KGet::actionCollection()->action("redownload_selected_download");
277 QList
<QAction
*> TransferHandler::factoryActions()
279 QList
<QAction
*> actions
;
280 foreach(QAction
*action
, m_transfer
->factory()->actions(this))
281 actions
.append(action
);
286 GenericTransferObserver::GenericTransferObserver(GenericTransferGroupObserver
*groupObserver
)
287 : QObject(groupObserver
),
290 m_groupObserver
= groupObserver
;
293 void GenericTransferObserver::transferChangedEvent(TransferHandler
* transfer
)
296 TransferHandler::ChangesFlags transferFlags
= transfer
->changesFlags(this);
298 if (transfer
->status() == Job::Finished
&& Settings::afterFinishActionEnabled()
299 && Settings::afterFinishAction() == KGet::Quit
)
304 #ifdef HAVE_KWORKSPACE
305 if (transfer
->status() == Job::Finished
&& Settings::afterFinishActionEnabled()
306 && Settings::afterFinishAction() == KGet::Shutdown
) {
311 if (prevStatus
!= transfer
->statusText())//FIXME: HACK: better: check statusFlags if it
312 { //contains Tc_Status (flags & Transfer::Tc_Status <-doesn't work)
313 prevStatus
= transfer
->statusText();
314 KGet::checkSystemTray();
317 if (transferFlags
& Transfer::Tc_Percent
) {
318 transfer
->group()->setGroupChange(TransferGroup::Gc_Percent
, true);
321 if (transferFlags
& Transfer::Tc_DownloadSpeed
) {
322 transfer
->group()->setGroupChange(TransferGroup::Gc_DownloadSpeed
, true);
325 if (transferFlags
& Transfer::Tc_UploadSpeed
) {
326 transfer
->group()->setGroupChange(TransferGroup::Gc_UploadSpeed
, true);
329 transfer
->resetChangesFlags(this);
330 transfer
->checkShareRatio();
332 m_groupObserver
->postTransferChanged(transfer
);
335 bool GenericTransferObserver::allTransfersFinished()
337 bool quitFlag
= true;
338 foreach(TransferGroup
*transferGroup
, KGet::m_transferTreeModel
->transferGroups()) {
339 foreach(TransferHandler
*transfer
, transferGroup
->handler()->transfers()) {
340 if(transfer
->status() != Job::Finished
) {
349 KPassivePopup
* GenericTransferObserver::popupMessage(const QString
&title
, const QString
&message
)
351 KPassivePopup
*popup
;
352 // we have to call diferent message from kpassivePopup
353 // one with parent as QWidget for the mainWindow
354 // and another with parent as QSystemTrayIcon if the parent is a systemTray
355 // so passing the QSystemTrayIcon as QWidget don't work
356 if(Settings::enableSystemTray())
358 popup
= KPassivePopup::message(5000, title
, message
, KGet::m_mainWindow
->systemTray());
362 popup
= KPassivePopup::message(5000, title
, message
, KGet::m_mainWindow
);
368 void GenericTransferObserver::checkAndFinish()
370 // check if there is some unfinished transfer in scheduler queues
371 if(allTransfersFinished()) {
372 KPassivePopup
*message
= popupMessage(i18n("Quit KGet"),
373 i18n("KGet is now closing, as all downloads have completed."));
374 QObject::connect(message
, SIGNAL(destroyed()), KGet::m_mainWindow
, SLOT(slotQuit()));
378 #ifdef HAVE_KWORKSPACE
379 void GenericTransferObserver::checkAndShutdown()
381 if(allTransfersFinished()) {
382 KPassivePopup
*message
= popupMessage(i18n("Quit KGet"),
383 i18n("The computer will now turn off, as all downloads have completed."));
384 QObject::connect(message
, SIGNAL(destroyed()), SLOT(slotShutdown()));
385 QObject::connect(message
, SIGNAL(destroyed()), KGet::m_mainWindow
, SLOT(slotQuit()));
389 void GenericTransferObserver::slotShutdown()
391 KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmNo
,
392 KWorkSpace::ShutdownTypeHalt
,
393 KWorkSpace::ShutdownModeForceNow
);