(trunk qt) copy some of the ideas from the gtk inspector rewrite

This commit is contained in:
Charles Kerr 2009-04-26 15:41:04 +00:00
parent a284303dac
commit 71060402ab
1 changed files with 295 additions and 104 deletions

View File

@ -95,24 +95,24 @@ class PeerItem: public QTreeWidgetItem
}
void setPeer( const Peer& p ) {
peer = p;
int quads[4];
if( sscanf( p.address.toUtf8().constData(), "%d.%d.%d.%d", quads+0, quads+1, quads+2, quads+3 ) == 4 )
collatedAddress.sprintf( "%03d.%03d.%03d.%03d", quads[0], quads[1], quads[2], quads[3] );
int q[4];
if( sscanf( p.address.toUtf8().constData(), "%d.%d.%d.%d", q+0, q+1, q+2, q+3 ) == 4 )
collatedAddress.sprintf( "%03d.%03d.%03d.%03d", q[0], q[1], q[2], q[3] );
else
collatedAddress = p.address;
}
virtual bool operator< ( const QTreeWidgetItem & other ) const {
const PeerItem * that = dynamic_cast<const PeerItem*>(&other);
const PeerItem * i = dynamic_cast<const PeerItem*>(&other);
QTreeWidget * tw( treeWidget( ) );
const int column = tw ? tw->sortColumn() : 0;
switch( column ) {
case COL_UP: return peer.rateToPeer < that->peer.rateToPeer;
case COL_DOWN: return peer.rateToClient < that->peer.rateToClient;
case COL_PERCENT: return peer.progress < that->peer.progress;
case COL_STATUS: return status < that->status;
case COL_ADDRESS: return collatedAddress < that->collatedAddress;
case COL_CLIENT: return peer.clientName < that->peer.clientName;
default: /*COL_LOCK*/ return peer.isEncrypted && !that->peer.isEncrypted;
case COL_UP: return peer.rateToPeer < i->peer.rateToPeer;
case COL_DOWN: return peer.rateToClient < i->peer.rateToClient;
case COL_PERCENT: return peer.progress < i->peer.progress;
case COL_STATUS: return status < i->status;
case COL_CLIENT: return peer.clientName < i->peer.clientName;
case COL_LOCK: return peer.isEncrypted && !i->peer.isEncrypted;
default: return collatedAddress < i->collatedAddress;
}
}
};
@ -148,10 +148,10 @@ Details :: Details( Session& session, TorrentModel& model, QWidget * parent ):
layout->addWidget( t );
QDialogButtonBox * buttons = new QDialogButtonBox( QDialogButtonBox::Close, Qt::Horizontal, this );
connect( buttons, SIGNAL(rejected()), this, SLOT(deleteLater()) ); // "close" triggers rejected
connect( buttons, SIGNAL(rejected()), this, SLOT(deleteLater()));
layout->addWidget( buttons );
connect( &myTimer, SIGNAL(timeout()), this, SLOT(onTimer()) );
connect( &myTimer, SIGNAL(timeout()), this, SLOT(onTimer()));
onTimer( );
myTimer.setSingleShot( false );
@ -220,10 +220,11 @@ Details :: refresh( )
const bool single = n == 1;
const QString blank;
const QFontMetrics fm( fontMetrics( ) );
QSet<const Torrent*> torrents;
const Torrent * tor;
QSet<QString> strings;
QList<const Torrent*> torrents;
QString string;
const QString none = tr( "None" );
const QString mixed = tr( "Mixed" );
const QString unknown = tr( "Unknown" );
// build a list of torrents
foreach( int id, myIds ) {
@ -238,11 +239,15 @@ Details :: refresh( )
// myStateLabel
if( torrents.empty( ) )
string = tr( "None" );
string = none;
else {
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->activityString( ) );
string = strings.size()==1 ? *strings.begin() : blank;
string = torrents[0]->activityString( );
foreach( const Torrent* t, torrents ) {
if( string != t->activityString( ) ) {
string = mixed;
break;
}
}
}
myStateLabel->setText( string );
@ -252,9 +257,9 @@ Details :: refresh( )
else {
double sizeWhenDone = 0;
double leftUntilDone = 0;
foreach( tor, torrents ) {
sizeWhenDone += tor->sizeWhenDone( );
leftUntilDone += tor->leftUntilDone( );
foreach( const Torrent * t, torrents ) {
sizeWhenDone += t->sizeWhenDone( );
leftUntilDone += t->leftUntilDone( );
}
string = locale.toString( 100.0*((sizeWhenDone-leftUntilDone)/sizeWhenDone), 'f', 2 );
}
@ -264,114 +269,200 @@ Details :: refresh( )
int64_t haveTotal = 0;
int64_t haveVerified = 0;
int64_t verifiedPieces = 0;
foreach( tor, torrents ) {
haveTotal += tor->haveTotal( );
haveVerified += tor->haveVerified( );
verifiedPieces += tor->haveVerified( ) / tor->pieceSize( );
foreach( const Torrent * t, torrents ) {
haveTotal += t->haveTotal( );
const uint64_t v = t->haveVerified( );
haveVerified += v;
verifiedPieces += v / t->pieceSize( );
}
myHaveLabel->setText( tr( "%1 (%2 verified in %L3 pieces)" )
.arg( Utils::sizeToString( haveTotal ) )
.arg( Utils::sizeToString( haveVerified ) )
.arg( verifiedPieces ) );
int64_t num = 0;
foreach( tor, torrents ) num += tor->downloadedEver( );
myDownloadedLabel->setText( Utils::sizeToString( num ) );
int64_t sum = 0;
foreach( const Torrent * t, torrents ) sum += t->downloadedEver( );
myDownloadedLabel->setText( Utils::sizeToString( sum ) );
num = 0;
foreach( tor, torrents ) num += tor->uploadedEver( );
myUploadedLabel->setText( Utils::sizeToString( num ) );
sum = 0;
foreach( const Torrent * t, torrents ) sum += t->uploadedEver( );
myUploadedLabel->setText( Utils::sizeToString( sum ) );
num = 0;
foreach( tor, torrents ) num += tor->failedEver( );
myFailedLabel->setText( Utils::sizeToString( num ) );
sum = 0;
foreach( const Torrent *t, torrents ) sum += t->failedEver( );
myFailedLabel->setText( Utils::sizeToString( sum ) );
double d = 0;
foreach( tor, torrents ) d += tor->ratio( );
foreach( const Torrent *t, torrents ) d += t->ratio( );
myRatioLabel->setText( Utils :: ratioToString( d / n ) );
Speed speed;
foreach( tor, torrents ) speed += tor->swarmSpeed( );
foreach( const Torrent *t, torrents ) speed += t->swarmSpeed( );
mySwarmSpeedLabel->setText( Utils::speedToString( speed ) );
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->dateAdded().toString() );
string = strings.size()==1 ? *strings.begin() : blank;
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->dateAdded().toString();
foreach( const Torrent * t, torrents ) {
if( string != t->dateAdded().toString() ) {
string = mixed;
break;
}
}
}
myAddedDateLabel->setText( string );
strings.clear( );
foreach( tor, torrents ) {
QDateTime dt = tor->lastActivity( );
strings.insert( dt.isNull() ? tr("Never") : dt.toString() );
}
string = strings.size()==1 ? *strings.begin() : blank;
myActivityLabel->setText( string );
if( torrents.empty( ) )
string = tr( "None" );
string = none;
else {
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->getError( ) );
string = strings.size()==1 ? *strings.begin() : blank;
QDateTime latest = torrents[0]->lastActivity( );
foreach( const Torrent * t, torrents ) {
const QDateTime dt = t->lastActivity( );
if( latest < dt )
latest = dt;
}
string = latest.toString( );
}
myActivityLabel->setText( string );
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->getError( );
foreach( const Torrent * t, torrents ) {
if( string != t->getError( ) ) {
string = mixed;
break;
}
}
}
myErrorLabel->setText( string );
///
/// information tab
///
// myPiecesLabel
int64_t pieceCount = 0;
int64_t pieceSize = 0;
foreach( tor, torrents ) {
pieceCount += tor->pieceCount( );
pieceSize += tor->pieceSize( );
if( torrents.empty( ) )
string = none;
else {
int64_t pieceCount = 0;
uint64_t baseSize = torrents[0]->pieceSize( );
foreach( const Torrent * t, torrents ) {
pieceCount += t->pieceCount( );
if( baseSize != t->pieceSize( ) )
baseSize = 0;
}
if( !baseSize ) // mixed piece size
string = tr( "%L1 Pieces" ).arg( pieceCount );
else
string = tr( "%L1 Pieces @ %2" ).arg( pieceCount )
.arg( Utils::sizeToString( baseSize ) );
}
myPiecesLabel->setText( tr( "%L1 Pieces @ %2" ).arg( pieceCount )
.arg( Utils::sizeToString( pieceSize ) ) );
myPiecesLabel->setText( string );
// myHashLabel
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->hashString( ) );
string = strings.size()==1 ? *strings.begin() : blank;
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->hashString( );
foreach( const Torrent * t, torrents ) {
if( string != t->hashString( ) ) {
string = mixed;
break;
}
}
}
myHashLabel->setText( string );
// myPrivacyLabel
strings.clear( );
foreach( tor, torrents )
strings.insert( tor->isPrivate( ) ? tr( "Private to this tracker -- PEX disabled" )
: tr( "Public torrent" ) );
string = strings.size()==1 ? *strings.begin() : blank;
if( torrents.empty( ) )
string = none;
else {
bool b = torrents[0]->isPrivate( );
string = b ? tr( "Private to this tracker -- PEX disabled" )
: tr( "Public torrent" );
foreach( const Torrent * t, torrents ) {
if( b != t->isPrivate( ) ) {
string = mixed;
break;
}
}
}
myPrivacyLabel->setText( string );
// myCommentBrowser
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->comment( ) );
string = strings.size()==1 ? *strings.begin() : blank;
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->comment( );
foreach( const Torrent * t, torrents ) {
if( string != t->comment( ) ) {
string = mixed;
break;
}
}
}
myCommentBrowser->setText( string );
// myCreatorLabel
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->creator().isEmpty() ? tr( "Unknown" ) : tor->creator() );
string = strings.size()==1 ? *strings.begin() : blank;
myCreatorLabel->setText( string );
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->creator( );
foreach( const Torrent * t, torrents ) {
if( string != t->creator( ) ) {
string = mixed;
break;
}
}
}
myCreatorLabel->setText( string.isEmpty() ? unknown : string );
// myDateCreatedLabel
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->dateCreated().toString() );
string = strings.size()==1 ? *strings.begin() : blank;
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->dateCreated().toString();
foreach( const Torrent * t, torrents ) {
if( string != t->dateCreated().toString() ) {
string = mixed;
break;
}
}
}
myDateCreatedLabel->setText( string );
// myDestinationLabel
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->getPath( ) );
string = strings.size()==1 ? *strings.begin() : blank;
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->getPath( );
foreach( const Torrent * t, torrents ) {
if( string != t->getPath( ) ) {
string = mixed;
break;
}
}
}
myDestinationLabel->setText( string );
// myTorrentFileLabel
strings.clear( );
foreach( tor, torrents ) strings.insert( tor->torrentFile( ) );
string = strings.size()==1 ? *strings.begin() : blank;
if( torrents.empty( ) )
string = none;
else {
string = torrents[0]->torrentFile( );
foreach( const Torrent * t, torrents ) {
if( string != t->torrentFile( ) ) {
string = mixed;
break;
}
}
}
myTorrentFileLabel->setText( string );
///
@ -382,6 +473,7 @@ Details :: refresh( )
{
int i;
const Torrent * baseline = *torrents.begin();
const Torrent * tor;
bool uniform;
bool baselineFlag;
int baselineInt;
@ -452,19 +544,122 @@ Details :: refresh( )
}
// tracker tab
//
const time_t now( time( 0 ) );
myScrapeTimePrevLabel->setText( tor ? tor->lastScrapeTime().toString() : blank );
myScrapeResponseLabel->setText( tor ? tor->scrapeResponse() : blank );
myScrapeTimeNextLabel->setText( Utils :: timeToString( tor ? tor->nextScrapeTime().toTime_t() - now : 0 ) );
myAnnounceTimePrevLabel->setText( tor ? tor->lastScrapeTime().toString() : blank );
myAnnounceTimeNextLabel->setText( Utils :: timeToString( tor ? tor->nextAnnounceTime().toTime_t() - now : 0 ) );
myAnnounceManualLabel->setText( Utils :: timeToString( tor ? tor->manualAnnounceTime().toTime_t() - now : 0 ) );
myAnnounceResponseLabel->setText( tor ? tor->announceResponse( ) : blank );
// 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 );
// 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
strings.clear( );
foreach( tor, torrents ) strings.insert( QUrl(tor->announceUrl()).host() );
string = strings.size()==1 ? *strings.begin() : blank;
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;
}
}
}
myTrackerLabel->setText( string );
///
@ -472,19 +667,19 @@ Details :: refresh( )
///
i = 0;
foreach( tor, torrents ) i += tor->seeders( );
foreach( const Torrent * t, torrents ) i += t->seeders( );
mySeedersLabel->setText( locale.toString( i ) );
i = 0;
foreach( tor, torrents ) i += tor->leechers( );
foreach( const Torrent * t, torrents ) i += t->leechers( );
myLeechersLabel->setText( locale.toString( i ) );
i = 0;
foreach( tor, torrents ) i += tor->timesCompleted( );
foreach( const Torrent * t, torrents ) i += t->timesCompleted( );
myTimesCompletedLabel->setText( locale.toString( i ) );
PeerList peers;
foreach( tor, torrents ) peers << tor->peers( );
foreach( const Torrent * t, torrents ) peers << t->peers( );
QMap<QString,QTreeWidgetItem*> peers2;
QList<QTreeWidgetItem*> newItems;
static const QIcon myEncryptionIcon( ":/icons/encrypted.png" );
@ -555,12 +750,10 @@ Details :: refresh( )
}
myPeers = peers2;
if( single ) {
tor = *torrents.begin();
myFileTreeView->update( tor->files( ) );
} else {
if( single )
myFileTreeView->update( torrents[0]->files( ) );
else
myFileTreeView->clear( );
}
myHavePendingRefresh = false;
foreach( QWidget * w, myWidgets )
@ -611,7 +804,6 @@ Details :: createActivityTab( )
void
Details :: onHonorsSessionLimitsToggled( bool val )
{
std::cerr << " honorsSessionLimits clicked to " << val << std::endl;
mySession.torrentSet( myIds, "honorsSessionLimits", val );
}
void
@ -860,7 +1052,6 @@ Details :: createPeersTab( )
myPeerTree->setColumnWidth( COL_ADDRESS, size.width( ) );
size = m.size( 0, "Some BitTorrent Client" );
myPeerTree->setColumnWidth( COL_CLIENT, size.width( ) );
//myPeerTree->sortItems( myTorrent.isDone() ? COL_UP : COL_DOWN, Qt::DescendingOrder );
myPeerTree->setAlternatingRowColors( true );
QHBoxLayout * h = new QHBoxLayout;