You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
815 lines
17 KiB
815 lines
17 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by Joris Guisson *
|
|
* joris.guisson@gmail.com *
|
|
* ivasic@gmail.com *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
***************************************************************************/
|
|
#include "queuemanager.h"
|
|
|
|
#include <tqstring.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tdelocale.h>
|
|
#include <util/log.h>
|
|
#include <util/error.h>
|
|
#include <util/sha1hash.h>
|
|
#include <util/waitjob.h>
|
|
#include <util/fileops.h>
|
|
#include <torrent/globals.h>
|
|
#include <torrent/torrent.h>
|
|
#include <torrent/torrentcontrol.h>
|
|
#include <interfaces/torrentinterface.h>
|
|
#include <interfaces/trackerslist.h>
|
|
#include <settings.h>
|
|
|
|
|
|
using namespace kt;
|
|
|
|
namespace bt
|
|
{
|
|
|
|
QueueManager::QueueManager() : TQObject(),exiting(false)
|
|
{
|
|
downloads.setAutoDelete(true);
|
|
max_downloads = 0;
|
|
max_seeds = 0; //for testing. Needs to be added to Settings::
|
|
|
|
keep_seeding = true; //test. Will be passed from Core
|
|
paused_state = false;
|
|
ordering = false;
|
|
}
|
|
|
|
|
|
QueueManager::~QueueManager()
|
|
{}
|
|
|
|
void QueueManager::append(kt::TorrentInterface* tc)
|
|
{
|
|
downloads.append(tc);
|
|
downloads.sort();
|
|
|
|
connect(tc, TQT_SIGNAL(diskSpaceLow(kt::TorrentInterface*, bool)), this, TQT_SLOT(onLowDiskSpace(kt::TorrentInterface*, bool)));
|
|
connect(tc, TQT_SIGNAL(torrentStopped(kt::TorrentInterface*)), this, TQT_SLOT(torrentStopped(kt::TorrentInterface*)));
|
|
}
|
|
|
|
void QueueManager::remove(kt::TorrentInterface* tc)
|
|
{
|
|
paused_torrents.erase(tc);
|
|
|
|
int index = downloads.findRef(tc);
|
|
|
|
if (index != -1)
|
|
downloads.remove(index);
|
|
else
|
|
Out(SYS_GEN | LOG_IMPORTANT) << "Could not delete removed torrent control." << endl;
|
|
}
|
|
|
|
void QueueManager::clear()
|
|
{
|
|
Uint32 nd = downloads.count();
|
|
|
|
paused_torrents.clear();
|
|
downloads.clear();
|
|
|
|
// wait for a second to allow all http jobs to send the stopped event
|
|
if (nd > 0)
|
|
SynchronousWait(1000);
|
|
}
|
|
|
|
kt::TorrentStartResponse QueueManager::start(kt::TorrentInterface* tc, bool user)
|
|
{
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
bool start_tc = user;
|
|
|
|
bool check_done = false;
|
|
|
|
if (tc->isCheckingData(check_done) && !check_done)
|
|
return kt::BUSY_WITH_DATA_CHECK;
|
|
|
|
if (!user)
|
|
{
|
|
if (s.completed)
|
|
start_tc = (max_seeds == 0 || getNumRunning(false, true) < max_seeds);
|
|
else
|
|
start_tc = (max_downloads == 0 || getNumRunning(true) < max_downloads);
|
|
}
|
|
else
|
|
{
|
|
//User started this torrent so make it user controlled
|
|
tc->setPriority(0);
|
|
}
|
|
|
|
if (start_tc)
|
|
{
|
|
|
|
if (!s.completed) //no need to check diskspace for seeding torrents
|
|
{
|
|
//check diskspace
|
|
bool shortDiskSpace = !tc->checkDiskSpace(false);
|
|
|
|
if (shortDiskSpace)
|
|
{
|
|
//we're short!
|
|
|
|
switch (Settings::startDownloadsOnLowDiskSpace())
|
|
{
|
|
|
|
case 0: //don't start!
|
|
tc->setPriority(0);
|
|
return kt::NOT_ENOUGH_DISKSPACE;
|
|
|
|
case 1: //ask user
|
|
if (KMessageBox::questionYesNo(0, i18n("You don't have enough disk space to download this torrent. Are you sure you want to continue?"), i18n("Insufficient disk space for %1").arg(s.torrent_name)) == KMessageBox::No)
|
|
{
|
|
tc->setPriority(0);
|
|
return kt::USER_CANCELED;
|
|
}
|
|
else
|
|
break;
|
|
|
|
case 2: //force start
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Out(SYS_GEN | LOG_NOTICE) << "Starting download" << endl;
|
|
|
|
float ratio = kt::ShareRatio(s);
|
|
|
|
float max_ratio = tc->getMaxShareRatio();
|
|
|
|
if (s.completed && max_ratio > 0 && ratio >= max_ratio)
|
|
{
|
|
if (KMessageBox::questionYesNo(0, i18n("Torrent \"%1\" has reached its maximum share ratio. Ignore the limit and start seeding anyway?").arg(s.torrent_name), i18n("Maximum share ratio limit reached.")) == KMessageBox::Yes)
|
|
{
|
|
tc->setMaxShareRatio(0.00f);
|
|
startSafely(tc);
|
|
}
|
|
else
|
|
return kt::USER_CANCELED;
|
|
}
|
|
else
|
|
startSafely(tc);
|
|
}
|
|
else
|
|
{
|
|
return kt::TQM_LIMITS_REACHED;
|
|
}
|
|
|
|
return kt::START_OK;
|
|
}
|
|
|
|
void QueueManager::stop(kt::TorrentInterface* tc, bool user)
|
|
{
|
|
bool check_done = false;
|
|
|
|
if (tc->isCheckingData(check_done) && !check_done)
|
|
return;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (s.running)
|
|
{
|
|
stopSafely(tc, user);
|
|
}
|
|
|
|
if (user) //dequeue it
|
|
tc->setPriority(0);
|
|
}
|
|
|
|
void QueueManager::startall(int type)
|
|
{
|
|
TQPtrList<kt::TorrentInterface>::iterator i = downloads.begin();
|
|
|
|
while (i != downloads.end())
|
|
{
|
|
kt::TorrentInterface* tc = *i;
|
|
|
|
if (type >= 3)
|
|
start(tc, true);
|
|
else
|
|
{
|
|
if ((tc->getStats().completed && type == 2) || (!tc->getStats().completed && type == 1) || (type == 3))
|
|
start(tc, true);
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void QueueManager::stopall(int type)
|
|
{
|
|
TQPtrList<kt::TorrentInterface>::iterator i = downloads.begin();
|
|
|
|
while (i != downloads.end())
|
|
{
|
|
kt::TorrentInterface* tc = *i;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (tc->getStats().running)
|
|
{
|
|
try
|
|
{
|
|
if (type >= 3)
|
|
stopSafely(tc, true);
|
|
else if ((s.completed && type == 2) || (!s.completed && type == 1))
|
|
stopSafely(tc, true);
|
|
}
|
|
catch (bt::Error & err)
|
|
{
|
|
TQString msg =
|
|
i18n("Error stopping torrent %1 : %2")
|
|
.arg(s.torrent_name).arg(err.toString());
|
|
KMessageBox::error(0, msg, i18n("Error"));
|
|
}
|
|
}
|
|
else //if torrent is not running but it is queued we need to make it user controlled
|
|
if ((s.completed && type == 2) || (!s.completed && type == 1) || (type == 3))
|
|
tc->setPriority(0);
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void QueueManager::onExit(WaitJob* wjob)
|
|
{
|
|
exiting = true;
|
|
TQPtrList<kt::TorrentInterface>::iterator i = downloads.begin();
|
|
|
|
while (i != downloads.end())
|
|
{
|
|
kt::TorrentInterface* tc = *i;
|
|
|
|
if (tc->getStats().running)
|
|
{
|
|
stopSafely(tc, false, wjob);
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
void QueueManager::startNext()
|
|
{
|
|
orderQueue();
|
|
}
|
|
|
|
int QueueManager::countDownloads()
|
|
{
|
|
int nr = 0;
|
|
TQPtrList<TorrentInterface>::const_iterator i = downloads.begin();
|
|
|
|
while (i != downloads.end())
|
|
{
|
|
if (!(*i)->getStats().completed)
|
|
++nr;
|
|
|
|
++i;
|
|
}
|
|
|
|
return nr;
|
|
}
|
|
|
|
int QueueManager::countSeeds()
|
|
{
|
|
int nr = 0;
|
|
TQPtrList<TorrentInterface>::const_iterator i = downloads.begin();
|
|
|
|
while (i != downloads.end())
|
|
{
|
|
if ((*i)->getStats().completed)
|
|
++nr;
|
|
|
|
++i;
|
|
}
|
|
|
|
return nr;
|
|
}
|
|
|
|
int QueueManager::getNumRunning(bool onlyDownload, bool onlySeed)
|
|
{
|
|
int nr = 0;
|
|
// int test = 1;
|
|
TQPtrList<TorrentInterface>::const_iterator i = downloads.begin();
|
|
|
|
while (i != downloads.end())
|
|
{
|
|
const TorrentInterface* tc = *i;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
//Out() << "Torrent " << test++ << s.torrent_name << " priority: " << tc->getPriority() << endl;
|
|
if (s.running)
|
|
{
|
|
if (onlyDownload)
|
|
{
|
|
if (!s.completed) nr++;
|
|
}
|
|
else
|
|
{
|
|
if (onlySeed)
|
|
{
|
|
if (s.completed) nr++;
|
|
}
|
|
else
|
|
nr++;
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
// Out() << endl;
|
|
return nr;
|
|
}
|
|
|
|
int QueueManager::getNumRunning(bool userControlled, bool onlyDownloads, bool onlySeeds)
|
|
{
|
|
int nr = 0;
|
|
// int test = 1;
|
|
TQPtrList<TorrentInterface>::const_iterator i = downloads.begin();
|
|
|
|
while (i != downloads.end())
|
|
{
|
|
const TorrentInterface* tc = *i;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
//Out() << "Torrent " << test++ << s.torrent_name << " priority: " << tc->getPriority() << endl;
|
|
if (s.running)
|
|
{
|
|
if (onlyDownloads)
|
|
{
|
|
if (!s.completed && (userControlled && s.user_controlled)) nr++;
|
|
}
|
|
else
|
|
{
|
|
if (onlySeeds)
|
|
{
|
|
if (s.completed && (userControlled && s.user_controlled)) nr++;
|
|
}
|
|
else
|
|
if (userControlled && s.user_controlled) nr++;
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
// Out() << endl;
|
|
return nr;
|
|
}
|
|
|
|
TQPtrList<kt::TorrentInterface>::iterator QueueManager::begin()
|
|
{
|
|
return downloads.begin();
|
|
}
|
|
|
|
TQPtrList<kt::TorrentInterface>::iterator QueueManager::end()
|
|
{
|
|
return downloads.end();
|
|
}
|
|
|
|
void QueueManager::setMaxDownloads(int m)
|
|
{
|
|
max_downloads = m;
|
|
}
|
|
|
|
void QueueManager::setMaxSeeds(int m)
|
|
{
|
|
max_seeds = m;
|
|
}
|
|
|
|
void QueueManager::setKeepSeeding(bool ks)
|
|
{
|
|
keep_seeding = ks;
|
|
}
|
|
|
|
bool QueueManager::allreadyLoaded(const SHA1Hash & ih) const
|
|
{
|
|
TQPtrList<kt::TorrentInterface>::const_iterator itr = downloads.begin();
|
|
|
|
while (itr != downloads.end())
|
|
{
|
|
const TorrentControl* tor = (const TorrentControl*)(*itr);
|
|
|
|
if (tor->getTorrent().getInfoHash() == ih)
|
|
return true;
|
|
|
|
itr++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void QueueManager::mergeAnnounceList(const SHA1Hash & ih, const TrackerTier* trk)
|
|
|
|
{
|
|
TQPtrList<kt::TorrentInterface>::iterator itr = downloads.begin();
|
|
|
|
while (itr != downloads.end())
|
|
{
|
|
TorrentControl* tor = (TorrentControl*)(*itr);
|
|
|
|
if (tor->getTorrent().getInfoHash() == ih)
|
|
{
|
|
TrackersList* ta = tor->getTrackersList();
|
|
ta->merge(trk);
|
|
return;
|
|
}
|
|
|
|
itr++;
|
|
}
|
|
}
|
|
|
|
void QueueManager::orderQueue()
|
|
{
|
|
if (!downloads.count() || ordering)
|
|
return;
|
|
|
|
if (paused_state || exiting)
|
|
return;
|
|
|
|
ordering = true;
|
|
|
|
downloads.sort();
|
|
|
|
TQPtrList<TorrentInterface>::const_iterator it = downloads.begin();
|
|
TQPtrList<TorrentInterface>::const_iterator its = downloads.end();
|
|
|
|
|
|
if (max_downloads != 0 || max_seeds != 0)
|
|
{
|
|
bt::QueuePtrList download_queue;
|
|
bt::QueuePtrList seed_queue;
|
|
|
|
int user_downloading = 0;
|
|
int user_seeding = 0;
|
|
|
|
for (; it != downloads.end(); ++it)
|
|
{
|
|
TorrentInterface* tc = *it;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (s.running && s.user_controlled)
|
|
{
|
|
if (!s.completed)
|
|
++user_downloading;
|
|
else
|
|
++user_seeding;
|
|
}
|
|
|
|
if (!s.user_controlled && !tc->isMovingFiles() && !s.stopped_by_error)
|
|
{
|
|
if (s.completed)
|
|
seed_queue.append(tc);
|
|
else
|
|
download_queue.append(tc);
|
|
}
|
|
}
|
|
|
|
int max_qm_downloads = max_downloads - user_downloading;
|
|
|
|
int max_qm_seeds = max_seeds - user_seeding;
|
|
|
|
//stop all QM started torrents
|
|
|
|
for (Uint32 i = max_qm_downloads; i < download_queue.count() && max_downloads; ++i)
|
|
{
|
|
TorrentInterface* tc = download_queue.at(i);
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (s.running && !s.user_controlled && !s.completed)
|
|
{
|
|
Out(SYS_GEN | LOG_DEBUG) << "QM Stopping: " << s.torrent_name << endl;
|
|
stop(tc);
|
|
}
|
|
}
|
|
|
|
//stop all QM started torrents
|
|
for (Uint32 i = max_qm_seeds; i < seed_queue.count() && max_seeds; ++i)
|
|
{
|
|
TorrentInterface* tc = seed_queue.at(i);
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (s.running && !s.user_controlled && s.completed)
|
|
{
|
|
Out(SYS_GEN | LOG_NOTICE) << "QM Stopping: " << s.torrent_name << endl;
|
|
stop(tc);
|
|
}
|
|
}
|
|
|
|
//Now start all needed torrents
|
|
if (max_downloads == 0)
|
|
max_qm_downloads = download_queue.count();
|
|
|
|
if (max_seeds == 0)
|
|
max_qm_seeds = seed_queue.count();
|
|
|
|
int counter = 0;
|
|
|
|
for (Uint32 i = 0; counter < max_qm_downloads && i < download_queue.count(); ++i)
|
|
{
|
|
TorrentInterface* tc = download_queue.at(i);
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (!s.running && !s.completed && !s.user_controlled)
|
|
{
|
|
start(tc, false);
|
|
|
|
if (tc->getStats().stopped_by_error)
|
|
{
|
|
tc->setPriority(0);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
++counter;
|
|
}
|
|
|
|
counter = 0;
|
|
|
|
for (Uint32 i = 0; counter < max_qm_seeds && i < seed_queue.count(); ++i)
|
|
{
|
|
TorrentInterface* tc = seed_queue.at(i);
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (!s.running && s.completed && !s.user_controlled)
|
|
{
|
|
start(tc, false);
|
|
|
|
if (tc->getStats().stopped_by_error)
|
|
{
|
|
tc->setPriority(0);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
++counter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//no limits at all
|
|
|
|
for (it = downloads.begin(); it != downloads.end(); ++it)
|
|
{
|
|
TorrentInterface* tc = *it;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (!s.running && !s.user_controlled && !s.stopped_by_error && !tc->isMovingFiles())
|
|
{
|
|
start(tc, false);
|
|
if (tc->getStats().stopped_by_error)
|
|
tc->setPriority(0);
|
|
}
|
|
}
|
|
}
|
|
ordering = false;
|
|
}
|
|
|
|
void QueueManager::torrentFinished(kt::TorrentInterface* tc)
|
|
{
|
|
//dequeue this tc
|
|
tc->setPriority(0);
|
|
//make sure the max_seeds is not reached
|
|
// if(max_seeds !=0 && max_seeds < getNumRunning(false,true))
|
|
// tc->stop(true);
|
|
|
|
if (keep_seeding)
|
|
torrentAdded(tc, false, false);
|
|
else
|
|
stop(tc,true);
|
|
|
|
orderQueue();
|
|
}
|
|
|
|
void QueueManager::torrentAdded(kt::TorrentInterface* tc, bool user, bool start_torrent)
|
|
{
|
|
if (!user)
|
|
{
|
|
TQPtrList<TorrentInterface>::const_iterator it = downloads.begin();
|
|
|
|
while (it != downloads.end())
|
|
{
|
|
TorrentInterface* _tc = *it;
|
|
int p = _tc->getPriority();
|
|
|
|
if (p == 0)
|
|
break;
|
|
else
|
|
_tc->setPriority(++p);
|
|
|
|
++it;
|
|
}
|
|
|
|
tc->setPriority(1);
|
|
}
|
|
else
|
|
{
|
|
tc->setPriority(0);
|
|
if(start_torrent)
|
|
start(tc, true);
|
|
}
|
|
|
|
orderQueue();
|
|
}
|
|
|
|
void QueueManager::torrentRemoved(kt::TorrentInterface* tc)
|
|
{
|
|
remove(tc);
|
|
|
|
orderQueue();
|
|
}
|
|
|
|
void QueueManager::setPausedState(bool pause)
|
|
{
|
|
paused_state = pause;
|
|
if (!pause)
|
|
{
|
|
std::set<kt::TorrentInterface*>::iterator it = paused_torrents.begin();
|
|
while (it != paused_torrents.end())
|
|
{
|
|
TorrentInterface* tc = *it;
|
|
startSafely(tc);
|
|
it++;
|
|
}
|
|
|
|
paused_torrents.clear();
|
|
orderQueue();
|
|
}
|
|
else
|
|
{
|
|
TQPtrList<TorrentInterface>::const_iterator it = downloads.begin();
|
|
for (; it != downloads.end(); it++)
|
|
{
|
|
TorrentInterface* tc = *it;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
if (s.running)
|
|
{
|
|
paused_torrents.insert(tc);
|
|
stopSafely(tc, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void QueueManager::enqueue(kt::TorrentInterface* tc)
|
|
{
|
|
//if a seeding torrent reached its maximum share ratio or maximum seed time don't enqueue it...
|
|
if (tc->getStats().completed && (tc->overMaxRatio() || tc->overMaxSeedTime()))
|
|
{
|
|
Out(SYS_GEN | LOG_IMPORTANT) << "Torrent has reached max share ratio or max seed time and cannot be started automatically." << endl;
|
|
emit queuingNotPossible(tc);
|
|
return;
|
|
}
|
|
|
|
torrentAdded(tc, false, false);
|
|
}
|
|
|
|
void QueueManager::dequeue(kt::TorrentInterface* tc)
|
|
{
|
|
int tp = tc->getPriority();
|
|
bool completed = tc->getStats().completed;
|
|
TQPtrList<TorrentInterface>::const_iterator it = downloads.begin();
|
|
|
|
while (it != downloads.end())
|
|
{
|
|
TorrentInterface* _tc = *it;
|
|
bool _completed = _tc->getStats().completed;
|
|
|
|
if (tc == _tc || (_completed != completed))
|
|
{
|
|
++it;
|
|
continue;
|
|
}
|
|
|
|
int p = _tc->getPriority();
|
|
|
|
if (p < tp)
|
|
break;
|
|
else
|
|
_tc->setPriority(--p);
|
|
|
|
++it;
|
|
}
|
|
|
|
tc->setPriority(0);
|
|
|
|
orderQueue();
|
|
}
|
|
|
|
void QueueManager::queue(kt::TorrentInterface* tc)
|
|
{
|
|
if (tc->getPriority() == 0)
|
|
enqueue(tc);
|
|
else
|
|
dequeue(tc);
|
|
}
|
|
|
|
void QueueManager::startSafely(kt::TorrentInterface* tc)
|
|
{
|
|
try
|
|
{
|
|
tc->start();
|
|
}
|
|
catch (bt::Error & err)
|
|
{
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
TQString msg =
|
|
i18n("Error starting torrent %1 : %2")
|
|
.arg(s.torrent_name).arg(err.toString());
|
|
|
|
KMessageBox::error(0, msg, i18n("Error"));
|
|
}
|
|
}
|
|
|
|
void QueueManager::stopSafely(kt::TorrentInterface* tc, bool user, WaitJob* wjob)
|
|
{
|
|
try
|
|
{
|
|
tc->stop(user, wjob);
|
|
}
|
|
catch (bt::Error & err)
|
|
{
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
TQString msg =
|
|
i18n("Error stopping torrent %1 : %2")
|
|
.arg(s.torrent_name).arg(err.toString());
|
|
|
|
KMessageBox::error(0, msg, i18n("Error"));
|
|
}
|
|
}
|
|
|
|
void QueueManager::onLowDiskSpace(kt::TorrentInterface* tc, bool toStop)
|
|
{
|
|
if(toStop)
|
|
{
|
|
stop(tc, false);
|
|
}
|
|
|
|
//then emit the signal to inform trayicon to show passive popup
|
|
emit lowDiskSpace(tc, toStop);
|
|
}
|
|
|
|
void QueueManager::torrentStopped(kt::TorrentInterface* tc )
|
|
{
|
|
orderQueue();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
QueuePtrList::QueuePtrList() : TQPtrList<kt::TorrentInterface>()
|
|
{}
|
|
|
|
QueuePtrList::~QueuePtrList()
|
|
{}
|
|
|
|
int QueuePtrList::compareItems(TQPtrCollection::Item item1, TQPtrCollection::Item item2)
|
|
{
|
|
kt::TorrentInterface* tc1 = (kt::TorrentInterface*) item1;
|
|
kt::TorrentInterface* tc2 = (kt::TorrentInterface*) item2;
|
|
|
|
if (tc1->getPriority() == tc2->getPriority())
|
|
return 0;
|
|
|
|
if (tc1->getPriority() == 0 && tc2->getPriority() != 0)
|
|
return 1;
|
|
else if (tc1->getPriority() != 0 && tc2->getPriority() == 0)
|
|
return -1;
|
|
|
|
return tc1->getPriority() > tc2->getPriority() ? -1 : 1;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
#include "queuemanager.moc"
|