24 #include <kstandarddirs.h> 
   25 #include <interfaces/torrentinterface.h> 
   26 #include <util/functions.h> 
   36     PeerViewModel::Item::Item(bt::PeerInterface* peer) : peer(peer)
 
   38         stats = peer->getStats();
 
   41             yes = KIcon(
"dialog-ok");
 
   42             no = KIcon(
"dialog-cancel");
 
   73         const PeerInterface::Stats & s = peer->getStats();
 
   79                 ret = s.download_rate != stats.download_rate;
 
   82                 ret = s.upload_rate != stats.upload_rate;
 
   85                 ret = s.choked != stats.choked;
 
   88                 ret = s.snubbed != stats.snubbed;
 
   91                 ret = s.perc_of_file != stats.perc_of_file;
 
   94                 ret = s.aca_score != stats.aca_score;
 
   97                 ret = s.has_upload_slot != stats.has_upload_slot;
 
  100                 ret = (s.num_down_requests != stats.num_down_requests || s.num_up_requests != stats.num_up_requests);
 
  103                 ret = s.bytes_downloaded != stats.bytes_downloaded;
 
  106                 ret = s.bytes_uploaded != stats.bytes_uploaded;
 
  109                 ret = s.interested != stats.interested;
 
  112                 ret = s.am_interested != stats.am_interested;
 
  119         modified = s.download_rate != stats.download_rate || 
 
  120                 s.upload_rate != stats.upload_rate || 
 
  121                 s.choked != stats.choked || 
 
  122                 s.snubbed != stats.snubbed || 
 
  123                 s.perc_of_file != stats.perc_of_file || 
 
  124                 s.aca_score != stats.aca_score || 
 
  125                 s.has_upload_slot != stats.has_upload_slot || 
 
  126                 s.num_down_requests != stats.num_down_requests || 
 
  127                 s.num_up_requests != stats.num_up_requests || 
 
  128                 s.bytes_downloaded != stats.bytes_downloaded || 
 
  129                 s.bytes_uploaded != stats.bytes_uploaded ||
 
  130                 s.interested != stats.interested ||
 
  131                 s.am_interested != stats.am_interested;
 
  140             case 0: 
return stats.ip_address;
 
  141             case 1: 
return stats.client;
 
  143                 if (stats.download_rate >= 103)
 
  144                     return BytesPerSecToString(stats.download_rate);
 
  148                 if (stats.upload_rate >= 103)
 
  149                     return BytesPerSecToString(stats.upload_rate);
 
  152             case 4: 
return stats.choked ? i18nc(
"Choked", 
"Yes") : i18nc(
"Not choked", 
"No");
 
  153             case 5: 
return stats.snubbed ? i18nc(
"Snubbed", 
"Yes") : i18nc(
"Not snubbed", 
"No");
 
  154             case 6: 
return QString(
"%1 %").arg(KGlobal::locale()->formatNumber(stats.perc_of_file,2));
 
  155             case 7: 
return QVariant();
 
  156             case 8: 
return KGlobal::locale()->formatNumber(stats.aca_score,2);
 
  157             case 9: 
return QVariant(); 
 
  158             case 10: 
return QString(
"%1 / %2").arg(stats.num_down_requests).arg(stats.num_up_requests);
 
  159             case 11: 
return BytesToString(stats.bytes_downloaded);
 
  160             case 12: 
return BytesToString(stats.bytes_uploaded);
 
  161             case 13: 
return stats.interested ? i18nc(
"Interested", 
"Yes") : i18nc(
"Not Interested", 
"No");
 
  162             case 14: 
return stats.am_interested ? i18nc(
"Interesting", 
"Yes") : i18nc(
"Not Interesting", 
"No");
 
  163             default: 
return QVariant();
 
  172             case 0: 
return stats.ip_address < other->
stats.ip_address;
 
  173             case 1: 
return QString::localeAwareCompare(stats.client,other->
stats.client) < 0;
 
  174             case 2: 
return stats.download_rate < other->
stats.download_rate;
 
  175             case 3: 
return stats.upload_rate < other->
stats.upload_rate;
 
  176             case 4: 
return stats.choked < other->
stats.choked;
 
  177             case 5: 
return stats.snubbed < other->
stats.snubbed;
 
  178             case 6: 
return stats.perc_of_file < other->
stats.perc_of_file;
 
  179             case 7: 
return stats.dht_support < other->
stats.dht_support;
 
  180             case 8: 
return stats.aca_score < other->
stats.aca_score;
 
  181             case 9: 
return stats.has_upload_slot < other->
stats.has_upload_slot;
 
  182             case 10: 
return stats.num_down_requests + stats.num_up_requests < 
 
  183                             other->
stats.num_down_requests + other->
stats.num_up_requests;
 
  184             case 11: 
return stats.bytes_downloaded < other->
stats.bytes_downloaded;
 
  185             case 12: 
return stats.bytes_uploaded < other->
stats.bytes_uploaded;
 
  186             case 13: 
return stats.interested < other->
stats.interested;
 
  187             case 14: 
return stats.am_interested < other->
stats.am_interested;
 
  188             default: 
return false;
 
  199                     return KIcon(
"kt-encrypted");
 
  202             case 8: 
return stats.dht_support ? 
yes : 
no;
 
  203             case 10: 
