(trunk qt) #3098 "tracker display broken in qt client" -- fixed in trunk for 2.00 by Longinus00's patch

This commit is contained in:
Charles Kerr 2010-04-03 14:23:29 +00:00
parent 4ddb13df77
commit d8b4779188
8 changed files with 298 additions and 149 deletions

View File

@ -44,6 +44,7 @@
#include "details.h"
#include "file-tree.h"
#include "hig.h"
#include "prefs.h"
#include "session.h"
#include "squeezelabel.h"
#include "torrent.h"
@ -117,9 +118,10 @@ class PeerItem: public QTreeWidgetItem
****
***/
Details :: Details( Session& session, TorrentModel& model, QWidget * parent ):
Details :: Details( Session& session, Prefs& prefs, TorrentModel& model, QWidget * parent ):
QDialog( parent, Qt::Dialog ),
mySession( session ),
myPrefs( prefs ),
myModel( model ),
myHavePendingRefresh( false )
{
@ -190,6 +192,13 @@ Details :: setIds( const QSet<int>& ids )
****
***/
QString
Details :: timeToStringRounded( int seconds )
{
if( seconds > 60 ) seconds -= ( seconds % 60 );
return Utils::timeToString ( seconds );
}
void
Details :: onTimer( )
{
@ -587,122 +596,142 @@ Details :: refresh( )
// tracker tab
//
QMap<QString,QTreeWidgetItem*> trackers2;
QList<QTreeWidgetItem*> newItems2;
const time_t now( time( 0 ) );
const bool showBackup = myPrefs.getBool( Prefs::SHOW_BACKUP_TRACKERS );
const bool showScrape = myPrefs.getBool( Prefs::SHOW_TRACKER_SCRAPES );
foreach( const Torrent * t, torrents )
{
const QString idStr( QString::number( t->id( ) ) );
TrackerStatsList trackerStats = t->trackerStats( );
// myScrapeTimePrevLabel
if( torrents.empty( ) )
string = none;
else {
QDateTime latest = torrents[0]->lastScrapeTime();
foreach( const Torrent * t, torrents ) {
const QDateTime e = t->lastScrapeTime();
if( latest < e )
latest = e;
}
string = latest.toString();
}
myScrapeTimePrevLabel->setText( string );
foreach( const TrackerStat& trackerStat, trackerStats )
{
const QString key( idStr + ":" + QString::number(trackerStat.id) );
QTreeWidgetItem * item = (QTreeWidgetItem*) myTrackerStats.value( key, 0 );
QString str;
// myScrapeResponseLabel
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->scrapeResponse( );
foreach( const Torrent * t, torrents ) {
if( string != t->scrapeResponse( ) ) {
string = mixed;
break;
}
}
}
myScrapeResponseLabel->setText( string );
// myScrapeTimeNextLabel
if( torrents.empty( ) )
string = none;
else {
QDateTime soonest = torrents[0]->nextScrapeTime( );
foreach( const Torrent * t, torrents ) {
const QDateTime e = t->nextScrapeTime( );
if( soonest > e )
soonest = e;
}
string = Utils::timeToString( soonest.toTime_t() - now );
}
myScrapeTimeNextLabel->setText( string );
// myAnnounceTimePrevLabel
if( torrents.empty( ) )
string = none;
else {
QDateTime latest = torrents[0]->lastAnnounceTime();
foreach( const Torrent * t, torrents ) {
const QDateTime e = t->lastAnnounceTime();
if( latest < e )
latest = e;
}
string = latest.toString();
}
myAnnounceTimePrevLabel->setText( string );
// myAnnounceTimeNextLabel
if( torrents.empty( ) )
string = none;
else {
QDateTime soonest = torrents[0]->nextAnnounceTime( );
foreach( const Torrent * t, torrents ) {
const QDateTime e = t->nextAnnounceTime( );
if( soonest > e )
soonest = e;
}
string = Utils::timeToString( soonest.toTime_t() - now );
}
myAnnounceTimeNextLabel->setText( string );
// myAnnounceManualLabel
if( torrents.empty( ) )
string = none;
else {
QDateTime soonest = torrents[0]->nextAnnounceTime( );
foreach( const Torrent * t, torrents ) {
const QDateTime e = t->nextAnnounceTime( );
if( soonest > e )
soonest = e;
}
if( soonest <= QDateTime::currentDateTime( ) )
string = tr( "Now" );
else
string = Utils::timeToString( soonest.toTime_t() - now );
}
myAnnounceManualLabel->setText( string );
// myAnnounceResponseLabel
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->announceResponse( );
foreach( const Torrent * t, torrents ) {
if( string != t->announceResponse( ) ) {
string = mixed;
break;
}
}
}
myAnnounceResponseLabel->setText( string );
// myTrackerLabel
if( torrents.empty( ) )
string = none;
else {
string = QUrl(torrents[0]->announceUrl()).host();
foreach( const Torrent * t, torrents ) {
if( string != QUrl(t->announceUrl()).host() ) {
string = mixed;
break;
if( item == 0 ) // new tracker
{
item = new QTreeWidgetItem( myTrackerTree );
newItems2 << item;
}
str = trackerStat.host;
if( showBackup || !trackerStat.isBackup)
{
if( trackerStat.hasAnnounced )
{
const QString tstr( timeToStringRounded( now - trackerStat.lastAnnounceTime ) );
str += "\n";
if( trackerStat.lastAnnounceSucceeded )
{
str += tr( "Got a list of %1 peers %2 ago" )
.arg( trackerStat.lastAnnouncePeerCount )
.arg( tstr );
}
else if( trackerStat.lastAnnounceTimedOut )
{
str += tr( "Peer list request timed out %1 ago; will retry" )
.arg( tstr );
}
else
{
str += tr( "Got an error %1 ago" )
.arg( tstr );
}
}
switch( trackerStat.announceState )
{
case TR_TRACKER_INACTIVE:
if( trackerStat.hasAnnounced )
{
str += "\n";
str += tr( "No updates scheduled" );
}
break;
case TR_TRACKER_WAITING:
{
const QString tstr( timeToStringRounded( trackerStat.nextAnnounceTime - now ) );
str += "\n";
str += tr( "Asking for more peers in %1" )
.arg( tstr );
}
break;
case TR_TRACKER_QUEUED:
str += "\n";
str += tr( "Queued to ask for more peers" );
break;
case TR_TRACKER_ACTIVE:
{
const QString tstr( timeToStringRounded( now - trackerStat.lastAnnounceStartTime ) );
str += "\n";
str += tr( "Asking for more peers now... %1" )
.arg( tstr );
}
break;
}
if( showScrape )
{
if( trackerStat.hasScraped )
{
const QString tstr( timeToStringRounded( now - trackerStat.lastScrapeTime ) );
str += "\n";
if( trackerStat.lastScrapeSucceeded )
{
str += tr( "Tracker had %1 seeders and %2 leechers %3 ago" )
.arg( trackerStat.seederCount )
.arg( trackerStat.leecherCount )
.arg( tstr );
}
else
{
str += tr( "Got a scrape error %1 ago" )
.arg( tstr );
}
}
switch( trackerStat.scrapeState )
{
case TR_TRACKER_INACTIVE:
break;
case TR_TRACKER_WAITING:
{
const QString tstr( timeToStringRounded( trackerStat.nextScrapeTime - now ) );
str += "\n";
str += tr( "Asking for peer counts in %1" )
.arg( tstr );
}
break;
case TR_TRACKER_QUEUED:
str += "\n";
str += tr( "Queued to ask for peer counts" );
break;
case TR_TRACKER_ACTIVE:
{
const QString tstr( timeToStringRounded( now - trackerStat.lastScrapeStartTime ) );
str += "\n";
str += tr( "Asking for peer counts now... %1" )
.arg( tstr );
}
break;
}
}
}
item->setText( 0, str );
trackers2.insert( key, item );
}
}
myTrackerLabel->setText( string );
myTrackerTree->addTopLevelItems( newItems2 );
foreach( QString key, myTrackerStats.keys() ) {
if( !trackers2.contains( key ) ) { // tracker has disappeared
QTreeWidgetItem * item = myTrackerStats.value( key, 0 );
myTrackerTree->takeTopLevelItem( myTrackerTree->indexOfTopLevelItem( item ) );
delete item;
}
}
myTrackerStats = trackers2;
///
/// Peers tab
@ -849,6 +878,18 @@ Details :: createInfoTab( )
****
***/
void
Details :: onShowBackupTrackersToggled( bool val )
{
myPrefs.set( Prefs::SHOW_BACKUP_TRACKERS, val );
}
void
Details :: onShowTrackerScrapesToggled( bool val )
{
myPrefs.set( Prefs::SHOW_TRACKER_SCRAPES, val );
}
void
Details :: onHonorsSessionLimitsToggled( bool val )
{
@ -1012,24 +1053,36 @@ Details :: createOptionsTab( )
QWidget *
Details :: createTrackerTab( )
{
HIG * hig = new HIG( );
QCheckBox * c;
QWidget * top = new QWidget;
QVBoxLayout * v = new QVBoxLayout( top );
hig->addSectionTitle( tr( "Scrape" ) );
hig->addRow( tr( "Last scrape at:" ), myScrapeTimePrevLabel = new SqueezeLabel );
hig->addRow( tr( "Tracker responded:" ), myScrapeResponseLabel = new SqueezeLabel );
hig->addRow( tr( "Next scrape in:" ), myScrapeTimeNextLabel = new SqueezeLabel );
hig->addSectionDivider( );
hig->addSectionTitle( tr( "Announce" ) );
hig->addRow( tr( "Tracker:" ), myTrackerLabel = new SqueezeLabel );
hig->addRow( tr( "Last announce at:" ), myAnnounceTimePrevLabel = new SqueezeLabel );
hig->addRow( tr( "Tracker responded:" ), myAnnounceResponseLabel = new SqueezeLabel );
hig->addRow( tr( "Next announce in:" ), myAnnounceTimeNextLabel = new SqueezeLabel );
hig->addRow( tr( "Manual announce allowed in:" ), myAnnounceManualLabel = new SqueezeLabel );
hig->finish( );
v->setSpacing( HIG :: PAD_BIG );
v->setContentsMargins( HIG::PAD_BIG, HIG::PAD_BIG, HIG::PAD_BIG, HIG::PAD_BIG );
myTrackerLabel->setScaledContents( true );
QStringList headers;
headers << tr("Trackers");
myTrackerTree = new QTreeWidget;
myTrackerTree->setHeaderLabels( headers );
myTrackerTree->setSelectionMode( QTreeWidget::NoSelection );
myTrackerTree->setRootIsDecorated( false );
myTrackerTree->setTextElideMode( Qt::ElideRight );
myTrackerTree->setAlternatingRowColors( true );
v->addWidget( myTrackerTree, 1 );
return hig;
c = new QCheckBox( tr( "Show &more details" ) );
c->setChecked( myPrefs.getBool( Prefs::SHOW_TRACKER_SCRAPES ) );
myShowTrackerScrapesCheck = c;
v->addWidget( c, 1 );
connect( c, SIGNAL(clicked(bool)), this, SLOT(onShowTrackerScrapesToggled(bool)) );
c = new QCheckBox( tr( "Show &backup trackers" ) );
c->setChecked( myPrefs.getBool( Prefs::SHOW_BACKUP_TRACKERS ) );
myShowBackupTrackersCheck = c;
v->addWidget( c, 1 );
connect( c, SIGNAL(clicked(bool)), this, SLOT(onShowBackupTrackersToggled(bool)) );
return top;
}
/***

View File

@ -46,7 +46,7 @@ class Details: public QDialog
void onTimer( );
public:
Details( Session&, TorrentModel&, QWidget * parent = 0 );
Details( Session&, Prefs&, TorrentModel&, QWidget * parent = 0 );
~Details( );
void setIds( const QSet<int>& ids );
@ -58,12 +58,14 @@ class Details: public QDialog
QWidget * createOptionsTab( );
private:
QString timeToStringRounded( int seconds );
QString trimToDesiredWidth( const QString& str );
void enableWhenChecked( QCheckBox *, QWidget * );
private:
Session& mySession;
Prefs& myPrefs;
TorrentModel& myModel;
QSet<int> myIds;
QTimer myTimer;
@ -83,6 +85,8 @@ class Details: public QDialog
QCheckBox * mySessionLimitCheck;
QCheckBox * mySingleDownCheck;
QCheckBox * mySingleUpCheck;
QCheckBox * myShowTrackerScrapesCheck;
QCheckBox * myShowBackupTrackersCheck;
QSpinBox * mySingleDownSpin;
QSpinBox * mySingleUpSpin;
QRadioButton * mySeedGlobalRadio;
@ -108,7 +112,9 @@ class Details: public QDialog
QLabel * myAnnounceResponseLabel;
QLabel * myAnnounceManualLabel;
QTreeWidget * myTrackerTree;
QTreeWidget * myPeerTree;
QMap<QString,QTreeWidgetItem*> myTrackerStats;
QMap<QString,QTreeWidgetItem*> myPeers;
QWidgetList myWidgets;
@ -125,6 +131,8 @@ class Details: public QDialog
void onUploadLimitChanged( int );
void onSeedUntilChanged( bool );
void onSeedRatioLimitChanged( double );
void onShowBackupTrackersToggled( bool );
void onShowTrackerScrapesToggled( bool );
void onMaxPeersChanged( int );
void refresh( );
};

View File

@ -638,7 +638,7 @@ void
TrMainWindow :: openProperties( )
{
if( myDetailsDialog == 0 ) {
myDetailsDialog = new Details( mySession, myModel, this );
myDetailsDialog = new Details( mySession, myPrefs, myModel, this );
connect( myDetailsDialog, SIGNAL(destroyed(QObject*)), this, SLOT(onDetailsDestroyed()));
}

View File

@ -42,9 +42,11 @@ Prefs::PrefItem Prefs::myItems[] =
{ SORT_MODE, "sort-mode", TrTypes::SortModeType },
{ SORT_REVERSED, "sort-reversed", QVariant::Bool },
{ COMPACT_VIEW, "compact-view", QVariant::Bool },
{ SHOW_BACKUP_TRACKERS, "show-backup-trackers", QVariant::Bool },
{ FILTERBAR, "show-filterbar", QVariant::Bool },
{ STATUSBAR, "show-statusbar", QVariant::Bool },
{ STATUSBAR_STATS, "statusbar-stats", QVariant::String },
{ SHOW_TRACKER_SCRAPES, "show-tracker-scrapes", QVariant::Bool },
{ TOOLBAR, "show-toolbar" , QVariant::Bool },
{ BLOCKLIST_DATE, "blocklist-date", QVariant::DateTime },
{ BLOCKLIST_UPDATES_ENABLED, "blocklist-updates-enabled" , QVariant::Bool },
@ -239,6 +241,8 @@ Prefs :: initDefaults( tr_benc * d )
tr_bencDictAddInt( d, keyStr(BLOCKLIST_DATE), 0 );
tr_bencDictAddInt( d, keyStr(BLOCKLIST_UPDATES_ENABLED), true );
tr_bencDictAddStr( d, keyStr(OPEN_DIALOG_FOLDER), QDir::home().absolutePath().toLatin1() );
tr_bencDictAddInt( d, keyStr(SHOW_BACKUP_TRACKERS), false );
tr_bencDictAddInt( d, keyStr(SHOW_TRACKER_SCRAPES), false );
tr_bencDictAddInt( d, keyStr(TOOLBAR), true );
tr_bencDictAddInt( d, keyStr(FILTERBAR), true );
tr_bencDictAddInt( d, keyStr(STATUSBAR), true );

View File

@ -45,9 +45,11 @@ class Prefs: public QObject
SORT_MODE,
SORT_REVERSED,
COMPACT_VIEW,
SHOW_BACKUP_TRACKERS,
FILTERBAR,
STATUSBAR,
STATUSBAR_STATS,
SHOW_TRACKER_SCRAPES,
TOOLBAR,
BLOCKLIST_DATE,
BLOCKLIST_UPDATES_ENABLED,

View File

@ -85,6 +85,7 @@ Torrent :: myProperties[] =
{ UPLOADED_EVER, "uploadedEver", QVariant::ULongLong, STAT },
{ FAILED_EVER, "corruptEver", QVariant::ULongLong, STAT_EXTRA },
{ TRACKERS, "trackers", QVariant::StringList, INFO },
{ TRACKERSTATS, "trackerStats", TrTypes::TrackerStatsList, STAT_EXTRA },
{ MIME_ICON, "ccc", QVariant::Icon, DERIVED },
{ SEED_RATIO_LIMIT, "seedRatioLimit", QVariant::Double, STAT_EXTRA },
{ SEED_RATIO_MODE, "seedRatioMode", QVariant::Int, STAT_EXTRA },
@ -98,14 +99,7 @@ Torrent :: myProperties[] =
{ IS_PRIVATE, "isPrivate", QVariant::Bool, INFO },
{ COMMENT, "comment", QVariant::String, INFO },
{ CREATOR, "creator", QVariant::String, INFO },
{ LAST_ANNOUNCE_TIME, "lastAnnounceTime", QVariant::DateTime, STAT_EXTRA },
{ LAST_SCRAPE_TIME, "lastScrapeTime", QVariant::DateTime, STAT_EXTRA },
{ MANUAL_ANNOUNCE_TIME, "manualAnnounceTime", QVariant::DateTime, STAT_EXTRA },
{ NEXT_ANNOUNCE_TIME, "nextAnnounceTime", QVariant::DateTime, STAT_EXTRA },
{ NEXT_SCRAPE_TIME, "nextScrapeTime", QVariant::DateTime, STAT_EXTRA },
{ SCRAPE_RESPONSE, "scrapeResponse", QVariant::String, STAT_EXTRA },
{ ANNOUNCE_RESPONSE, "announceResponse", QVariant::String, STAT_EXTRA },
{ ANNOUNCE_URL, "announceURL", QVariant::String, STAT_EXTRA },
{ PEERS, "peers", TrTypes::PeerList, STAT_EXTRA },
{ TORRENT_FILE, "torrentFile", QVariant::String, STAT_EXTRA },
{ BANDWIDTH_PRIORITY, "bandwidthPriority", QVariant::Int, STAT_EXTRA }
@ -555,6 +549,72 @@ Torrent :: update( tr_benc * d )
}
}
tr_benc * trackerStats;
if( tr_bencDictFindList( d, "trackerStats", &trackerStats ) ) {
tr_benc * child;
TrackerStatsList trackerStatsList;
int childNum = 0;
while(( child = tr_bencListChild( trackerStats, childNum++ ))) {
tr_bool b;
int64_t i;
const char * str;
TrackerStat trackerStat;
if( tr_bencDictFindStr( child, "announce", &str ) )
trackerStat.announce = QString::fromUtf8( str );
if( tr_bencDictFindInt( child, "announceState", &i ) )
trackerStat.announceState = i;
if( tr_bencDictFindInt( child, "downloadCount", &i ) )
trackerStat.downloadCount = i;
if( tr_bencDictFindBool( child, "hasAnnounced", &b ) )
trackerStat.hasAnnounced = b;
if( tr_bencDictFindBool( child, "hasScraped", &b ) )
trackerStat.hasScraped = b;
if( tr_bencDictFindStr( child, "host", &str ) )
trackerStat.host = QString::fromUtf8( str );
if( tr_bencDictFindInt( child, "id", &i ) )
trackerStat.id = i;
if( tr_bencDictFindBool( child, "isBackup", &b ) )
trackerStat.isBackup = b;
if( tr_bencDictFindInt( child, "lastAnnouncePeerCount", &i ) )
trackerStat.lastAnnouncePeerCount = i;
if( tr_bencDictFindInt( child, "lastAnnounceResult", &i ) )
trackerStat.lastAnnounceResult = i;
if( tr_bencDictFindInt( child, "lastAnnounceStartTime", &i ) )
trackerStat.lastAnnounceStartTime = i;
if( tr_bencDictFindBool( child, "lastAnnounceSucceeded", &b ) )
trackerStat.lastAnnounceSucceeded = b;
if( tr_bencDictFindInt( child, "lastAnnounceTime", &i ) )
trackerStat.lastAnnounceTime = i;
if( tr_bencDictFindBool( child, "lastAnnounceTimedOut", &b ) )
trackerStat.lastAnnounceTimedOut = b;
if( tr_bencDictFindStr( child, "lastScrapeResult", &str ) )
trackerStat.lastScrapeResult = QString::fromUtf8( str );
if( tr_bencDictFindInt( child, "lastScrapeStartTime", &i ) )
trackerStat.lastScrapeStartTime = i;
if( tr_bencDictFindBool( child, "lastScrapeSucceeded", &b ) )
trackerStat.lastScrapeSucceeded = b;
if( tr_bencDictFindInt( child, "lastScrapeTime", &i ) )
trackerStat.lastScrapeTime = i;
if( tr_bencDictFindBool( child, "lastScrapeTimedOut", &b ) )
trackerStat.lastScrapeTimedOut = b;
if( tr_bencDictFindInt( child, "leecherCount", &i ) )
trackerStat.leecherCount = i;
if( tr_bencDictFindInt( child, "nextAnnounceTime", &i ) )
trackerStat.nextAnnounceTime = i;
if( tr_bencDictFindInt( child, "nextScrapeTime", &i ) )
trackerStat.nextScrapeTime = i;
if( tr_bencDictFindInt( child, "scrapeState", &i ) )
trackerStat.scrapeState = i;
if( tr_bencDictFindInt( child, "seederCount", &i ) )
trackerStat.seederCount = i;
if( tr_bencDictFindInt( child, "tier", &i ) )
trackerStat.tier = i;
trackerStatsList << trackerStat;
}
myValues[TRACKERSTATS].setValue( trackerStatsList );
changed = true;
}
tr_benc * peers;
if( tr_bencDictFindList( d, "peers", &peers ) ) {
tr_benc * child;

View File

@ -58,6 +58,39 @@ typedef QList<Peer> PeerList;
Q_DECLARE_METATYPE(Peer)
Q_DECLARE_METATYPE(PeerList)
struct TrackerStat
{
QString announce;
int announceState;
int downloadCount;
bool hasAnnounced;
bool hasScraped;
QString host;
int id;
bool isBackup;
int lastAnnouncePeerCount;
int lastAnnounceResult;
int lastAnnounceStartTime;
bool lastAnnounceSucceeded;
int lastAnnounceTime;
bool lastAnnounceTimedOut;
QString lastScrapeResult;
int lastScrapeStartTime;
bool lastScrapeSucceeded;
int lastScrapeTime;
bool lastScrapeTimedOut;
int leecherCount;
int nextAnnounceTime;
int nextScrapeTime;
int scrapeState;
int seederCount;
int tier;
};
typedef QList<TrackerStat> TrackerStatsList;
Q_DECLARE_METATYPE(TrackerStat)
Q_DECLARE_METATYPE(TrackerStatsList)
struct TrFile
{
TrFile(): index(-1), priority(0), wanted(true), size(0), have(0) { }
@ -115,6 +148,7 @@ class Torrent: public QObject
UPLOADED_EVER,
FAILED_EVER,
TRACKERS,
TRACKERSTATS,
MIME_ICON,
SEED_RATIO_LIMIT,
SEED_RATIO_MODE,
@ -128,14 +162,7 @@ class Torrent: public QObject
IS_PRIVATE,
COMMENT,
CREATOR,
LAST_ANNOUNCE_TIME,
LAST_SCRAPE_TIME,
MANUAL_ANNOUNCE_TIME,
NEXT_ANNOUNCE_TIME,
NEXT_SCRAPE_TIME,
SCRAPE_RESPONSE,
ANNOUNCE_RESPONSE,
ANNOUNCE_URL,
PEERS,
TORRENT_FILE,
BANDWIDTH_PRIORITY,
@ -208,9 +235,6 @@ class Torrent: public QObject
QString getPath( ) const { return getString( DOWNLOAD_DIR ); }
QString getError( ) const;
QString hashString( ) const { return getString( HASH_STRING ); }
QString scrapeResponse( ) const { return getString( SCRAPE_RESPONSE ); }
QString announceResponse( ) const { return getString( ANNOUNCE_RESPONSE ); }
QString announceUrl( ) const { return getString( ANNOUNCE_URL ); }
QString torrentFile( ) const { return getString( TORRENT_FILE ); }
bool hasError( ) const { return !getError( ).isEmpty( ); }
bool isDone( ) const { return getSize( LEFT_UNTIL_DONE ) == 0; }
@ -242,11 +266,7 @@ class Torrent: public QObject
QDateTime lastStarted( ) const { return getDateTime( DATE_STARTED ); }
QDateTime dateAdded( ) const { return getDateTime( DATE_ADDED ); }
QDateTime dateCreated( ) const { return getDateTime( DATE_CREATED ); }
QDateTime lastAnnounceTime( ) const { return getDateTime( LAST_ANNOUNCE_TIME ); }
QDateTime lastScrapeTime( ) const { return getDateTime( LAST_SCRAPE_TIME ); }
QDateTime manualAnnounceTime( ) const { return getDateTime( MANUAL_ANNOUNCE_TIME ); }
QDateTime nextAnnounceTime( ) const { return getDateTime( NEXT_ANNOUNCE_TIME ); }
QDateTime nextScrapeTime( ) const { return getDateTime( NEXT_SCRAPE_TIME ); }
bool canManualAnnounce( ) const { return isReadyToTransfer() && (manualAnnounceTime()<=QDateTime::currentDateTime()); }
int peersWeAreDownloadingFrom( ) const { return getInt( PEERS_SENDING_TO_US ) + getInt( WEBSEEDS_SENDING_TO_US ); }
int peersWeAreUploadingTo( ) const { return getInt( PEERS_GETTING_FROM_US ); }
@ -266,6 +286,7 @@ class Torrent: public QObject
int peerLimit( ) const { return getInt( PEER_LIMIT ); }
double seedRatioLimit( ) const { return getDouble( SEED_RATIO_LIMIT ); }
tr_ratiolimit seedRatioMode( ) const { return (tr_ratiolimit) getInt( SEED_RATIO_MODE ); }
TrackerStatsList trackerStats( ) const{ return myValues[TRACKERSTATS].value<TrackerStatsList>(); }
PeerList peers( ) const{ return myValues[PEERS].value<PeerList>(); }
const FileList& files( ) const { return myFiles; }

View File

@ -21,6 +21,7 @@ class TrTypes
enum
{
TrackerStatsList = QVariant::UserType,
PeerList = QVariant::UserType,
FileList,
FilterModeType,