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/transfergroup.h"
13 #include "core/transfergrouphandler.h"
14 #include "core/kget.h"
15 #include "core/transferhistorystore.h"
18 #include <KMessageBox>
20 #include <KStandardDirs>
21 #include <kio/global.h>
25 #include <QDomElement>
28 TransferGroup::TransferGroup(TransferTreeModel
* model
, Scheduler
* scheduler
, const QString
& name
)
29 : JobQueue(scheduler
),
30 m_model(model
), m_name(name
),
31 m_totalSize(0), m_downloadedSize(0), m_uploadedSize(0),
32 m_percent(0), m_downloadSpeed(0), m_uploadSpeed(0),
33 m_downloadLimit(0), m_uploadLimit(0),
34 m_visibleDownloadLimit(0), m_visibleUploadLimit(0),
35 m_iconName("bookmark-new-list"), m_defaultFolder(0)
37 m_handler
= new TransferGroupHandler(this, scheduler
);
40 TransferGroup::~TransferGroup()
42 m_handler
->postDeleteEvent();
45 int TransferGroup::downloadSpeed()
48 foreach(Job
*job
, runningJobs())
50 Transfer
*transfer
= static_cast<Transfer
*>(job
);
52 m_downloadSpeed
+= transfer
->downloadSpeed();
54 return m_downloadSpeed
;
57 int TransferGroup::uploadSpeed()
60 foreach(Job
*job
, runningJobs())
62 Transfer
*transfer
= static_cast<Transfer
*>(job
);
64 m_uploadSpeed
+= transfer
->uploadSpeed();
69 bool TransferGroup::supportsSpeedLimits()
72 foreach (Job
* job
, runningJobs())
74 Transfer
* transfer
= static_cast<Transfer
*>(job
);
75 if (!transfer
->supportsSpeedLimits())
81 void TransferGroup::setStatus(Status queueStatus
)
83 JobQueue::setStatus(queueStatus
);
85 m_handler
->setGroupChange(Gc_Status
, true);
88 void TransferGroup::append(Transfer
* transfer
)
90 kDebug(5001) << "TransferGroup::append";
96 after
= static_cast<Transfer
*> (last());
98 JobQueue::append(transfer
);
100 calculateSpeedLimits();
101 m_handler
->postAddedTransferEvent(transfer
, after
);
104 void TransferGroup::prepend(Transfer
* transfer
)
106 JobQueue::prepend(transfer
);
108 m_handler
->postAddedTransferEvent(transfer
, 0);
109 calculateSpeedLimits();
112 void TransferGroup::insert(Transfer
* transfer
, Transfer
* after
)
114 JobQueue::insert(transfer
, after
);
116 m_handler
->postAddedTransferEvent(transfer
, after
);
117 calculateSpeedLimits();
120 void TransferGroup::remove(Transfer
* transfer
)
122 TransferHistoryStore::getStore()->saveItem(TransferHistoryItem(*transfer
));
123 JobQueue::remove(transfer
);
125 m_handler
->postRemovedTransferEvent(transfer
);
126 calculateSpeedLimits();
129 void TransferGroup::move(Transfer
* transfer
, Transfer
* after
)
131 if(transfer
== after
)
134 TransferGroup
* oldTransferGroup
= transfer
->group();
136 JobQueue::move(transfer
, after
);
138 if(oldTransferGroup
== this)
139 m_handler
->postMovedTransferEvent(transfer
, after
);
142 m_handler
->postAddedTransferEvent(transfer
, after
);
143 oldTransferGroup
->handler()->postRemovedTransferEvent(transfer
);
147 Transfer
* TransferGroup::findTransfer(const KUrl
&src
)
149 iterator it
= begin();
150 iterator itEnd
= end();
152 for(; it
!=itEnd
; ++it
)
154 Transfer
* t
= (Transfer
*) *it
;
155 if( t
->source().url() == src
.url() )
161 Transfer
*TransferGroup::findTransferByDestination(const KUrl
&dest
)
163 iterator it
= begin();
164 iterator itEnd
= end();
166 for(; it
!=itEnd
; ++it
) {
167 Transfer
*t
= (Transfer
*) *it
;
168 if(t
->dest().url() == dest
.url()) {
175 Transfer
* TransferGroup::operator[] (int i
) const
177 // kDebug(5001) << "TransferGroup::operator[]";
179 return (Transfer
*)((* (JobQueue
*)this)[i
]);
182 TransferGroupHandler
* TransferGroup::handler() const
187 void TransferGroup::setUploadLimit(int ulLimit
, Transfer::SpeedLimit limit
)
189 if (limit
== Transfer::VisibleSpeedLimit
)
190 m_visibleUploadLimit
= ulLimit
;
191 if (ulLimit
< m_uploadLimit
|| m_uploadLimit
== 0)
192 m_uploadLimit
= ulLimit
;
194 m_uploadLimit
= ulLimit
;
196 calculateUploadLimit();
199 void TransferGroup::setDownloadLimit(int dlLimit
, Transfer::SpeedLimit limit
)
201 if (limit
== Transfer::VisibleSpeedLimit
)
202 m_visibleDownloadLimit
= dlLimit
;
203 if (dlLimit
< m_downloadLimit
|| m_downloadLimit
== 0)
204 m_downloadLimit
= dlLimit
;
206 m_downloadLimit
= dlLimit
;
208 calculateDownloadLimit();
211 int TransferGroup::uploadLimit(Transfer::SpeedLimit limit
) const
213 if (limit
== Transfer::VisibleSpeedLimit
)
214 return m_visibleUploadLimit
;
216 return m_uploadLimit
;
219 int TransferGroup::downloadLimit(Transfer::SpeedLimit limit
) const
221 if (limit
== Transfer::VisibleSpeedLimit
)
222 return m_visibleDownloadLimit
;
224 return m_downloadLimit
;
227 void TransferGroup::calculateSpeedLimits()
229 kDebug(5001) << "We will calculate the new SpeedLimits now";
230 calculateDownloadLimit();
231 calculateUploadLimit();
234 void TransferGroup::calculateDownloadLimit()
236 kDebug(5001) << "Calculate new DownloadLimit of " + QString::number(m_downloadLimit
);
237 if (supportsSpeedLimits())
239 int n
= runningJobs().count();
240 int pool
= 0;//We create a pool where we have some KiB/s to go to other transfer's...
241 QList
<Transfer
*> transfersNeedSpeed
;
242 foreach (Job
* job
, runningJobs())
244 Transfer
* transfer
= static_cast<Transfer
*>(job
);
247 if (m_downloadLimit
== 0 && transfer
->downloadLimit(Transfer::VisibleSpeedLimit
) != 0)
249 else if (m_downloadLimit
== 0 && transfer
->downloadLimit(Transfer::VisibleSpeedLimit
) == 0)
250 transfer
->setDownloadLimit(0, Transfer::InvisibleSpeedLimit
);
251 else if (transfer
->downloadLimit(Transfer::VisibleSpeedLimit
) < m_downloadLimit
/ n
252 && transfer
->downloadLimit(Transfer::VisibleSpeedLimit
) != 0)
253 /*If the transfer's visible download limit is under the new one,
254 we move the KiB/s which are different to the pool*/
255 pool
= pool
+ (m_downloadLimit
/ n
- transfer
->downloadLimit(Transfer::VisibleSpeedLimit
));
256 else if (transfer
->downloadSpeed() + 10 < m_downloadLimit
/ n
)
258 /*When the downloadSpeed of the transfer is under the new downloadLimit + 10 then we
259 set the downloadLimit to the downloadSpeed + 10*/
260 pool
= pool
+ m_downloadLimit
/ n
- transfer
->downloadSpeed() + 10;
261 transfer
->setDownloadLimit(transfer
->downloadSpeed() + 10, Transfer::InvisibleSpeedLimit
);
265 transfer
->setDownloadLimit(m_downloadLimit
/ n
, Transfer::InvisibleSpeedLimit
);
266 transfersNeedSpeed
.append(transfer
);
270 foreach (Transfer
*transfer
, transfersNeedSpeed
)
272 transfer
->setDownloadLimit(m_downloadLimit
/ n
+ pool
/ transfersNeedSpeed
.count(), Transfer::InvisibleSpeedLimit
);
277 void TransferGroup::calculateUploadLimit()
279 kDebug(5001) << "Calculate new Upload Limit of " + QString::number(m_uploadLimit
);
280 if (supportsSpeedLimits())
282 int n
= runningJobs().count();
283 int pool
= 0;//We create a pool where we have some KiB/s to go to other transfer's...
284 QList
<Transfer
*> transfersNeedSpeed
;
285 foreach (Job
* job
, runningJobs())
287 Transfer
* transfer
= static_cast<Transfer
*>(job
);
290 if (m_uploadLimit
== 0 && transfer
->uploadLimit(Transfer::VisibleSpeedLimit
) != 0)
292 else if (m_uploadLimit
== 0 && transfer
->uploadLimit(Transfer::VisibleSpeedLimit
) == 0)
293 transfer
->setUploadLimit(0, Transfer::InvisibleSpeedLimit
);
294 else if (transfer
->uploadLimit(Transfer::VisibleSpeedLimit
) < m_uploadLimit
/ n
295 && transfer
->uploadLimit(Transfer::VisibleSpeedLimit
) != 0)
296 /*If the transfer's visible upload limit is under the new one,
297 we move the KiB/s which are different to the pool*/
298 pool
= pool
+ (m_uploadLimit
/ n
- transfer
->uploadLimit(Transfer::VisibleSpeedLimit
));
299 else if (transfer
->uploadSpeed() + 10 < m_uploadLimit
/ n
)
301 /*When the uploadSpeed of the transfer is under the new uploadLimit + 10 then we
302 set the uploadLimit to the uploadSpeed + 10*/
303 pool
= pool
+ m_uploadLimit
/ n
- transfer
->uploadSpeed() + 10;
304 transfer
->setUploadLimit(transfer
->uploadSpeed() + 10, Transfer::InvisibleSpeedLimit
);
308 transfer
->setUploadLimit(m_uploadLimit
/ n
, Transfer::InvisibleSpeedLimit
);
309 transfersNeedSpeed
.append(transfer
);
313 foreach (Transfer
*transfer
, transfersNeedSpeed
)
315 transfer
->setUploadLimit(m_uploadLimit
/ n
+ pool
/ transfersNeedSpeed
.count(), Transfer::InvisibleSpeedLimit
);
320 void TransferGroup::transferChangedEvent(Transfer
* transfer
)
323 // Disable this line for now, since as of now we don't do nothing with this event.
324 // reenabled for the plasma applet
325 m_handler
->postGroupChangedEvent();
328 void TransferGroup::save(QDomElement e
) // krazy:exclude=passbyvalue
330 kDebug(5001) << " --> " << name();
332 e
.setAttribute("Name", m_name
);
333 e
.setAttribute("DefaultFolder", m_defaultFolder
);
334 e
.setAttribute("DownloadLimit", m_visibleDownloadLimit
);
335 e
.setAttribute("UploadLimit", m_visibleUploadLimit
);
336 e
.setAttribute("Icon", m_iconName
);
337 e
.setAttribute("Status", status() == JobQueue::Running
? "Running" : "Stopped");
339 iterator it
= begin();
340 iterator itEnd
= end();
342 for( ; it
!=itEnd
; ++it
)
344 kDebug(5001) << " --> " << name() << " transfer: " << ((Transfer
*) *it
)->source();
345 QDomElement t
= e
.ownerDocument().createElement("Transfer");
347 ((Transfer
*) *it
)->save(t
);
351 void TransferGroup::load(const QDomElement
& e
)
353 kDebug(5001) << "TransferGroup::load";
355 m_name
= e
.attribute("Name");
356 m_defaultFolder
= e
.attribute("DefaultFolder");
357 m_visibleDownloadLimit
= e
.attribute("DownloadLimit").toInt();
358 m_visibleUploadLimit
= e
.attribute("UploadLimit").toInt();
359 if (!e
.attribute("Icon").isEmpty())
360 m_iconName
= e
.attribute("Icon");
362 if (e
.attribute("Status") == "Running")
363 setStatus(JobQueue::Running
);
365 setStatus(JobQueue::Stopped
);
367 QDomNodeList nodeList
= e
.elementsByTagName("Transfer");
368 int nItems
= nodeList
.length();
370 for(int i
=0; i
<nItems
; i
++)
372 kDebug(5001) << "TransferGroup::load -> addTransfer";
373 KGet::addTransfer( nodeList
.item(i
).toElement(), name() );