return stats.has_upload_slot ? 
yes : KIcon();
 
  215         sort_order = Qt::AscendingOrder;
 
  226         items.append(
new Item(peer));
 
  227         insertRow(items.count() - 1);
 
  228         sort(sort_column,sort_order);
 
  234         for (QList<Item*>::iterator i = items.begin();i != items.end();i++)
 
  237             if (item->
peer == peer)
 
  259         foreach (
Item* i,items)
 
  261             bool modified = 
false;
 
  262             if (i->
changed(sort_column,modified))
 
  265             if (modified && !resort)
 
  271             sort(sort_column,sort_order);
 
  276         if (!hasIndex(row,column,parent) || parent.isValid())
 
  277             return QModelIndex();
 
  279             return createIndex(row,column,items[row]);
 
  284         if (parent.isValid())
 
  287             return items.count();
 
  292         if (parent.isValid())
 
  300         if (orientation != Qt::Horizontal)
 
  303         if (role == Qt::DisplayRole)
 
  307                 case 0: 
return i18n(
"IP Address");
 
  308                 case 1: 
return i18n(
"Client");
 
  309                 case 2: 
return i18n(
"Down Speed");
 
  310                 case 3: 
return i18n(
"Up Speed");
 
  311                 case 4: 
return i18n(
"Choked");
 
  312                 case 5: 
return i18n(
"Snubbed");
 
  313                 case 6: 
return i18n(
"Availability");
 
  314                 case 7: 
return i18n(
"DHT");
 
  315                 case 8: 
return i18n(
"Score");
 
  316                 case 9: 
return i18n(
"Upload Slot");
 
  317                 case 10: 
return i18n(
"Requests");
 
  318                 case 11: 
return i18n(
"Downloaded");
 
  319                 case 12: 
return i18n(
"Uploaded");
 
  320                 case 13: 
return i18n(
"Interested");
 
  321                 case 14: 
return i18n(
"Interesting");
 
  322                 default: 
return QVariant();
 
  325         else if (role == Qt::ToolTipRole)
 
  329                 case 0: 
return i18n(
"IP address of the peer");
 
  330                 case 1: 
return i18n(
"Which client the peer is using");
 
  331                 case 2: 
return i18n(
"Download speed");
 
  332                 case 3: 
return i18n(
"Upload speed");
 
  333                 case 4: 
return i18n(
"Whether or not the peer has choked us.  If we are choked, the peer will not send us any data.");
 
  334                 case 5: 
return i18n(
"Snubbed means the peer has not sent us any data in the last 2 minutes");
 
  335                 case 6: 
return i18n(
"How much of the torrent's data the peer has");
 
  336                 case 7: 
return i18n(
"Whether or not the peer has DHT enabled");
 
  337                 case 8: 
return i18n(
"The score of the peer. KTorrent uses this to determine who to upload to.");
 
  338                 case 9: 
return i18n(
"Only peers which have an upload slot will get data from us");
 
  339                 case 10: 
return i18n(
"The number of download and upload requests");
 
  340                 case 11: 
return i18n(
"How much data we have downloaded from this peer");
 
  341                 case 12: 
return i18n(
"How much data we have uploaded to this peer");
 
  342                 case 13: 
return i18n(
"Whether the peer is interested in downloading data from us");
 
  343                 case 14: 
return i18n(
"Whether we are interested in downloading from this peer");
 
  344                 default: 
return QVariant();
 
  353         if (!index.isValid() || index.row() >= items.count() || index.row() < 0)
 
  356         Item* item = (
Item*)index.internalPointer();
 
  357         if (role == Qt::DisplayRole)
 
  358             return item->
data(index.column());
 
  359         else if (role == Qt::DecorationRole)
 
  367         beginRemoveRows(QModelIndex(),row,row + count - 1);
 
  374         beginInsertRows(QModelIndex(),row,row + count - 1);
 
  381         if (!index.isValid() || index.row() >= items.count() || index.row() < 0)
 
  384             return ((
Item*)index.internalPointer())->peer;
 
  387     class PeerViewModelItemCmp
 
  390         PeerViewModelItemCmp(
int col,Qt::SortOrder order) : col(col),order(order)
 
  393         bool operator()(PeerViewModel::Item* a,PeerViewModel::Item* b)
 
  395             if (order == Qt::AscendingOrder)
 
  396                 return a->lessThan(col,b);
 
  398                 return !a->lessThan(col,b);
 
  409         emit layoutAboutToBeChanged();
 
  410         qStableSort(items.begin(),items.end(),PeerViewModelItemCmp(col,order));
 
  411         emit layoutChanged();
 
void sort(int col, Qt::SortOrder order)
 
virtual bool removeRows(int row, int count, const QModelIndex &parent)
 
QVariant decoration(int col) const 
 
bool changed(int col, bool &modified) const 
 
void peerRemoved(bt::PeerInterface *peer)
A peer has been removed. 
 
QVariant data(int col) const 
 
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const 
 
PeerViewModel(QObject *parent)
 
virtual QVariant data(const QModelIndex &index, int role) const 
 
void peerAdded(bt::PeerInterface *peer)
A peer has been added. 
 
virtual int rowCount(const QModelIndex &parent) const 
 
void update()
Update the model. 
 
virtual bool insertRows(int row, int count, const QModelIndex &parent)
 
virtual int columnCount(const QModelIndex &parent) const 
 
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const 
 
bt::PeerInterface * indexToPeer(const QModelIndex &idx)
 
bool lessThan(int col, const Item *other) const 
 
bt::PeerInterface::Stats stats