mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 11:22:55 +00:00
293 lines
7.7 KiB
C++
293 lines
7.7 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2007 by Joris Guisson and Ivan Vasic *
|
|
* 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 "chunkdownloadmodel.h"
|
|
|
|
#include <klocale.h>
|
|
#include <interfaces/torrentinterface.h>
|
|
#include <interfaces/torrentfileinterface.h>
|
|
#include <interfaces/chunkdownloadinterface.h>
|
|
#include <util/functions.h>
|
|
|
|
using namespace bt;
|
|
|
|
namespace kt
|
|
{
|
|
|
|
ChunkDownloadModel::Item::Item(ChunkDownloadInterface* cd,const QString & files) : cd(cd),files(files)
|
|
{
|
|
cd->getStats(stats);
|
|
}
|
|
|
|
bool ChunkDownloadModel::Item::changed(int col,bool & modified) const
|
|
{
|
|
ChunkDownloadInterface::Stats s;
|
|
cd->getStats(s);
|
|
bool ret = false;
|
|
switch (col)
|
|
{
|
|
case 1: ret = s.pieces_downloaded != stats.pieces_downloaded; break;
|
|
case 2: ret = s.current_peer_id != stats.current_peer_id; break;
|
|
case 3: ret = s.download_speed != stats.download_speed; break;
|
|
default: break;
|
|
}
|
|
|
|
modified = s.pieces_downloaded != stats.pieces_downloaded ||
|
|
s.download_speed != stats.download_speed ||
|
|
s.current_peer_id != stats.current_peer_id;
|
|
|
|
stats = s;
|
|
return ret;
|
|
}
|
|
|
|
QVariant ChunkDownloadModel::Item::data(int col) const
|
|
{
|
|
switch (col)
|
|
{
|
|
case 0: return stats.chunk_index;
|
|
case 1: return QString("%1 / %2").arg(stats.pieces_downloaded).arg(stats.total_pieces);
|
|
case 2: return stats.current_peer_id;
|
|
case 3: return BytesPerSecToString(stats.download_speed);
|
|
case 4: return files;
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
bool ChunkDownloadModel::Item::lessThan(int col,const Item* other) const
|
|
{
|
|
switch (col)
|
|
{
|
|
case 0: return stats.chunk_index < other->stats.chunk_index;
|
|
case 1: return stats.pieces_downloaded < other->stats.pieces_downloaded;
|
|
case 2: return stats.current_peer_id < other->stats.current_peer_id;
|
|
case 3: return stats.download_speed < other->stats.download_speed;
|
|
case 4: return files < other->files;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
ChunkDownloadModel::ChunkDownloadModel ( QObject* parent )
|
|
: QAbstractTableModel(parent),tc(0)
|
|
{
|
|
sort_column = 0;
|
|
sort_order = Qt::AscendingOrder;
|
|
}
|
|
|
|
|
|
ChunkDownloadModel::~ChunkDownloadModel()
|
|
{
|
|
qDeleteAll(items);
|
|
}
|
|
|
|
void ChunkDownloadModel::downloadAdded(bt::ChunkDownloadInterface* cd)
|
|
{
|
|
if (!tc)
|
|
return;
|
|
|
|
bt::ChunkDownloadInterface::Stats stats;
|
|
cd->getStats(stats);
|
|
QString files;
|
|
int n = 0;
|
|
if (tc->getStats().multi_file_torrent)
|
|
{
|
|
for (Uint32 i = 0;i < tc->getNumFiles();++i)
|
|
{
|
|
const bt::TorrentFileInterface & tf = tc->getTorrentFile(i);
|
|
if (stats.chunk_index >= tf.getFirstChunk() && stats.chunk_index <= tf.getLastChunk())
|
|
{
|
|
if (n > 0)
|
|
files += '\n';
|
|
|
|
files += tf.getPath();
|
|
n++;
|
|
}
|
|
else if (stats.chunk_index < tf.getFirstChunk())
|
|
break;
|
|
}
|
|
}
|
|
|
|
Item* nitem = new Item(cd,files);
|
|
items.append(nitem);
|
|
insertRow(items.count() - 1);
|
|
sort(sort_column,sort_order);
|
|
}
|
|
|
|
void ChunkDownloadModel::downloadRemoved(bt::ChunkDownloadInterface* cd)
|
|
{
|
|
int idx = 0;
|
|
for (QList<Item*>::iterator i = items.begin();i != items.end();i++)
|
|
{
|
|
const Item* item = *i;
|
|
if (item->cd == cd)
|
|
{
|
|
items.erase(i);
|
|
delete item;
|
|
removeRow(idx);
|
|
break;
|
|
}
|
|
idx++;
|
|
}
|
|
}
|
|
|
|
void ChunkDownloadModel::changeTC(bt::TorrentInterface* tc)
|
|
{
|
|
qDeleteAll(items);
|
|
items.clear();
|
|
this->tc = tc;
|
|
reset();
|
|
}
|
|
|
|
void ChunkDownloadModel::clear()
|
|
{
|
|
qDeleteAll(items);
|
|
items.clear();
|
|
reset();
|
|
}
|
|
|
|
void ChunkDownloadModel::update()
|
|
{
|
|
bool resort = false;
|
|
Uint32 idx=0;
|
|
foreach (Item* i,items)
|
|
{
|
|
bool modified = false;
|
|
if (i->changed(sort_column,modified))
|
|
resort = true;
|
|
|
|
if (modified && !resort)
|
|
emit dataChanged(index(idx,1),index(idx,3));
|
|
idx++;
|
|
}
|
|
|
|
if (resort)
|
|
sort(sort_column,sort_order);
|
|
}
|
|
|
|
int ChunkDownloadModel::rowCount(const QModelIndex & parent) const
|
|
{
|
|
if (parent.isValid())
|
|
return 0;
|
|
else
|
|
return items.count();
|
|
}
|
|
|
|
int ChunkDownloadModel::columnCount(const QModelIndex & parent) const
|
|
{
|
|
if (parent.isValid())
|
|
return 0;
|
|
else
|
|
return 5;
|
|
}
|
|
|
|
QVariant ChunkDownloadModel::headerData(int section,Qt::Orientation orientation,int role) const
|
|
{
|
|
if (orientation != Qt::Horizontal)
|
|
return QVariant();
|
|
|
|
if (role == Qt::DisplayRole)
|
|
{
|
|
switch (section)
|
|
{
|
|
case 0: return i18n("Chunk");
|
|
case 1: return i18n("Progress");
|
|
case 2: return i18n("Peer");
|
|
case 3: return i18n("Down Speed");
|
|
case 4: return i18n("Files");
|
|
default: return QVariant();
|
|
}
|
|
}
|
|
else if (role == Qt::ToolTipRole)
|
|
{
|
|
switch (section)
|
|
{
|
|
case 0: return i18n("Number of the chunk");
|
|
case 1: return i18n("Download progress of the chunk");
|
|
case 2: return i18n("Which peer we are downloading it from");
|
|
case 3: return i18n("Download speed of the chunk");
|
|
case 4: return i18n("Which files the chunk is located in");
|
|
default: return QVariant();
|
|
}
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
QModelIndex ChunkDownloadModel::index(int row,int column,const QModelIndex & parent) const
|
|
{
|
|
if (!hasIndex(row,column,parent) || parent.isValid())
|
|
return QModelIndex();
|
|
else
|
|
return createIndex(row,column,items[row]);
|
|
}
|
|
|
|
QVariant ChunkDownloadModel::data(const QModelIndex & index,int role) const
|
|
{
|
|
if (!index.isValid() || index.row() >= items.count() || index.row() < 0)
|
|
return QVariant();
|
|
|
|
if (role == Qt::DisplayRole)
|
|
return items[index.row()]->data(index.column());
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
bool ChunkDownloadModel::removeRows(int row,int count,const QModelIndex & /*parent*/ )
|
|
{
|
|
beginRemoveRows(QModelIndex(),row,row + count - 1);
|
|
endRemoveRows();
|
|
return true;
|
|
}
|
|
|
|
bool ChunkDownloadModel::insertRows(int row,int count,const QModelIndex & /*parent*/ )
|
|
{
|
|
beginInsertRows(QModelIndex(),row,row + count - 1);
|
|
endInsertRows();
|
|
return true;
|
|
}
|
|
|
|
class ChunkDownloadModelItemCmp
|
|
{
|
|
public:
|
|
ChunkDownloadModelItemCmp(int col,Qt::SortOrder order) : col(col),order(order)
|
|
{}
|
|
|
|
bool operator()(ChunkDownloadModel::Item* a,ChunkDownloadModel::Item* b)
|
|
{
|
|
if (order == Qt::AscendingOrder)
|
|
return a->lessThan(col,b);
|
|
else
|
|
return !a->lessThan(col,b);
|
|
}
|
|
|
|
int col;
|
|
Qt::SortOrder order;
|
|
};
|
|
|
|
void ChunkDownloadModel::sort(int col, Qt::SortOrder order)
|
|
{
|
|
sort_column = col;
|
|
sort_order = order;
|
|
emit layoutAboutToBeChanged();
|
|
qStableSort(items.begin(),items.end(),ChunkDownloadModelItemCmp(col,order));
|
|
emit layoutChanged();
|
|
}
|
|
}
|