source: trunk/qt/torrent.cc @ 11240

Last change on this file since 11240 was 11240, checked in by charles, 12 years ago

(trunk qt) silence a couple of gcc warnings by adding reasonable defaults at the bottom of a switch statement in case bad tr_ratiolimits or FilterModes? get used in the switch

  • Property svn:keywords set to Date Rev Author Id
File size: 21.3 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9 *
10 * $Id: torrent.cc 11240 2010-09-20 13:46:08Z charles $
11 */
12
13#include <cassert>
14#include <iostream>
15
16#include <QApplication>
17#include <QFileIconProvider>
18#include <QFileInfo>
19#include <QSet>
20#include <QString>
21#include <QStyle>
22#include <QUrl>
23#include <QVariant>
24
25#include <libtransmission/transmission.h>
26#include <libtransmission/bencode.h>
27#include <libtransmission/utils.h> /* tr_new0, tr_strdup */
28
29#include "app.h"
30#include "prefs.h"
31#include "torrent.h"
32#include "utils.h"
33
34
35Torrent :: Torrent( Prefs& prefs, int id ):
36    magnetTorrent( false ),
37    myPrefs( prefs )
38{
39    for( int i=0; i<PROPERTY_COUNT; ++i )
40        assert( myProperties[i].id == i );
41
42    setInt( ID, id );
43    setIcon( MIME_ICON, QApplication::style()->standardIcon( QStyle::SP_FileIcon ) );
44}
45
46Torrent :: ~Torrent( )
47{
48}
49
50/***
51****
52***/
53
54Torrent :: Property
55Torrent :: myProperties[] =
56{
57    { ID, "id", QVariant::Int, INFO, },
58    { UPLOAD_SPEED, "rateUpload", QVariant::ULongLong, STAT } /* Bps */,
59    { DOWNLOAD_SPEED, "rateDownload", QVariant::ULongLong, STAT }, /* Bps */
60    { DOWNLOAD_DIR, "downloadDir", QVariant::String, STAT },
61    { ACTIVITY, "status", QVariant::Int, STAT },
62    { NAME, "name", QVariant::String, INFO },
63    { ERROR, "error", QVariant::Int, STAT },
64    { ERROR_STRING, "errorString", QVariant::String, STAT },
65    { SIZE_WHEN_DONE, "sizeWhenDone", QVariant::ULongLong, STAT },
66    { LEFT_UNTIL_DONE, "leftUntilDone", QVariant::ULongLong, STAT },
67    { HAVE_UNCHECKED, "haveUnchecked", QVariant::ULongLong, STAT },
68    { HAVE_VERIFIED, "haveValid", QVariant::ULongLong, STAT },
69    { DESIRED_AVAILABLE, "desiredAvailable", QVariant::ULongLong, STAT },
70    { TOTAL_SIZE, "totalSize", QVariant::ULongLong, INFO },
71    { PIECE_SIZE, "pieceSize", QVariant::ULongLong, INFO },
72    { PIECE_COUNT, "pieceCount", QVariant::Int, INFO },
73    { PEERS_GETTING_FROM_US, "peersGettingFromUs", QVariant::Int, STAT },
74    { PEERS_SENDING_TO_US, "peersSendingToUs", QVariant::Int, STAT },
75    { WEBSEEDS_SENDING_TO_US, "webseedsSendingToUs", QVariant::Int, STAT_EXTRA },
76    { PERCENT_DONE, "percentDone", QVariant::Double, STAT },
77    { METADATA_PERCENT_DONE, "metadataPercentComplete", QVariant::Double, STAT },
78    { PERCENT_VERIFIED, "recheckProgress", QVariant::Double, STAT },
79    { DATE_ACTIVITY, "activityDate", QVariant::DateTime, STAT_EXTRA },
80    { DATE_ADDED, "addedDate", QVariant::DateTime, INFO },
81    { DATE_STARTED, "startDate", QVariant::DateTime, STAT_EXTRA },
82    { DATE_CREATED, "dateCreated", QVariant::DateTime, INFO },
83    { PEERS_CONNECTED, "peersConnected", QVariant::Int, STAT },
84    { ETA, "eta", QVariant::Int, STAT },
85    { RATIO, "uploadRatio", QVariant::Double, STAT },
86    { DOWNLOADED_EVER, "downloadedEver", QVariant::ULongLong, STAT },
87    { UPLOADED_EVER, "uploadedEver", QVariant::ULongLong, STAT },
88    { FAILED_EVER, "corruptEver", QVariant::ULongLong, STAT_EXTRA },
89    { TRACKERS, "trackers", QVariant::StringList, STAT },
90    { TRACKERSTATS, "trackerStats", TrTypes::TrackerStatsList, STAT_EXTRA },
91    { MIME_ICON, "ccc", QVariant::Icon, DERIVED },
92    { SEED_RATIO_LIMIT, "seedRatioLimit", QVariant::Double, STAT },
93    { SEED_RATIO_MODE, "seedRatioMode", QVariant::Int, STAT },
94    { SEED_IDLE_LIMIT, "seedIdleLimit", QVariant::Int, STAT_EXTRA },
95    { SEED_IDLE_MODE, "seedIdleMode", QVariant::Int, STAT_EXTRA },
96    { DOWN_LIMIT, "downloadLimit", QVariant::Int, STAT_EXTRA }, /* KB/s */
97    { DOWN_LIMITED, "downloadLimited", QVariant::Bool, STAT_EXTRA },
98    { UP_LIMIT, "uploadLimit", QVariant::Int, STAT_EXTRA }, /* KB/s */
99    { UP_LIMITED, "uploadLimited", QVariant::Bool, STAT_EXTRA },
100    { HONORS_SESSION_LIMITS, "honorsSessionLimits", QVariant::Bool, STAT_EXTRA },
101    { PEER_LIMIT, "peer-limit", QVariant::Int, STAT_EXTRA },
102    { HASH_STRING, "hashString", QVariant::String, INFO },
103    { IS_FINISHED, "isFinished", QVariant::Bool, STAT },
104    { IS_PRIVATE, "isPrivate", QVariant::Bool, INFO },
105    { COMMENT, "comment", QVariant::String, INFO },
106    { CREATOR, "creator", QVariant::String, INFO },
107    { MANUAL_ANNOUNCE_TIME, "manualAnnounceTime", QVariant::DateTime, STAT_EXTRA },
108    { PEERS, "peers", TrTypes::PeerList, STAT_EXTRA },
109    { TORRENT_FILE, "torrentFile", QVariant::String, STAT_EXTRA },
110    { BANDWIDTH_PRIORITY, "bandwidthPriority", QVariant::Int, STAT_EXTRA }
111};
112
113Torrent :: KeyList
114Torrent :: buildKeyList( Group group )
115{
116    KeyList keys;
117
118    if( keys.empty( ) )
119        for( int i=0; i<PROPERTY_COUNT; ++i )
120            if( myProperties[i].id==ID || myProperties[i].group==group )
121                keys << myProperties[i].key;
122
123    return keys;
124}
125
126const Torrent :: KeyList&
127Torrent :: getInfoKeys( )
128{
129    static KeyList keys;
130    if( keys.isEmpty( ) )
131        keys << buildKeyList( INFO ) << "files";
132    return keys;
133}
134
135const Torrent :: KeyList&
136Torrent :: getStatKeys( )
137{
138    static KeyList keys( buildKeyList( STAT ) );
139    return keys;
140}
141
142const Torrent :: KeyList&
143Torrent :: getExtraStatKeys( )
144{
145    static KeyList keys;
146    if( keys.isEmpty( ) )
147        keys << buildKeyList( STAT_EXTRA ) << "fileStats";
148    return keys;
149}
150
151
152bool
153Torrent :: setInt( int i, int value )
154{
155    bool changed = false;
156
157    assert( 0<=i && i<PROPERTY_COUNT );
158    assert( myProperties[i].type == QVariant::Int );
159
160    if( myValues[i].isNull() || myValues[i].toInt()!=value )
161    {
162        myValues[i].setValue( value );
163        changed = true;
164    }
165
166    return changed;
167}
168
169bool
170Torrent :: setBool( int i, bool value )
171{
172    bool changed = false;
173
174    assert( 0<=i && i<PROPERTY_COUNT );
175    assert( myProperties[i].type == QVariant::Bool );
176
177    if( myValues[i].isNull() || myValues[i].toBool()!=value )
178    {
179        myValues[i].setValue( value );
180        changed = true;
181    }
182
183    return changed;
184}
185
186bool
187Torrent :: setDouble( int i, double value )
188{
189    bool changed = false;
190
191    assert( 0<=i && i<PROPERTY_COUNT );
192    assert( myProperties[i].type == QVariant::Double );
193
194    if( myValues[i].isNull() || myValues[i].toDouble()!=value )
195    {
196        myValues[i].setValue( value );
197        changed = true;
198    }
199
200    return changed;
201}
202
203bool
204Torrent :: setDateTime( int i, const QDateTime& value )
205{
206    bool changed = false;
207
208    assert( 0<=i && i<PROPERTY_COUNT );
209    assert( myProperties[i].type == QVariant::DateTime );
210
211    if( myValues[i].isNull() || myValues[i].toDateTime()!=value )
212    {
213        myValues[i].setValue( value );
214        changed = true;
215    }
216
217    return changed;
218}
219
220bool
221Torrent :: setSize( int i, qulonglong value )
222{
223    bool changed = false;
224
225    assert( 0<=i && i<PROPERTY_COUNT );
226    assert( myProperties[i].type == QVariant::ULongLong );
227
228    if( myValues[i].isNull() || myValues[i].toULongLong()!=value )
229    {
230        myValues[i].setValue( value );
231        changed = true;
232    }
233
234    return changed;
235}
236
237bool
238Torrent :: setString( int i, const char * value )
239{
240    bool changed = false;
241
242    assert( 0<=i && i<PROPERTY_COUNT );
243    assert( myProperties[i].type == QVariant::String );
244
245    if( myValues[i].isNull() || myValues[i].toString()!=value )
246    {
247        myValues[i].setValue( QString::fromUtf8( value ) );
248        changed = true;
249    }
250
251    return changed;
252}
253
254bool
255Torrent :: setIcon( int i, const QIcon& value )
256{
257    assert( 0<=i && i<PROPERTY_COUNT );
258    assert( myProperties[i].type == QVariant::Icon );
259
260    myValues[i].setValue( value );
261    return true;
262}
263
264int
265Torrent :: getInt( int i ) const
266{
267    assert( 0<=i && i<PROPERTY_COUNT );
268    assert( myProperties[i].type == QVariant::Int );
269
270    return myValues[i].toInt( );
271}
272
273QDateTime
274Torrent :: getDateTime( int i ) const
275{
276    assert( 0<=i && i<PROPERTY_COUNT );
277    assert( myProperties[i].type == QVariant::DateTime );
278
279    return myValues[i].toDateTime( );
280}
281
282bool
283Torrent :: getBool( int i ) const
284{
285    assert( 0<=i && i<PROPERTY_COUNT );
286    assert( myProperties[i].type == QVariant::Bool );
287
288    return myValues[i].toBool( );
289}
290
291qulonglong
292Torrent :: getSize( int i ) const
293{
294    assert( 0<=i && i<PROPERTY_COUNT );
295    assert( myProperties[i].type == QVariant::ULongLong );
296
297    return myValues[i].toULongLong( );
298}
299double
300Torrent :: getDouble( int i ) const
301{
302    assert( 0<=i && i<PROPERTY_COUNT );
303    assert( myProperties[i].type == QVariant::Double );
304
305    return myValues[i].toDouble( );
306}
307QString
308Torrent :: getString( int i ) const
309{
310    assert( 0<=i && i<PROPERTY_COUNT );
311    assert( myProperties[i].type == QVariant::String );
312
313    return myValues[i].toString( );
314}
315QIcon
316Torrent :: getIcon( int i ) const
317{
318    assert( 0<=i && i<PROPERTY_COUNT );
319    assert( myProperties[i].type == QVariant::Icon );
320
321    return myValues[i].value<QIcon>();
322}
323
324/***
325****
326***/
327
328bool
329Torrent :: getSeedRatio( double& ratio ) const
330{
331    bool isLimited;
332
333    switch( seedRatioMode( ) )
334    {
335        case TR_RATIOLIMIT_SINGLE:
336            isLimited = true;
337            ratio = seedRatioLimit( );
338            break;
339
340        case TR_RATIOLIMIT_GLOBAL:
341            if(( isLimited = myPrefs.getBool( Prefs :: RATIO_ENABLED )))
342                ratio = myPrefs.getDouble( Prefs :: RATIO );
343            break;
344
345        default: // TR_RATIOLIMIT_UNLIMITED:
346            isLimited = false;
347            break;
348    }
349
350    return isLimited;
351}
352
353bool
354Torrent :: hasFileSubstring( const QString& substr ) const
355{
356    foreach( const TrFile file, myFiles )
357        if( file.filename.contains( substr, Qt::CaseInsensitive ) )
358            return true;
359    return false;
360}
361
362bool
363Torrent :: hasTrackerSubstring( const QString& substr ) const
364{
365    foreach( QString s, myValues[TRACKERS].toStringList() )
366        if( s.contains( substr, Qt::CaseInsensitive ) )
367            return true;
368    return false;
369}
370
371int
372Torrent :: compareRatio( const Torrent& that ) const
373{
374    const double a = ratio( );
375    const double b = that.ratio( );
376    if( (int)a == TR_RATIO_INF && (int)b == TR_RATIO_INF ) return 0;
377    if( (int)a == TR_RATIO_INF ) return 1;
378    if( (int)b == TR_RATIO_INF ) return -1;
379    if( a < b ) return -1;
380    if( a > b ) return 1;
381    return 0;
382}
383
384int
385Torrent :: compareETA( const Torrent& that ) const
386{
387    const bool haveA( hasETA( ) );
388    const bool haveB( that.hasETA( ) );
389    if( haveA && haveB ) return getETA() - that.getETA();
390    if( haveA ) return 1;
391    if( haveB ) return -1;
392    return 0;
393}
394
395int
396Torrent :: compareTracker( const Torrent& that ) const
397{
398    Q_UNUSED( that );
399
400    // FIXME
401    return 0;
402}
403
404/***
405****
406***/
407
408void
409Torrent :: updateMimeIcon( )
410{
411    const FileList& files( myFiles );
412
413    QIcon icon;
414
415    if( files.size( ) > 1 )
416        icon = QFileIconProvider().icon( QFileIconProvider::Folder );
417    else if( files.size( ) == 1 )
418        icon = Utils :: guessMimeIcon( files.at(0).filename );
419    else
420        icon = QIcon( );
421
422    setIcon( MIME_ICON, icon );
423}
424
425/***
426****
427***/
428
429void
430Torrent :: notifyComplete( ) const
431{
432    // if someone wants to implement notification, here's the hook.
433}
434
435/***
436****
437***/
438
439void
440Torrent :: update( tr_benc * d )
441{
442    bool changed = false;
443
444    for( int  i=0; i<PROPERTY_COUNT; ++i )
445    {
446        tr_benc * child = tr_bencDictFind( d, myProperties[i].key );
447        if( !child )
448            continue;
449
450        switch( myProperties[i].type )
451        {
452            case QVariant :: Int: {
453                int64_t val;
454                if( tr_bencGetInt( child, &val ) )
455                    changed |= setInt( i, val );
456                break;
457            }
458
459            case QVariant :: Bool: {
460                tr_bool val;
461                if( tr_bencGetBool( child, &val ) )
462                    changed |= setBool( i, val );
463                break;
464            }
465
466            case QVariant :: String: {
467                const char * val;
468                if( tr_bencGetStr( child, &val ) )
469                    changed |= setString( i, val );
470                break;
471            }
472
473            case QVariant :: ULongLong: {
474                int64_t val;
475                if( tr_bencGetInt( child, &val ) )
476                    changed |= setSize( i, val );
477                break;
478            }
479
480            case QVariant :: Double: {
481                double val;
482                if( tr_bencGetReal( child, &val ) )
483                    changed |= setDouble( i, val );
484                break;
485            }
486
487            case QVariant :: DateTime: {
488                int64_t val;
489                if( tr_bencGetInt( child, &val ) && val )
490                    changed |= setDateTime( i, QDateTime :: fromTime_t( val ) );
491                break;
492            }
493
494            case QVariant :: StringList:
495            case TrTypes :: PeerList:
496                break;
497
498            default:
499                assert( 0 && "unhandled type" );
500        }
501    }
502
503    tr_benc * files;
504
505    if( tr_bencDictFindList( d, "files", &files ) ) {
506        const char * str;
507        int64_t intVal;
508        int i = 0;
509        myFiles.clear( );
510        tr_benc * child;
511        while(( child = tr_bencListChild( files, i ))) {
512            TrFile file;
513            file.index = i++;
514            if( tr_bencDictFindStr( child, "name", &str ) )
515                file.filename = QString::fromUtf8( str );
516            if( tr_bencDictFindInt( child, "length", &intVal ) )
517                file.size = intVal;
518            myFiles.append( file );
519        }
520        updateMimeIcon( );
521        changed = true;
522    }
523
524    if( tr_bencDictFindList( d, "fileStats", &files ) ) {
525        const int n = tr_bencListSize( files );
526        assert( n == myFiles.size( ) );
527        for( int i=0; i<n; ++i ) {
528            int64_t intVal;
529            tr_bool boolVal;
530            tr_benc * child = tr_bencListChild( files, i );
531            TrFile& file( myFiles[i] );
532            if( tr_bencDictFindInt( child, "bytesCompleted", &intVal ) )
533                file.have = intVal;
534            if( tr_bencDictFindBool( child, "wanted", &boolVal ) )
535                file.wanted = boolVal;
536            if( tr_bencDictFindInt( child, "priority", &intVal ) )
537                file.priority = intVal;
538        }
539        changed = true;
540    }
541
542    tr_benc * trackers;
543    if( tr_bencDictFindList( d, "trackers", &trackers ) ) {
544        const char * str;
545        int i = 0;
546        QStringList list;
547        tr_benc * child;
548        while(( child = tr_bencListChild( trackers, i++ ))) {
549            if( tr_bencDictFindStr( child, "announce", &str )) {
550                dynamic_cast<MyApp*>(QApplication::instance())->favicons.add( QUrl(str) );
551                list.append( QString::fromUtf8( str ) );
552            }
553        }
554        if( myValues[TRACKERS] != list ) {
555            myValues[TRACKERS].setValue( list );
556            changed = true;
557        }
558    }
559
560    tr_benc * trackerStats;
561    if( tr_bencDictFindList( d, "trackerStats", &trackerStats ) ) {
562        tr_benc * child;
563        TrackerStatsList  trackerStatsList;
564        int childNum = 0;
565        while(( child = tr_bencListChild( trackerStats, childNum++ ))) {
566            tr_bool b;
567            int64_t i;
568            const char * str;
569            TrackerStat trackerStat;
570            if( tr_bencDictFindStr( child, "announce", &str ) ) {
571                trackerStat.announce = QString::fromUtf8( str );
572                dynamic_cast<MyApp*>(QApplication::instance())->favicons.add( QUrl( trackerStat.announce ) );
573            }
574            if( tr_bencDictFindInt( child, "announceState", &i ) )
575                trackerStat.announceState = i;
576            if( tr_bencDictFindInt( child, "downloadCount", &i ) )
577                trackerStat.downloadCount = i;
578            if( tr_bencDictFindBool( child, "hasAnnounced", &b ) )
579                trackerStat.hasAnnounced = b;
580            if( tr_bencDictFindBool( child, "hasScraped", &b ) )
581                trackerStat.hasScraped = b;
582            if( tr_bencDictFindStr( child, "host", &str ) )
583                trackerStat.host = QString::fromUtf8( str );
584            if( tr_bencDictFindInt( child, "id", &i ) )
585                trackerStat.id = i;
586            if( tr_bencDictFindBool( child, "isBackup", &b ) )
587                trackerStat.isBackup = b;
588            if( tr_bencDictFindInt( child, "lastAnnouncePeerCount", &i ) )
589                trackerStat.lastAnnouncePeerCount = i;
590            if( tr_bencDictFindStr( child, "lastAnnounceResult", &str ) )
591                trackerStat.lastAnnounceResult = str;
592            if( tr_bencDictFindInt( child, "lastAnnounceStartTime", &i ) )
593                trackerStat.lastAnnounceStartTime = i;
594            if( tr_bencDictFindBool( child, "lastAnnounceSucceeded", &b ) )
595                trackerStat.lastAnnounceSucceeded = b;
596            if( tr_bencDictFindInt( child, "lastAnnounceTime", &i ) )
597                trackerStat.lastAnnounceTime = i;
598            if( tr_bencDictFindBool( child, "lastAnnounceTimedOut", &b ) )
599                trackerStat.lastAnnounceTimedOut = b;
600            if( tr_bencDictFindStr( child, "lastScrapeResult", &str ) )
601                trackerStat.lastScrapeResult = QString::fromUtf8( str );
602            if( tr_bencDictFindInt( child, "lastScrapeStartTime", &i ) )
603                trackerStat.lastScrapeStartTime = i;
604            if( tr_bencDictFindBool( child, "lastScrapeSucceeded", &b ) )
605                trackerStat.lastScrapeSucceeded = b;
606            if( tr_bencDictFindInt( child, "lastScrapeTime", &i ) )
607                trackerStat.lastScrapeTime = i;
608            if( tr_bencDictFindBool( child, "lastScrapeTimedOut", &b ) )
609                trackerStat.lastScrapeTimedOut = b;
610            if( tr_bencDictFindInt( child, "leecherCount", &i ) )
611                trackerStat.leecherCount = i;
612            if( tr_bencDictFindInt( child, "nextAnnounceTime", &i ) )
613                trackerStat.nextAnnounceTime = i;
614            if( tr_bencDictFindInt( child, "nextScrapeTime", &i ) )
615                trackerStat.nextScrapeTime = i;
616            if( tr_bencDictFindInt( child, "scrapeState", &i ) )
617                trackerStat.scrapeState = i;
618            if( tr_bencDictFindInt( child, "seederCount", &i ) )
619                trackerStat.seederCount = i;
620            if( tr_bencDictFindInt( child, "tier", &i ) )
621                trackerStat.tier = i;
622            trackerStatsList << trackerStat;
623        }
624        myValues[TRACKERSTATS].setValue( trackerStatsList );
625        changed = true;
626    }
627
628    tr_benc * peers;
629    if( tr_bencDictFindList( d, "peers", &peers ) ) {
630        tr_benc * child;
631        PeerList peerList;
632        int childNum = 0;
633        while(( child = tr_bencListChild( peers, childNum++ ))) {
634            double d;
635            tr_bool b;
636            int64_t i;
637            const char * str;
638            Peer peer;
639            if( tr_bencDictFindStr( child, "address", &str ) )
640                peer.address = QString::fromUtf8( str );
641            if( tr_bencDictFindStr( child, "clientName", &str ) )
642                peer.clientName = QString::fromUtf8( str );
643            if( tr_bencDictFindBool( child, "clientIsChoked", &b ) )
644                peer.clientIsChoked = b;
645            if( tr_bencDictFindBool( child, "clientIsInterested", &b ) )
646                peer.clientIsInterested = b;
647            if( tr_bencDictFindStr( child, "flagStr", &str ) )
648                peer.flagStr = QString::fromUtf8( str );
649            if( tr_bencDictFindBool( child, "isDownloadingFrom", &b ) )
650                peer.isDownloadingFrom = b;
651            if( tr_bencDictFindBool( child, "isEncrypted", &b ) )
652                peer.isEncrypted = b;
653            if( tr_bencDictFindBool( child, "isIncoming", &b ) )
654                peer.isIncoming = b;
655            if( tr_bencDictFindBool( child, "isUploadingTo", &b ) )
656                peer.isUploadingTo = b;
657            if( tr_bencDictFindBool( child, "peerIsChoked", &b ) )
658                peer.peerIsChoked = b;
659            if( tr_bencDictFindBool( child, "peerIsInterested", &b ) )
660                peer.peerIsInterested = b;
661            if( tr_bencDictFindInt( child, "port", &i ) )
662                peer.port = i;
663            if( tr_bencDictFindReal( child, "progress", &d ) )
664                peer.progress = d;
665            if( tr_bencDictFindInt( child, "rateToClient", &i ) )
666                peer.rateToClient = Speed::fromBps( i );
667            if( tr_bencDictFindInt( child, "rateToPeer", &i ) )
668                peer.rateToPeer = Speed::fromBps( i );
669            peerList << peer;
670        }
671        myValues[PEERS].setValue( peerList );
672        changed = true;
673    }
674
675    if( changed )
676        emit torrentChanged( id( ) );
677}
678
679QString
680Torrent :: activityString( ) const
681{
682    QString str;
683
684    switch( getActivity( ) )
685    {
686        case TR_STATUS_CHECK_WAIT: str = tr( "Waiting to verify local data" ); break;
687        case TR_STATUS_CHECK:      str = tr( "Verifying local data" ); break;
688        case TR_STATUS_DOWNLOAD:   str = tr( "Downloading" ); break;
689        case TR_STATUS_SEED:       str = tr( "Seeding" ); break;
690        case TR_STATUS_STOPPED:    str = isFinished() ? tr( "Finished" ): tr( "Paused" ); break;
691    }
692
693    return str;
694}
695
696QString
697Torrent :: getError( ) const
698{
699    QString s = getString( ERROR_STRING );
700
701    switch( getInt( ERROR ) )
702    {
703        case TR_STAT_TRACKER_WARNING: s = tr( "Tracker gave a warning: %1" ).arg( s ); break;
704        case TR_STAT_TRACKER_ERROR: s = tr( "Tracker gave an error: %1" ).arg( s ); break;
705        case TR_STAT_LOCAL_ERROR: s = tr( "Error: %1" ).arg( s ); break;
706        default: s.clear(); break;
707    }
708
709    return s;
710}
711
712QPixmap
713TrackerStat :: getFavicon( ) const
714{
715    MyApp * myApp = dynamic_cast<MyApp*>(QApplication::instance());
716    return myApp->favicons.find( QUrl( announce ) );
717}
718
Note: See TracBrowser for help on using the repository browser.