transmission/qt/torrent-model.cc

277 lines
6.3 KiB
C++
Raw Normal View History

2009-04-09 18:55:47 +00:00
/*
* This file Copyright (C) Mnemosyne LLC
2009-04-09 18:55:47 +00:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
2009-04-09 18:55:47 +00:00
*
* $Id$
2009-04-09 18:55:47 +00:00
*/
#include <cassert>
#include <iostream>
#include <libtransmission/transmission.h>
#include <libtransmission/variant.h>
2009-04-09 18:55:47 +00:00
#include "torrent-delegate.h"
#include "torrent-model.h"
void
TorrentModel :: clear( )
{
myIdToRow.clear( );
myIdToTorrent.clear( );
foreach( Torrent * tor, myTorrents ) delete tor;
myTorrents.clear( );
reset( );
}
2009-04-09 18:55:47 +00:00
int
TorrentModel :: rowCount( const QModelIndex& parent ) const
{
Q_UNUSED( parent );
return myTorrents.size( );
}
QVariant
TorrentModel :: data (const QModelIndex& index, int role) const
2009-04-09 18:55:47 +00:00
{
QVariant var;
2009-04-09 18:55:47 +00:00
const Torrent * t = myTorrents.value (index.row(), 0);
if (t != 0)
2009-04-09 18:55:47 +00:00
{
switch (role)
{
case Qt::DisplayRole:
var.setValue (t->name());
2009-04-09 18:55:47 +00:00
break;
case Qt::DecorationRole:
var.setValue (t->getMimeTypeIcon());
2009-04-09 18:55:47 +00:00
break;
case TorrentRole:
var = qVariantFromValue(t);
2009-04-09 18:55:47 +00:00
break;
default:
2009-04-09 18:55:47 +00:00
//std::cerr << "Unhandled role: " << role << std::endl;
break;
}
2009-04-09 18:55:47 +00:00
}
return var;
2009-04-09 18:55:47 +00:00
}
/***
****
***/
void
TorrentModel :: addTorrent( Torrent * t )
{
myIdToTorrent.insert( t->id( ), t );
myIdToRow.insert( t->id( ), myTorrents.size( ) );
myTorrents.append( t );
}
TorrentModel :: TorrentModel( Prefs& prefs ):
myPrefs( prefs )
{
}
TorrentModel :: ~TorrentModel( )
{
clear( );
2009-04-09 18:55:47 +00:00
}
/***
****
***/
Torrent*
TorrentModel :: getTorrentFromId( int id )
{
id_to_torrent_t::iterator it( myIdToTorrent.find( id ) );
return it == myIdToTorrent.end() ? 0 : it.value( );
}
const Torrent*
TorrentModel :: getTorrentFromId( int id ) const
{
id_to_torrent_t::const_iterator it( myIdToTorrent.find( id ) );
return it == myIdToTorrent.end() ? 0 : it.value( );
}
/***
****
***/
void
TorrentModel :: onTorrentChanged( int torrentId )
{
const int row( myIdToRow.value( torrentId, -1 ) );
if( row >= 0 ) {
QModelIndex qmi( index( row, 0 ) );
emit dataChanged( qmi, qmi );
2009-04-09 18:55:47 +00:00
}
}
void
TorrentModel :: removeTorrents( tr_variant * torrents )
2009-04-09 18:55:47 +00:00
{
int i = 0;
tr_variant * child;
while(( child = tr_variantListChild( torrents, i++ ))) {
2009-04-09 18:55:47 +00:00
int64_t intVal;
if( tr_variantGetInt( child, &intVal ) )
2009-04-09 18:55:47 +00:00
removeTorrent( intVal );
}
}
void
TorrentModel :: updateTorrents( tr_variant * torrents, bool isCompleteList )
2009-04-09 18:55:47 +00:00
{
QList<Torrent*> newTorrents;
QSet<int> oldIds;
QSet<int> addIds;
2009-04-09 18:55:47 +00:00
QSet<int> newIds;
int updatedCount = 0;
if ( isCompleteList )
oldIds = getIds( );
if( tr_variantIsList( torrents ) )
2009-04-09 18:55:47 +00:00
{
size_t i( 0 );
tr_variant * child;
while(( child = tr_variantListChild( torrents, i++ )))
2009-04-09 18:55:47 +00:00
{
int64_t id;
if( tr_variantDictFindInt( child, TR_KEY_id, &id ) )
2009-04-09 18:55:47 +00:00
{
newIds.insert( id );
Torrent * tor = getTorrentFromId( id );
if( tor == 0 )
{
tor = new Torrent( myPrefs, id );
tor->update( child );
if( !tor->hasMetadata() )
tor->setMagnet( true );
2009-04-09 18:55:47 +00:00
newTorrents.append( tor );
connect( tor, SIGNAL(torrentChanged(int)), this, SLOT(onTorrentChanged(int)));
}
else
{
tor->update( child );
++updatedCount;
if( tor->isMagnet() && tor->hasMetadata() )
{
addIds.insert( tor->id() );
tor->setMagnet( false );
}
2009-04-09 18:55:47 +00:00
}
}
}
}
if( !newTorrents.isEmpty( ) )
{
const int oldCount( rowCount( ) );
const int newCount( oldCount + newTorrents.size( ) );
QSet<int> ids;
beginInsertRows( QModelIndex(), oldCount, newCount - 1 );
foreach( Torrent * tor, newTorrents ) {
addTorrent( tor );
addIds.insert( tor->id( ) );
2009-04-09 18:55:47 +00:00
}
endInsertRows( );
}
if( !addIds.isEmpty() )
emit torrentsAdded( addIds );
2009-04-09 18:55:47 +00:00
if( isCompleteList )
{
QSet<int> removedIds( oldIds );
removedIds -= newIds;
foreach( int id, removedIds )
removeTorrent( id );
}
}
void
TorrentModel :: removeTorrent( int id )
{
const int row = myIdToRow.value( id, -1 );
if( row >= 0 )
{
Torrent * tor = myIdToTorrent.value( id, 0 );
beginRemoveRows( QModelIndex(), row, row );
// make the myIdToRow map consistent with list view/model
for( QMap<int,int>::iterator i = myIdToRow.begin(); i != myIdToRow.end(); ++i )
if( i.value() > row )
--i.value();
2009-04-09 18:55:47 +00:00
myIdToRow.remove( id );
myIdToTorrent.remove( id );
myTorrents.remove( myTorrents.indexOf( tor ) );
endRemoveRows( );
delete tor;
}
}
void
TorrentModel :: getTransferSpeed (Speed & uploadSpeed,
size_t & uploadPeerCount,
Speed & downloadSpeed,
size_t & downloadPeerCount)
2009-04-09 18:55:47 +00:00
{
Speed upSpeed, downSpeed;
size_t upCount=0, downCount=0;
2009-04-09 18:55:47 +00:00
foreach (const Torrent * const tor, myTorrents)
{
upSpeed += tor->uploadSpeed ();
upCount += tor->peersWeAreUploadingTo ();
downSpeed += tor->downloadSpeed ();
downCount += tor->webseedsWeAreDownloadingFrom();
downCount += tor->peersWeAreDownloadingFrom();
}
uploadSpeed = upSpeed;
uploadPeerCount = upCount;
downloadSpeed = downSpeed;
downloadPeerCount = downCount;
2009-04-09 18:55:47 +00:00
}
QSet<int>
TorrentModel :: getIds () const
2009-04-09 18:55:47 +00:00
{
QSet<int> ids;
ids.reserve (myTorrents.size());
foreach (const Torrent * tor, myTorrents)
ids.insert (tor->id());
return ids;
2009-04-09 18:55:47 +00:00
}
bool
TorrentModel :: hasTorrent( const QString& hashString ) const
{
foreach( const Torrent * tor, myTorrents )
if( tor->hashString( ) == hashString )
return true;
return false;
}