Changeset 11059


Ignore:
Timestamp:
Jul 27, 2010, 7:43:32 PM (12 years ago)
Author:
charles
Message:

(trunk Qt) sync the "trackers" tab with the GTK+ client and more.

Location:
trunk
Files:
4 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/rpc-spec.txt

    r11044 r11059  
    105105   "seedRatioLimit"      | double     torrent-level seeding ratio
    106106   "seedRatioMode"       | number     which ratio to use.  See tr_ratiolimit
    107    "trackerAdd"          | object     (see below)
    108    "trackerEdit"         | object     (see below)
    109    "trackerRemove"       | object     (see below)
     107   "trackerAdd"          | array      strings of URLs to add
     108   "trackerRemove"       | array      strings of URLs to remove
     109   "trackerReplace"      | array      pairs of old/new announce URLs
    110110   "uploadLimit"         | number     maximum upload speed (KBps)
    111111   "uploadLimited"       | boolean    true if "uploadLimit" is honored
    112                          |
    113    ----------------------+---------------------------------+
    114    trackerAdd            | an object containing:           |
    115                          +-----------------------+---------+
    116                          | announce              | string  | announce URL of the tracker
    117                          | tier (optional)       | number  | tier to add the tracker to
    118    ----------------------+---------------------------------+
    119    trackerEdit           | an object containing:           |
    120                          +-----------------------+---------+
    121                          | announce (or id)      | string  | announce URL of the tracker to modify
    122                          | id (or announce)      | number  | trackerId of the tracker to modify (see trackerStats)
    123                          +-----------------------+---------+
    124                          | announce-new          | string  | new announce URL for the tracker
    125                          | tier                  | number  | tier to change the tracker to
    126    ----------------------+---------------------------------+
    127    trackerRemove         | an object containing:           |
    128                          +-----------------------+---------+
    129                          | announce (or id)      | string  | announce URL of the tracker to remove
    130                          | id (or announce)      | number  | trackerId of the tracker to remove (see trackerStats)
    131                          +-----------------------+---------+
    132112
    133113   Just as an empty "ids" value is shorthand for "all ids", using an empty array
  • trunk/libtransmission/rpcimpl.c

    r11044 r11059  
    758758
    759759static tr_bool
    760 findTrackerById( const tr_info * inf,
    761                  uint32_t id,
    762                  int * index )
     760findAnnounceUrl( const tr_tracker_info * t, int n, const char * url, int * pos )
    763761{
    764762    int i;
    765763    tr_bool found = FALSE;
    766764
    767     for( i = 0; i < inf->trackerCount; ++i )
    768     {
    769         const tr_tracker_info * t = &inf->trackers[i];
    770         if( t->id == id )
     765    for( i=0; i<n; ++i )
     766    {
     767        if( !strcmp( t[i].announce, url ) )
    771768        {
    772             if( index ) *index = i;
    773769            found = TRUE;
     770            if( pos ) *pos = i;
    774771            break;
    775772        }
     
    779776}
    780777
    781 static tr_bool
    782 findTrackerByURL( const tr_info * inf,
    783                   const char * url,
    784                   int * index )
     778static int
     779copyTrackers( tr_tracker_info * tgt, const tr_tracker_info * src, int n )
    785780{
    786781    int i;
    787     tr_bool found = FALSE;
    788 
    789     for( i = 0; i < inf->trackerCount; ++i )
    790     {
    791         const tr_tracker_info * t = &inf->trackers[i];
    792         if( !strcmp( t->announce, url ) )
     782    int maxTier = -1;
     783   
     784    for( i=0; i<n; ++i )
     785    {
     786        tgt[i].tier = src[i].tier;
     787        tgt[i].announce = tr_strdup( src[i].announce );
     788        maxTier = MAX( maxTier, src[i].tier );
     789    }
     790
     791    return maxTier;
     792}
     793
     794static void
     795freeTrackers( tr_tracker_info * trackers, int n )
     796{
     797    int i;
     798
     799    for( i=0; i<n; ++i )
     800        tr_free( trackers[i].announce );
     801
     802    tr_free( trackers );
     803}
     804
     805static const char*
     806addTrackerUrls( tr_torrent * tor, tr_benc * urls )
     807{
     808    int i;
     809    int n;
     810    int tier;
     811    tr_benc * val;
     812    tr_tracker_info * trackers;
     813    tr_bool changed = FALSE;
     814    const tr_info * inf = tr_torrentInfo( tor );
     815    const char * errmsg = NULL;
     816
     817    /* make a working copy of the existing announce list */
     818    n = inf->trackerCount;
     819    trackers = tr_new0( tr_tracker_info, n + tr_bencListSize( urls ) );
     820    tier = copyTrackers( trackers, inf->trackers, n );
     821
     822    /* and add the new ones */
     823    i = 0;
     824    while(( val = tr_bencListChild( urls, i++ ) ))
     825    {
     826        const char * announce = NULL;
     827
     828        if(    tr_bencGetStr( val, &announce )
     829            && tr_urlIsValid( announce )
     830            && !findAnnounceUrl( trackers, n, announce, NULL ) )
    793831        {
    794             if( index ) *index = i;
    795             found = TRUE;
    796             break;
    797         }
    798     }
    799 
    800     return found;
    801 }
    802 
    803 static const char*
    804 addTracker( tr_torrent * tor,
    805             tr_benc    * tracker )
     832            trackers[n].tier = ++tier; /* add a new tier */
     833            trackers[n].announce = tr_strdup( announce );
     834            ++n;
     835            changed = TRUE;
     836        }
     837    }
     838
     839    if( !changed )
     840        errmsg = "invalid argument";
     841    else if( !tr_torrentSetAnnounceList( tor, trackers, n ) )
     842        errmsg = "error setting announce list";
     843
     844    freeTrackers( trackers, n );
     845    return errmsg;
     846}
     847
     848static const char*
     849replaceTrackerUrls( tr_torrent * tor, tr_benc * urls )
    806850{
    807851    int i;
    808     int64_t tmp;
    809     tr_bool duplicate = FALSE;
     852    tr_benc * pair[2];
     853    tr_tracker_info * trackers;
     854    tr_bool changed = FALSE;
     855    const tr_info * inf = tr_torrentInfo( tor );
     856    const int n = inf->trackerCount;
    810857    const char * errmsg = NULL;
    811     const char * announce;
     858
     859    /* make a working copy of the existing announce list */
     860    trackers = tr_new0( tr_tracker_info, n );
     861    copyTrackers( trackers, inf->trackers, n );
     862
     863    /* make the substitutions... */
     864    i = 0;
     865    while(((pair[0] = tr_bencListChild(urls,i))) &&
     866          ((pair[1] = tr_bencListChild(urls,i+1))))
     867    {
     868        const char * oldval;
     869        const char * newval;
     870
     871        if(    tr_bencGetStr( pair[0], &oldval )
     872            && tr_bencGetStr( pair[1], &newval )
     873            && strcmp( oldval, newval )
     874            && tr_urlIsValid( newval )
     875            && findAnnounceUrl( trackers, n, oldval, &i ) )
     876        {
     877            tr_free( trackers[i].announce );
     878            trackers[i].announce = tr_strdup( newval );
     879            changed = TRUE;
     880        }
     881
     882        i += 2;
     883    }
     884
     885    if( !changed )
     886        errmsg = "invalid argument";
     887    else if( !tr_torrentSetAnnounceList( tor, trackers, n ) )
     888        errmsg = "error setting announce list";
     889
     890    freeTrackers( trackers, n );
     891    return errmsg;
     892}
     893
     894static const char*
     895removeTrackerUrls( tr_torrent * tor, tr_benc * urls )
     896{
     897    int i;
     898    int n;
     899    tr_benc * val;
     900    tr_tracker_info * trackers;
     901    tr_bool changed = FALSE;
    812902    const tr_info * inf = tr_torrentInfo( tor );
    813 
    814     if( !tr_bencDictFindStr( tracker, "announce", &announce ) )
    815         return "no announce url supplied";
    816 
    817     duplicate = findTrackerByURL( inf, announce, NULL );
    818 
    819     if( !duplicate )
    820     {
    821         int tier, trackerCount;
    822         tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount + 1 );
    823 
    824         if( tr_bencDictFindInt( tracker, "tier", &tmp ) )
    825             tier = (int)tmp;
    826         else
    827             tier = -1;
    828 
    829         for( i = 0; i < inf->trackerCount; ++i )
     903    const char * errmsg = NULL;
     904
     905    /* make a working copy of the existing announce list */
     906    n = inf->trackerCount;
     907    trackers = tr_new0( tr_tracker_info, n );
     908    copyTrackers( trackers, inf->trackers, n );
     909
     910    /* remove the ones specified in the urls list */
     911    i = 0;
     912    while(( val = tr_bencListChild( urls, i++ )))
     913    {
     914        int pos;
     915        const char * url;
     916        if( tr_bencGetStr( val, &url ) && findAnnounceUrl( trackers, n, url, &pos ) )
    830917        {
    831             const tr_tracker_info * t = &inf->trackers[i];
    832             trackers[i].tier = t->tier;
    833             trackers[i].announce = tr_strdup( t->announce );
    834         }
    835         trackers[i].tier = tier < 0 ? trackers[i-1].tier + 1 : tier;
    836         trackers[i].announce = tr_strdup( announce );
    837         trackerCount = inf->trackerCount + 1;
    838 
    839         if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) )
    840             errmsg = "tracker URL was invalid";
    841 
    842         for( i = 0; i < trackerCount; ++i )
    843             tr_free( trackers[i].announce );
    844         tr_free( trackers );
    845     }
    846     else
    847         errmsg = "tracker already exists";
    848 
    849     return errmsg;
    850 }
    851 
    852 static const char*
    853 editTracker( tr_torrent * tor,
    854              tr_benc    * tracker )
    855 {
    856     int trackerIndex;
    857     int64_t tmp;
    858     tr_bool found = FALSE;
    859     const char * errmsg = NULL;
    860     const char * announce;
    861     const tr_info * inf = tr_torrentInfo( tor );
    862 
    863     if( tr_bencDictFindInt( tracker, "id", &tmp ) )
    864         found = findTrackerById( inf, (uint32_t)tmp, &trackerIndex );
    865     else if( tr_bencDictFindStr( tracker, "announce", &announce ) )
    866         found = findTrackerByURL( inf, announce, &trackerIndex );
    867     else
    868         errmsg = "no tracker supplied";
    869 
    870     if( found )
    871     {
    872         int tier;
    873         const char * new;
    874         tr_bool rename = FALSE;
    875         tr_bool move = FALSE;
    876 
    877         if( tr_bencDictFindStr( tracker, "announce-new", &new ) )
    878         {
    879             rename = !findTrackerByURL( inf, new, NULL );
    880             if( !rename )
    881                 errmsg = "tracker already exists";
    882         }
    883         if( tr_bencDictFindInt( tracker, "tier", &tmp ) )
    884         {
    885             tier = (int)tmp;
    886             move = TRUE;
    887         }
    888 
    889         if( ( rename || move ) && !errmsg )
    890         {
    891             int i, trackerCount;
    892             tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount );
    893 
    894             for( i = 0; i < inf->trackerCount; ++i )
    895             {
    896                 const tr_tracker_info * t = &inf->trackers[i];
    897                 if( i != trackerIndex )
    898                 {
    899                     trackers[i].tier = t->tier;
    900                     trackers[i].announce = tr_strdup( t->announce );
    901                 }
    902                 else
    903                 {
    904                     trackers[i].tier = move ? tier : t->tier;
    905                     trackers[i].announce = tr_strdup( rename ? new : t->announce );
    906                 }
    907             }
    908             trackerCount = i;
    909 
    910             if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) )
    911                 errmsg = "error setting announce list";
    912 
    913             for( i = 0; i < trackerCount; ++i )
    914                 tr_free( trackers[i].announce );
    915             tr_free( trackers );
    916         }
    917         else if( !errmsg )
    918             errmsg = "no operation supplied";
    919     }
    920     else
    921         errmsg = "tracker doesn't exists";
    922 
    923     return errmsg;
    924 }
    925 
    926 static const char*
    927 removeTracker( tr_torrent * tor,
    928                tr_benc * tracker  )
    929 {
    930     int trackerIndex;
    931     int64_t tmp;
    932     tr_bool found = FALSE;
    933     const char * errmsg = NULL;
    934     const char * announce;
    935     const tr_info * inf = tr_torrentInfo( tor );
    936 
    937     if( tr_bencDictFindInt( tracker, "id", &tmp ) )
    938         found = findTrackerById( inf, (uint32_t)tmp, &trackerIndex );
    939     else if( tr_bencDictFindStr( tracker, "announce", &announce ) )
    940         found = findTrackerByURL( inf, announce, &trackerIndex );
    941     else
    942         errmsg = "no tracker supplied";
    943 
    944     if( found )
    945     {
    946         int i, j, trackerCount;
    947         tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount - 1 );
    948 
    949         for( i = 0, j = 0; i < inf->trackerCount; ++i )
    950         {
    951             if( i != trackerIndex )
    952             {
    953                 const tr_tracker_info * t = &inf->trackers[i];
    954                 trackers[j].tier = t->tier;
    955                 trackers[j].announce = tr_strdup( t->announce );
    956                 ++j;
    957             }
    958         }
    959         trackerCount = j;
    960 
    961         if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) )
    962             errmsg = "error setting announce list";
    963 
    964         for( i = 0; i < trackerCount; ++i )
    965             tr_free( trackers[i].announce );
    966         tr_free( trackers );
    967     }
    968     else
    969         errmsg = "tracker doesn't exists";
    970 
     918            tr_removeElementFromArray( trackers, pos, sizeof( tr_tracker_info ), n-- );
     919            changed = TRUE;
     920        }
     921    }
     922
     923    if( !changed )
     924        errmsg = "invalid argument";
     925    else if( !tr_torrentSetAnnounceList( tor, trackers, n ) )
     926        errmsg = "error setting announce list";
     927
     928    freeTrackers( trackers, n );
    971929    return errmsg;
    972930}
     
    989947        double       d;
    990948        tr_benc *    files;
    991         tr_benc *    tracker;
     949        tr_benc *    urls;
    992950        tr_bool      boolVal;
    993951        tr_torrent * tor = torrents[i];
     
    1026984        if( tr_bencDictFindInt( args_in, "seedRatioMode", &tmp ) )
    1027985            tr_torrentSetRatioMode( tor, tmp );
    1028         if( !errmsg && tr_bencDictFindDict( args_in, "trackerAdd", &tracker ) )
    1029             errmsg = addTracker( tor, tracker );
    1030         if( !errmsg && tr_bencDictFindDict( args_in, "trackerEdit", &tracker ) )
    1031             errmsg = editTracker( tor, tracker );
    1032         if( !errmsg && tr_bencDictFindDict( args_in, "trackerRemove", &tracker ) )
    1033             errmsg = removeTracker( tor, tracker );
     986        if( !errmsg && tr_bencDictFindList( args_in, "trackerAdd", &urls ) )
     987            errmsg = addTrackerUrls( tor, urls );
     988        if( !errmsg && tr_bencDictFindList( args_in, "trackerRemove", &urls ) )
     989            errmsg = removeTrackerUrls( tor, urls );
     990        if( !errmsg && tr_bencDictFindList( args_in, "trackerReplace", &urls ) )
     991            errmsg = replaceTrackerUrls( tor, urls );
    1034992        notify( session, TR_RPC_TORRENT_CHANGED, tor );
    1035993    }
  • trunk/qt/details.cc

    r11054 r11059  
    1313#include <cassert>
    1414#include <ctime>
    15 #include <iostream>
    1615
    1716#include <QCheckBox>
     
    2726#include <QHeaderView>
    2827#include <QInputDialog>
     28#include <QItemSelectionModel>
    2929#include <QLabel>
     30#include <QList>
     31#include <QMap>
    3032#include <QMessageBox>
    3133#include <QPushButton>
     
    3335#include <QResizeEvent>
    3436#include <QSpinBox>
     37#include <QStringList>
    3538#include <QStyle>
    3639#include <QTabWidget>
     
    5457#include "torrent.h"
    5558#include "torrent-model.h"
     59#include "tracker-delegate.h"
     60#include "tracker-model.h"
    5661
    5762class Prefs;
     
    164169    QWidget::setAttribute( Qt::WA_DeleteOnClose, true );
    165170
     171    QList<int> initKeys;
     172    initKeys << Prefs :: SHOW_TRACKER_SCRAPES;
     173    foreach( int key, initKeys )
     174        refreshPref( key );
     175
    166176    connect( &myTimer, SIGNAL(timeout()), this, SLOT(onTimer()));
     177    connect( &myPrefs, SIGNAL(changed(int)), this, SLOT(refreshPref(int)) );
    167178
    168179    onTimer( );
     
    191202
    192203    myFileTreeView->clear( );
    193 
    194204    myIds = ids;
    195205
     
    207217}
    208218
     219void
     220Details :: refreshPref( int key )
     221{
     222    QString str;
     223
     224    switch( key )
     225    {
     226        case Prefs::SHOW_TRACKER_SCRAPES:
     227            myTrackerDelegate->setShowMore( myPrefs.getBool( key ) );
     228            myTrackerView->update( );
     229            break;
     230
     231        default:
     232            break;
     233    }
     234}
     235
     236
    209237/***
    210238****
     
    220248void
    221249Details :: onTimer( )
     250{
     251    getNewData( );
     252}
     253
     254void
     255Details :: getNewData( )
    222256{
    223257    if( !myIds.empty( ) )
     
    681715    }
    682716
    683     // tracker tab
    684     //
    685     QMap<QString,QTreeWidgetItem*> trackerTiers;
    686     QMap<QString,QTreeWidgetItem*> trackerItems;
    687     const time_t now( time( 0 ) );
    688     const bool showScrape = myPrefs.getBool( Prefs::SHOW_TRACKER_SCRAPES );
    689     foreach( const Torrent * t, torrents )
    690     {
    691         const QString idStr( QString::number( t->id( ) ) );
    692         const TrackerStatsList trackerStats = t->trackerStats( );
    693 
    694         foreach( const TrackerStat& trackerStat, trackerStats )
    695         {
    696             QFont font;
    697             QString str;
    698             const QString tierKey( QString::number(trackerStat.tier) );
    699             QTreeWidgetItem * tier = (QTreeWidgetItem*) myTrackerTiers.value( tierKey, 0 );
    700 
    701             if( tier == 0 ) // check if has tier been created this pass
    702                 tier = (QTreeWidgetItem*) trackerTiers.value( tierKey, 0 );
    703 
    704             if( tier == 0 ) // new tier
    705             {
    706                 QFont tierFont;
    707                 tier = new QTreeWidgetItem( myTrackerTree );
    708                 myTrackerTree->addTopLevelItem( tier );
    709                 str = "Tier: " + QString::number( trackerStat.tier + 1 );
    710                 tier->setText( 0, str );
    711                 tierFont.setBold( true );
    712                 tier->setFont( 0, tierFont );
    713             }
    714 
    715             const QString key( idStr + tierKey + ":" + QString::number( trackerStat.id ) );
    716             QTreeWidgetItem * item = (QTreeWidgetItem*) myTrackerItems.value( key, 0 );
    717 
    718             if( item == 0 ) // new tracker
    719             {
    720                 item = new QTreeWidgetItem( tier );
    721                 tier->addChild( item );
    722                 if( tier->childCount() == 1 )
    723                     tier->setExpanded( true );
    724             }
    725             str = trackerStat.host;
    726 
    727             if( trackerStat.isBackup )
    728             {
    729                 font.setItalic( true );
    730                 if( showScrape )
    731                 {
    732                     str += "\n";
    733                     str += "Tracker will be used as a backup";
    734                 }
    735             }
    736             else
    737             {
    738                 font.setItalic( false );
    739                 if( trackerStat.hasAnnounced )
    740                 {
    741                     const QString tstr( timeToStringRounded( now - trackerStat.lastAnnounceTime ) );
    742                     str += "\n";
    743                     if( trackerStat.lastAnnounceSucceeded )
    744                     {
    745                         str += tr( "Got a list of %1 peers %2 ago" )
    746                             .arg( trackerStat.lastAnnouncePeerCount )
    747                             .arg( tstr );
    748                     }
    749                     else if( trackerStat.lastAnnounceTimedOut )
    750                     {
    751                         str += tr( "Peer list request timed out %1 ago; will retry" )
    752                             .arg( tstr );
    753                     }
    754                     else
    755                     {
    756                         str += tr( "Got an error %1 ago" )
    757                             .arg( tstr );
    758                     }
    759                 }
    760                 switch( trackerStat.announceState )
    761                 {
    762                     case TR_TRACKER_INACTIVE:
    763                         if( trackerStat.hasAnnounced )
    764                         {
    765                             str += "\n";
    766                             str += tr( "No updates scheduled" );
    767                         }
    768                         break;
    769                     case TR_TRACKER_WAITING:
    770                         {
    771                             const QString tstr( timeToStringRounded( trackerStat.nextAnnounceTime - now ) );
    772                             str += "\n";
    773                             str += tr( "Asking for more peers in %1" )
    774                                 .arg( tstr );
    775                         }
    776                         break;
    777                     case TR_TRACKER_QUEUED:
    778                         str += "\n";
    779                         str += tr( "Queued to ask for more peers" );
    780                         break;
    781                     case TR_TRACKER_ACTIVE:
    782                         {
    783                             const QString tstr( timeToStringRounded( now - trackerStat.lastAnnounceStartTime ) );
    784                             str += "\n";
    785                             str += tr( "Asking for more peers now... %1" )
    786                                 .arg( tstr );
    787                         }
    788                         break;
    789                 }
    790                 if( showScrape )
    791                 {
    792                     if( trackerStat.hasScraped )
    793                     {
    794                         const QString tstr( timeToStringRounded( now - trackerStat.lastScrapeTime ) );
    795                         str += "\n";
    796                         if( trackerStat.lastScrapeSucceeded )
    797                         {
    798                             str += tr( "Tracker had %1 seeders and %2 leechers %3 ago" )
    799                                 .arg( trackerStat.seederCount )
    800                                 .arg( trackerStat.leecherCount )
    801                                 .arg( tstr );
    802                         }
    803                         else
    804                         {
    805                             str += tr( "Got a scrape error %1 ago" )
    806                                 .arg( tstr );
    807                         }
    808                     }
    809                     switch( trackerStat.scrapeState )
    810                     {
    811                         case TR_TRACKER_INACTIVE:
    812                             break;
    813                         case TR_TRACKER_WAITING:
    814                             {
    815                                 const QString tstr( timeToStringRounded( trackerStat.nextScrapeTime - now ) );
    816                                 str += "\n";
    817                                 str += tr( "Asking for peer counts in %1" )
    818                                     .arg( tstr );
    819                             }
    820                             break;
    821                         case TR_TRACKER_QUEUED:
    822                             str += "\n";
    823                             str += tr( "Queued to ask for peer counts" );
    824                             break;
    825                         case TR_TRACKER_ACTIVE:
    826                             {
    827                                 const QString tstr( timeToStringRounded( now - trackerStat.lastScrapeStartTime ) );
    828                                 str += "\n";
    829                                 str += tr( "Asking for peer counts now... %1" )
    830                                     .arg( tstr );
    831                             }
    832                             break;
    833                     }
    834                 }
    835             }
    836             item->setText( 0, str );
    837             item->setFont( 0, font );
    838             item->setData( 0, TRACKERID, trackerStat.id );
    839             item->setData( 0, TRACKERURL, trackerStat.announce );
    840             item->setData( 0, TRACKERTIER, trackerStat.tier );
    841             item->setData( 0, TORRENTID, t->id() );
    842 
    843             tier->setData( 0, TRACKERID, -1 );
    844             tier->setData( 0, TRACKERURL, QString() );
    845             tier->setData( 0, TRACKERTIER, trackerStat.tier );
    846             tier->setData( 0, TORRENTID, torrents.count() > 1 ? -1 : t->id() );
    847 
    848             trackerTiers.insert( tierKey, tier );
    849             trackerItems.insert( key, item );
    850         }
    851     }
    852     QList<QTreeWidgetItem*> tierList = trackerTiers.values();
    853     QList<QTreeWidgetItem*> itemList = trackerItems.values();
    854     for( int i = 0; i < myTrackerTree->topLevelItemCount(); ++i )
    855     {
    856         QTreeWidgetItem * tier = myTrackerTree->topLevelItem( i );
    857         for( int j = 0; j < tier->childCount(); ++j )
    858         {
    859             if( !itemList.contains( tier->child( j ) ) ) // tracker has disappeared
    860                 delete tier->takeChild( j-- );
    861         }
    862         if( !tierList.contains( tier ) ) // tier has disappeared
    863             delete myTrackerTree->takeTopLevelItem( i-- );
    864     }
    865     myTrackerTiers = trackerTiers;
    866     myTrackerItems = trackerItems;
     717    ///
     718    ///  Tracker tab
     719    ///
     720
     721    myTrackerModel->refresh( myModel, myIds );
    867722
    868723    ///
     
    1015870{
    1016871    mySession.torrentSet( myIds, "honorsSessionLimits", val );
     872    getNewData( );
    1017873}
    1018874void
     
    1020876{
    1021877    mySession.torrentSet( myIds, "downloadLimited", val );
     878    getNewData( );
    1022879}
    1023880void
     
    1025882{
    1026883    mySession.torrentSet( myIds, "downloadLimit", val );
     884    getNewData( );
    1027885}
    1028886void
     
    1030888{
    1031889    mySession.torrentSet( myIds, "uploadLimited", val );
     890    getNewData( );
    1032891}
    1033892void
     
    1035894{
    1036895    mySession.torrentSet( myIds, "uploadLimit", val );
     896    getNewData( );
    1037897}
    1038898
     
    1042902    const int val = myIdleCombo->itemData( index ).toInt( );
    1043903    mySession.torrentSet( myIds, "seedIdleMode", val );
     904    getNewData( );
    1044905}
    1045906
     
    1048909{
    1049910    mySession.torrentSet( myIds, "seedIdleLimit", val );
     911    getNewData( );
    1050912}
    1051913
     
    1061923{
    1062924    mySession.torrentSet( myIds, "seedRatioLimit", val );
     925    getNewData( );
    1063926}
    1064927
     
    1067930{
    1068931    mySession.torrentSet( myIds, "peer-limit", val );
     932    getNewData( );
    1069933}
    1070934
     
    1076940        const int priority = myBandwidthPriorityCombo->itemData(index).toInt( );
    1077941        mySession.torrentSet( myIds, "bandwidthPriority", priority );
     942        getNewData( );
    1078943    }
    1079944}
     
    1082947Details :: onTrackerSelectionChanged( )
    1083948{
    1084     const QList<QTreeWidgetItem*> items = myTrackerTree->selectedItems();
    1085     if( items.count() == 1 )
    1086         myEditTrackerButton->setEnabled( items.first()->data( 0, TRACKERID ).toInt() >= 0 );
     949    const int selectionCount = myTrackerView->selectionModel()->selectedRows().size();
     950    myEditTrackerButton->setEnabled( selectionCount == 1 );
     951    myRemoveTrackerButton->setEnabled( selectionCount > 0 );
     952}
     953
     954void
     955Details :: onAddTrackerClicked( )
     956{
     957    bool ok = false;
     958    const QString url = QInputDialog::getText( this,
     959                                               tr( "Add URL " ),
     960                                               tr( "Add tracker announce URL:" ),
     961                                               QLineEdit::Normal, QString(), &ok );
     962    if( !ok )
     963    {
     964        // user pressed "cancel" -- noop
     965    }
     966    else if( !QUrl(url).isValid( ) )
     967    {
     968        QMessageBox::warning( this, tr( "Error" ), tr( "Invalid URL \"%1\"" ).arg( url ) );
     969    }
    1087970    else
    1088         myEditTrackerButton->setEnabled( false );
    1089     myRemoveTrackerButton->setEnabled( !items.isEmpty() );
    1090 }
    1091 
    1092 bool
    1093 Details :: findTrackerByURL( const QString& url, int torId )
    1094 {
    1095     bool duplicate = false;
    1096     foreach( QTreeWidgetItem * tracker, myTrackerItems.values() )
    1097     {
    1098         if( tracker->data( 0, TRACKERURL ).toString() == url &&
    1099           ( torId == -1 || tracker->data( 0, TORRENTID ).toInt() == torId ) )
     971    {
     972        QSet<int> ids;
     973
     974        foreach( int id, myIds )
     975            if( myTrackerModel->find( id, url ) == -1 )
     976                ids.insert( id );
     977
     978        if( ids.empty( ) ) // all the torrents already have this tracker
    1100979        {
    1101             duplicate = true;
    1102             break;
    1103         }
    1104     }
    1105     return duplicate;
    1106 }
    1107 
    1108 void
    1109 Details :: onAddTrackerPushed( )
    1110 {
    1111     const QString urlString = QInputDialog::getText( this,
    1112                                                      tr( "Add tracker announce URL " ),
    1113                                                      NULL );
    1114     if( !urlString.isEmpty() )
    1115     {
    1116         if( !findTrackerByURL( urlString, -1 ) )
     980            QMessageBox::warning( this, tr( "Error" ), tr( "Tracker already exists." ) );
     981        }
     982        else
    1117983        {
    1118             QByteArray url = urlString.toUtf8();
    1119             tr_benc top;
    1120 
    1121             tr_bencInitDict( &top, 1 );
    1122             tr_bencDictAddStr( &top, "announce", url );
    1123 
    1124             mySession.torrentSet( myIds, "trackerAdd", &top );
    1125         }
    1126         else
    1127             QMessageBox::warning( this, "Error", "Tracker already exists." );
    1128     }
    1129 }
    1130 
    1131 void
    1132 Details :: onEditTrackerPushed( )
    1133 {
    1134     const QTreeWidgetItem * item = myTrackerTree->selectedItems().first();
    1135     const QString urlString = QInputDialog::getText( this,
    1136                                                      tr( "Edit tracker announce URL " ),
    1137                                                      NULL,
    1138                                                      QLineEdit::Normal,
    1139                                                      item->data( 0, TRACKERURL ).toString() );
    1140     if( !urlString.isEmpty() )
    1141     {
    1142         const int torId = item->data( 0, TORRENTID ).toInt();
    1143         if( !findTrackerByURL( urlString, torId ) )
    1144         {
    1145             QByteArray url = urlString.toUtf8();
    1146             QSet<int> ids;
    1147             tr_benc top;
    1148 
    1149             ids << torId;
    1150             tr_bencInitDict( &top, 2 );
    1151             tr_bencDictAddStr( &top, "announce", item->data( 0, TRACKERURL ).toByteArray() );
    1152             tr_bencDictAddStr( &top, "announce-new", url );
    1153 
    1154             mySession.torrentSet( ids, "trackerEdit", &top );
    1155         }
    1156         else
    1157             QMessageBox::warning( this, "Error", "Tracker already exists." );
    1158     }
    1159 }
    1160 
    1161 void
    1162 Details :: removeTracker( const QTreeWidgetItem * item )
    1163 {
    1164     QByteArray url = item->data( 0, TRACKERURL ).toByteArray();
    1165     const int torId = item->data( 0, TORRENTID ).toInt();
    1166     QSet<int> ids;
    1167     tr_benc top;
    1168 
    1169     ids << torId;
    1170     tr_bencInitDict( &top, 1 );
    1171     tr_bencDictAddStr( &top, "announce", url );
    1172 
    1173     mySession.torrentSet( ids, "trackerRemove", &top );
    1174 }
    1175 
    1176 void
    1177 Details :: onRemoveTrackerPushed( )
    1178 {
    1179     const QList<QTreeWidgetItem*> items = myTrackerTree->selectedItems();
    1180     QSet<int> removedTiers;
    1181     foreach( const QTreeWidgetItem * item, items ) {
    1182         const bool isTier = item->data( 0, TRACKERID ).toInt() == -1;
    1183         const int curTier = item->data( 0, TRACKERTIER ).toInt();
    1184         if( isTier )
    1185         {
    1186             removedTiers << curTier;
    1187             for( int i = 0; i < item->childCount(); ++i )
    1188                 removeTracker( item->child( i ) );
    1189         }
    1190         else if( !removedTiers.contains( curTier ) ) // skip trackers removed by clearing a tier
    1191             removeTracker( item );
     984            QStringList urls;
     985            urls << url;
     986            mySession.torrentSet( ids, "trackerAdd", urls );
     987            getNewData( );
     988        }
     989    }
     990}
     991
     992void
     993Details :: onEditTrackerClicked( )
     994{
     995    QItemSelectionModel * selectionModel = myTrackerView->selectionModel( );
     996    QModelIndexList selectedRows = selectionModel->selectedRows( );
     997    assert( selectedRows.size( ) == 1 );
     998    QModelIndex i = selectionModel->currentIndex( );
     999    const TrackerInfo trackerInfo = myTrackerModel->data( i, TrackerModel::TrackerRole ).value<TrackerInfo>();
     1000
     1001    bool ok = false;
     1002    const QString newval = QInputDialog::getText( this,
     1003                                                  tr( "Edit URL " ),
     1004                                                  tr( "Edit tracker announce URL:" ),
     1005                                                  QLineEdit::Normal,
     1006                                                  trackerInfo.st.announce, &ok );
     1007
     1008    if( !ok )
     1009    {
     1010        // user pressed "cancel" -- noop
     1011    }
     1012    else if( !QUrl(newval).isValid( ) )
     1013    {
     1014        QMessageBox::warning( this, tr( "Error" ), tr( "Invalid URL \"%1\"" ).arg( newval ) );
     1015    }
     1016    else
     1017    {
     1018        QSet<int> ids;
     1019        ids << trackerInfo.torrentId;
     1020
     1021        QStringList urls;
     1022        urls << trackerInfo.st.announce;
     1023        urls << newval;
     1024
     1025        mySession.torrentSet( ids, "trackerReplace", urls );
     1026        getNewData( );
     1027    }
     1028}
     1029
     1030void
     1031Details :: onRemoveTrackerClicked( )
     1032{
     1033    // make a map of torrentIds to announce URLs to remove
     1034    QItemSelectionModel * selectionModel = myTrackerView->selectionModel( );
     1035    QModelIndexList selectedRows = selectionModel->selectedRows( );
     1036    QMap<int,QStringList> torrentId_to_urls;
     1037    foreach( QModelIndex i, selectedRows )
     1038    {
     1039        const TrackerInfo inf = myTrackerModel->data( i, TrackerModel::TrackerRole ).value<TrackerInfo>();
     1040        torrentId_to_urls[ inf.torrentId ].append( inf.st.announce );
     1041    }
     1042
     1043    // batch all of a tracker's torrents into one command
     1044    foreach( int id, torrentId_to_urls.keys( ) )
     1045    {
     1046        QSet<int> ids;
     1047        ids << id;
     1048        mySession.torrentSet( ids, "trackerRemove", torrentId_to_urls.value( id ) );
     1049        getNewData( );
    11921050    }
    11931051}
     
    13071165    v2->setSpacing( HIG::PAD );
    13081166
    1309     QStringList headers;
    1310     headers << tr("Trackers");
    1311     myTrackerTree = new QTreeWidget;
    1312     myTrackerTree->setHeaderLabels( headers );
    1313     myTrackerTree->setSelectionMode( QTreeWidget::ExtendedSelection );
    1314     myTrackerTree->setRootIsDecorated( false );
    1315     myTrackerTree->setIndentation( 2 );
    1316     myTrackerTree->setItemsExpandable( false );
    1317     myTrackerTree->setTextElideMode( Qt::ElideRight );
    1318     myTrackerTree->setAlternatingRowColors( true );
    1319     connect( myTrackerTree, SIGNAL(itemSelectionChanged()), this, SLOT(onTrackerSelectionChanged()));
    1320     h->addWidget( myTrackerTree, 1 );
     1167    myTrackerView = new QTreeView;
     1168    myTrackerView->setModel( myTrackerModel = new TrackerModel );
     1169    myTrackerView->setHeaderHidden( true );
     1170    myTrackerView->setSelectionMode( QTreeWidget::ExtendedSelection );
     1171    myTrackerView->setRootIsDecorated( false );
     1172    myTrackerView->setIndentation( 2 );
     1173    myTrackerView->setItemsExpandable( false );
     1174    myTrackerView->setAlternatingRowColors( true );
     1175    myTrackerView->setItemDelegate( myTrackerDelegate = new TrackerDelegate( ) );
     1176    connect( myTrackerView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(onTrackerSelectionChanged()));
     1177    h->addWidget( myTrackerView, 1 );
    13211178
    13221179    p = new QPushButton();
     
    13251182    myAddTrackerButton = p;
    13261183    v2->addWidget( p, 1 );
    1327     connect( p, SIGNAL(clicked(bool)), this, SLOT(onAddTrackerPushed()));
     1184    connect( p, SIGNAL(clicked(bool)), this, SLOT(onAddTrackerClicked()));
    13281185
    13291186    p = new QPushButton();
     
    13341191    myEditTrackerButton = p;
    13351192    v2->addWidget( p, 1 );
    1336     connect( p, SIGNAL(clicked(bool)), this, SLOT(onEditTrackerPushed()));
     1193    connect( p, SIGNAL(clicked(bool)), this, SLOT(onEditTrackerClicked()));
    13371194
    13381195    p = new QPushButton();
     
    13421199    myRemoveTrackerButton = p;
    13431200    v2->addWidget( p, 1 );
    1344     connect( p, SIGNAL(clicked(bool)), this, SLOT(onRemoveTrackerPushed()));
     1201    connect( p, SIGNAL(clicked(bool)), this, SLOT(onRemoveTrackerClicked()));
    13451202
    13461203    v2->addStretch( 1 );
     
    14291286    }
    14301287    mySession.torrentSet( myIds, key, indices.toList( ) );
     1288    getNewData( );
    14311289}
    14321290
     
    14361294    QString key( wanted ? "files-wanted" : "files-unwanted" );
    14371295    mySession.torrentSet( myIds, key, indices.toList( ) );
    1438 }
     1296    getNewData( );
     1297}
  • trunk/qt/details.h

    r11047 r11059  
    3737class Torrent;
    3838class TorrentModel;
     39class TrackerDelegate;
     40class TrackerModel;
    3941
    4042class Details: public QDialog
     
    4345
    4446    private:
    45         enum
    46         {
    47             TRACKERID = Qt::UserRole,
    48             TRACKERURL,
    49             TRACKERTIER,
    50             TORRENTID
    51         };
     47        void getNewData( );
    5248
    5349    private slots:
     
    7268        QString trimToDesiredWidth( const QString& str );
    7369        void enableWhenChecked( QCheckBox *, QWidget * );
    74         bool findTrackerByURL( const QString& url, int torId );
    75         void removeTracker( const QTreeWidgetItem * item );
    7670
    7771    private:
     
    127121        QLabel * myAnnounceManualLabel;
    128122
    129         QTreeWidget * myTrackerTree;
     123        TrackerModel * myTrackerModel;
     124        TrackerDelegate * myTrackerDelegate;
     125        QTreeView * myTrackerView;
     126        //QMap<QString,QTreeWidgetItem*> myTrackerTiers;
     127        //QMap<QString,QTreeWidgetItem*> myTrackerItems;
     128
    130129        QTreeWidget * myPeerTree;
    131         QMap<QString,QTreeWidgetItem*> myTrackerTiers;
    132         QMap<QString,QTreeWidgetItem*> myTrackerItems;
    133130        QMap<QString,QTreeWidgetItem*> myPeers;
     131
    134132        QWidgetList myWidgets;
    135133
     
    137135
    138136    private slots:
     137        void refreshPref( int key );
    139138        void onBandwidthPriorityChanged( int );
    140139        void onFilePriorityChanged( const QSet<int>& fileIndices, int );
     
    151150        void onShowTrackerScrapesToggled( bool );
    152151        void onTrackerSelectionChanged( );
    153         void onAddTrackerPushed( );
    154         void onEditTrackerPushed( );
    155         void onRemoveTrackerPushed( );
     152        void onAddTrackerClicked( );
     153        void onEditTrackerClicked( );
     154        void onRemoveTrackerClicked( );
    156155        void onMaxPeersChanged( int );
    157156        void refresh( );
  • trunk/qt/favicon.cc

    r11055 r11059  
    9898    {
    9999        // add a placholder s.t. we only ping the server once per session
    100         myPixmaps.insert( host, QPixmap( ) );
     100        QPixmap tmp( 16, 16 );
     101        tmp.fill( Qt::transparent );
     102        myPixmaps.insert( host, tmp );
    101103
    102104        // try to download the favicon
  • trunk/qt/favicon.h

    r11055 r11059  
    2929    public:
    3030
     31        static QString getHost( const QUrl& url );
     32
     33    public:
     34
    3135        Favicons();
    3236        virtual ~Favicons();
     
    4751        QMap<QString,QPixmap> myPixmaps;
    4852
    49         QString getHost( const QUrl& url );
    50 
    5153        QString getCacheDir( );
    5254        void ensureCacheDirHasBeenScanned( );
  • trunk/qt/qtr.pro

    r11052 r11059  
    3737           stats-dialog.cc torrent.cc torrent-delegate.cc \
    3838           torrent-delegate-min.cc torrent-filter.cc torrent-model.cc \
    39            triconpushbutton.cc utils.cc watchdir.cc
     39           tracker-delegate.cc tracker-model.cc triconpushbutton.cc \
     40           utils.cc watchdir.cc
    4041HEADERS += $$replace(SOURCES, .cc, .h)
    4142HEADERS += speed.h types.h
  • trunk/qt/session.cc

    r11044 r11059  
    2323#include <QNetworkRequest>
    2424#include <QSet>
     25#include <QStringList>
    2526#include <QStyle>
    2627#include <QTextStream>
     
    407408
    408409void
     410Session :: torrentSet( const QSet<int>& ids, const QString& key, const QStringList& value )
     411{
     412    tr_benc top;
     413    tr_bencInitDict( &top, 2 );
     414    tr_bencDictAddStr( &top, "method", "torrent-set" );
     415    tr_benc * args = tr_bencDictAddDict( &top, "arguments", 2 );
     416    addOptionalIds( args, ids );
     417    tr_benc * list( tr_bencDictAddList( args, key.toUtf8().constData(), value.size( ) ) );
     418    foreach( const QString str, value )
     419        tr_bencListAddStr( list, str.toUtf8().constData() );
     420    exec( &top );
     421    tr_bencFree( &top );
     422}
     423
     424void
    409425Session :: torrentSet( const QSet<int>& ids, const QString& key, const QList<int>& value )
    410426{
     
    417433    foreach( int i, value )
    418434        tr_bencListAddInt( list, i );
    419     exec( &top );
    420     tr_bencFree( &top );
    421 }
    422 
    423 void
    424 Session :: torrentSet( const QSet<int>& ids, const QString& key, const tr_benc * value )
    425 {
    426     tr_benc top;
    427     tr_bencInitDict( &top, 2 );
    428     tr_bencDictAddStr( &top, "method", "torrent-set" );
    429     tr_benc * args( tr_bencDictAddDict( &top, "arguments", 2 ) );
    430     addOptionalIds( args, ids );
    431     tr_benc * child( tr_bencDictAdd( args, key.toUtf8().constData() ) );
    432     memcpy( child, value, sizeof(tr_benc) );
    433435    exec( &top );
    434436    tr_bencFree( &top );
  • trunk/qt/session.h

    r10937 r11059  
    2121#include <QString>
    2222#include <QUrl>
     23
     24class QStringList;
    2325
    2426#include <libtransmission/transmission.h>
     
    99101        void torrentSet( const QSet<int>& ids, const QString& key, double val );
    100102        void torrentSet( const QSet<int>& ids, const QString& key, const QList<int>& val );
    101         void torrentSet( const QSet<int>& ids, const QString& key, const tr_benc * value );
     103        void torrentSet( const QSet<int>& ids, const QString& key, const QStringList& val );
    102104        void torrentSetLocation( const QSet<int>& ids, const QString& path, bool doMove );
    103105
  • trunk/qt/torrent.cc

    r11052 r11059  
    567567            const char * str;
    568568            TrackerStat trackerStat;
    569             if( tr_bencDictFindStr( child, "announce", &str ) )
     569            if( tr_bencDictFindStr( child, "announce", &str ) ) {
    570570                trackerStat.announce = QString::fromUtf8( str );
     571                dynamic_cast<MyApp*>(QApplication::instance())->favicons.add( QUrl( trackerStat.announce ) );
     572            }
    571573            if( tr_bencDictFindInt( child, "announceState", &i ) )
    572574                trackerStat.announceState = i;
     
    706708    return s;
    707709}
     710
     711QPixmap
     712TrackerStat :: getFavicon( ) const
     713{
     714    MyApp * myApp = dynamic_cast<MyApp*>(QApplication::instance());
     715    return myApp->favicons.find( QUrl( announce ) );
     716}
     717
  • trunk/qt/torrent.h

    r11047 r11059  
    3535
    3636class Prefs;
     37class QPixmap;
    3738class QStyle;
    3839
     
    8788    int seederCount;
    8889    int tier;
     90    QPixmap getFavicon( ) const;
    8991};
    9092
  • trunk/qt/transmission_en.ts

    r10957 r11059  
    3838    <name>Details</name>
    3939    <message>
    40         <location filename="details.cc" line="145"/>
     40        <location filename="details.cc" line="151"/>
    4141        <source>Torrent Properties</source>
    4242        <translation type="unfinished"></translation>
    4343    </message>
    4444    <message>
    45         <location filename="details.cc" line="149"/>
     45        <location filename="details.cc" line="155"/>
    4646        <source>Information</source>
    4747        <translation type="unfinished"></translation>
    4848    </message>
    4949    <message>
    50         <location filename="details.cc" line="151"/>
     50        <location filename="details.cc" line="157"/>
    5151        <source>Peers</source>
    5252        <translation type="unfinished"></translation>
    5353    </message>
    5454    <message>
    55         <location filename="details.cc" line="153"/>
     55        <location filename="details.cc" line="159"/>
    5656        <source>Tracker</source>
    5757        <translation type="unfinished"></translation>
    5858    </message>
    5959    <message>
    60         <location filename="details.cc" line="155"/>
     60        <location filename="details.cc" line="161"/>
    6161        <source>Files</source>
    6262        <translation type="unfinished"></translation>
    6363    </message>
    6464    <message>
    65         <location filename="details.cc" line="157"/>
     65        <location filename="details.cc" line="163"/>
    6666        <source>Options</source>
    6767        <translation type="unfinished"></translation>
    6868    </message>
    6969    <message>
    70         <location filename="details.cc" line="256"/>
     70        <location filename="details.cc" line="287"/>
    7171        <source>None</source>
    7272        <translation type="unfinished"></translation>
    7373    </message>
    7474    <message>
    75         <location filename="details.cc" line="257"/>
     75        <location filename="details.cc" line="288"/>
    7676        <source>Mixed</source>
    7777        <translation type="unfinished"></translation>
    7878    </message>
    7979    <message>
    80         <location filename="details.cc" line="258"/>
    81         <location filename="details.cc" line="441"/>
     80        <location filename="details.cc" line="289"/>
     81        <location filename="details.cc" line="472"/>
    8282        <source>Unknown</source>
    8383        <translation type="unfinished"></translation>
    8484    </message>
    8585    <message>
    86         <location filename="details.cc" line="290"/>
     86        <location filename="details.cc" line="321"/>
    8787        <source>Finished</source>
    8888        <translation type="unfinished"></translation>
    8989    </message>
    9090    <message>
    91         <location filename="details.cc" line="292"/>
     91        <location filename="details.cc" line="323"/>
    9292        <source>Paused</source>
    9393        <translation type="unfinished"></translation>
    9494    </message>
    9595    <message>
    96         <location filename="details.cc" line="328"/>
     96        <location filename="details.cc" line="359"/>
    9797        <source>%1 (%2%)</source>
    9898        <translation type="unfinished"></translation>
    9999    </message>
    100100    <message>
    101         <location filename="details.cc" line="332"/>
     101        <location filename="details.cc" line="363"/>
    102102        <source>%1 (%2%); %3 Unverified</source>
    103103        <translation type="unfinished"></translation>
    104104    </message>
    105105    <message>
    106         <location filename="details.cc" line="363"/>
     106        <location filename="details.cc" line="394"/>
    107107        <source>%1 (+%2 corrupt)</source>
    108108        <translation type="unfinished"></translation>
    109109    </message>
    110110    <message>
    111         <location filename="details.cc" line="461"/>
     111        <location filename="details.cc" line="492"/>
    112112        <source>Active now</source>
    113113        <translation type="unfinished"></translation>
    114114    </message>
    115115    <message>
    116         <location filename="details.cc" line="463"/>
     116        <location filename="details.cc" line="494"/>
    117117        <source>%1 ago</source>
    118118        <translation type="unfinished"></translation>
    119119    </message>
    120120    <message numerus="yes">
    121         <location filename="details.cc" line="504"/>
     121        <location filename="details.cc" line="535"/>
    122122        <source>%1 (%Ln pieces @ %2)</source>
    123123        <translation>
     
    127127    </message>
    128128    <message numerus="yes">
    129         <location filename="details.cc" line="508"/>
     129        <location filename="details.cc" line="539"/>
    130130        <source>%1 (%Ln pieces)</source>
    131131        <translation>
     
    135135    </message>
    136136    <message>
    137         <location filename="details.cc" line="532"/>
     137        <location filename="details.cc" line="563"/>
    138138        <source>Private to this tracker -- DHT and PEX disabled</source>
    139139        <translation type="unfinished"></translation>
    140140    </message>
    141141    <message>
    142         <location filename="details.cc" line="533"/>
     142        <location filename="details.cc" line="564"/>
    143143        <source>Public torrent</source>
    144144        <translation type="unfinished"></translation>
    145145    </message>
    146146    <message>
    147         <location filename="details.cc" line="572"/>
     147        <location filename="details.cc" line="603"/>
    148148        <source>Created by %1</source>
    149149        <translation type="unfinished"></translation>
    150150    </message>
    151151    <message>
    152         <location filename="details.cc" line="574"/>
     152        <location filename="details.cc" line="605"/>
    153153        <source>Created on %1</source>
    154154        <translation type="unfinished"></translation>
    155155    </message>
    156156    <message>
    157         <location filename="details.cc" line="576"/>
     157        <location filename="details.cc" line="607"/>
    158158        <source>Created by %1 on %2</source>
    159159        <translation type="unfinished"></translation>
    160160    </message>
    161161    <message>
    162         <location filename="details.cc" line="735"/>
     162        <location filename="details.cc" line="778"/>
    163163        <source>Got a list of %1 peers %2 ago</source>
    164164        <translation type="unfinished"></translation>
    165165    </message>
    166166    <message>
    167         <location filename="details.cc" line="741"/>
     167        <location filename="details.cc" line="784"/>
    168168        <source>Peer list request timed out %1 ago; will retry</source>
    169169        <translation type="unfinished"></translation>
    170170    </message>
    171171    <message>
    172         <location filename="details.cc" line="746"/>
     172        <location filename="details.cc" line="789"/>
    173173        <source>Got an error %1 ago</source>
    174174        <translation type="unfinished"></translation>
    175175    </message>
    176176    <message>
    177         <location filename="details.cc" line="756"/>
     177        <location filename="details.cc" line="799"/>
    178178        <source>No updates scheduled</source>
    179179        <translation type="unfinished"></translation>
    180180    </message>
    181181    <message>
    182         <location filename="details.cc" line="763"/>
     182        <location filename="details.cc" line="806"/>
    183183        <source>Asking for more peers in %1</source>
    184184        <translation type="unfinished"></translation>
    185185    </message>
    186186    <message>
    187         <location filename="details.cc" line="769"/>
     187        <location filename="details.cc" line="812"/>
    188188        <source>Queued to ask for more peers</source>
    189189        <translation type="unfinished"></translation>
    190190    </message>
    191191    <message>
    192         <location filename="details.cc" line="775"/>
     192        <location filename="details.cc" line="818"/>
    193193        <source>Asking for more peers now... %1</source>
    194194        <translation type="unfinished"></translation>
    195195    </message>
    196196    <message>
    197         <location filename="details.cc" line="788"/>
     197        <location filename="details.cc" line="831"/>
    198198        <source>Tracker had %1 seeders and %2 leechers %3 ago</source>
    199199        <translation type="unfinished"></translation>
    200200    </message>
    201201    <message>
    202         <location filename="details.cc" line="795"/>
     202        <location filename="details.cc" line="838"/>
    203203        <source>Got a scrape error %1 ago</source>
    204204        <translation type="unfinished"></translation>
    205205    </message>
    206206    <message>
    207         <location filename="details.cc" line="807"/>
     207        <location filename="details.cc" line="850"/>
    208208        <source>Asking for peer counts in %1</source>
    209209        <translation type="unfinished"></translation>
    210210    </message>
    211211    <message>
    212         <location filename="details.cc" line="813"/>
     212        <location filename="details.cc" line="856"/>
    213213        <source>Queued to ask for peer counts</source>
    214214        <translation type="unfinished"></translation>
    215215    </message>
    216216    <message>
    217         <location filename="details.cc" line="819"/>
     217        <location filename="details.cc" line="862"/>
    218218        <source>Asking for peer counts now... %1</source>
    219219        <translation type="unfinished"></translation>
    220220    </message>
    221221    <message>
    222         <location filename="details.cc" line="883"/>
    223         <location filename="details.cc" line="904"/>
     222        <location filename="details.cc" line="926"/>
     223        <location filename="details.cc" line="947"/>
    224224        <source>Encrypted connection</source>
    225225        <translation type="unfinished"></translation>
    226226    </message>
    227227    <message>
    228         <location filename="details.cc" line="897"/>
     228        <location filename="details.cc" line="940"/>
    229229        <source>Optimistic unchoke</source>
    230230        <translation type="unfinished"></translation>
    231231    </message>
    232232    <message>
    233         <location filename="details.cc" line="898"/>
     233        <location filename="details.cc" line="941"/>
    234234        <source>Downloading from this peer</source>
    235235        <translation type="unfinished"></translation>
    236236    </message>
    237237    <message>
    238         <location filename="details.cc" line="899"/>
     238        <location filename="details.cc" line="942"/>
    239239        <source>We would download from this peer if they would let us</source>
    240240        <translation type="unfinished"></translation>
    241241    </message>
    242242    <message>
    243         <location filename="details.cc" line="900"/>
     243        <location filename="details.cc" line="943"/>
    244244        <source>Uploading to peer</source>
    245245        <translation type="unfinished"></translation>
    246246    </message>
    247247    <message>
    248         <location filename="details.cc" line="901"/>
     248        <location filename="details.cc" line="944"/>
    249249        <source>We would upload to this peer if they asked</source>
    250250        <translation type="unfinished"></translation>
    251251    </message>
    252252    <message>
    253         <location filename="details.cc" line="902"/>
     253        <location filename="details.cc" line="945"/>
    254254        <source>Peer has unchoked us, but we&apos;re not interested</source>
    255255        <translation type="unfinished"></translation>
    256256    </message>
    257257    <message>
    258         <location filename="details.cc" line="903"/>
     258        <location filename="details.cc" line="946"/>
    259259        <source>We unchoked this peer, but they&apos;re not interested</source>
    260260        <translation type="unfinished"></translation>
    261261    </message>
    262262    <message>
    263         <location filename="details.cc" line="905"/>
     263        <location filename="details.cc" line="948"/>
    264264        <source>Peer was discovered through DHT</source>
    265265        <translation type="unfinished"></translation>
    266266    </message>
    267267    <message>
    268         <location filename="details.cc" line="906"/>
     268        <location filename="details.cc" line="949"/>
    269269        <source>Peer was discovered through Peer Exchange (PEX)</source>
    270270        <translation type="unfinished"></translation>
    271271    </message>
    272272    <message>
    273         <location filename="details.cc" line="907"/>
     273        <location filename="details.cc" line="950"/>
    274274        <source>Peer is an incoming connection</source>
    275275        <translation type="unfinished"></translation>
    276276    </message>
    277277    <message>
    278         <location filename="details.cc" line="963"/>
     278        <location filename="details.cc" line="1006"/>
    279279        <source>Activity</source>
    280280        <translation type="unfinished"></translation>
    281281    </message>
    282282    <message>
    283         <location filename="details.cc" line="964"/>
     283        <location filename="details.cc" line="1007"/>
    284284        <source>Torrent size:</source>
    285285        <translation type="unfinished"></translation>
    286286    </message>
    287287    <message>
    288         <location filename="details.cc" line="965"/>
     288        <location filename="details.cc" line="1008"/>
    289289        <source>Have:</source>
    290290        <translation type="unfinished"></translation>
    291291    </message>
    292292    <message>
    293         <location filename="details.cc" line="966"/>
     293        <location filename="details.cc" line="1009"/>
    294294        <source>Availability:</source>
    295295        <translation type="unfinished"></translation>
    296296    </message>
    297297    <message>
    298         <location filename="details.cc" line="967"/>
     298        <location filename="details.cc" line="1010"/>
    299299        <source>Downloaded:</source>
    300300        <translation type="unfinished"></translation>
    301301    </message>
    302302    <message>
    303         <location filename="details.cc" line="968"/>
     303        <location filename="details.cc" line="1011"/>
    304304        <source>Uploaded:</source>
    305305        <translation type="unfinished"></translation>
    306306    </message>
    307307    <message>
    308         <location filename="details.cc" line="969"/>
     308        <location filename="details.cc" line="1012"/>
    309309        <source>Ratio:</source>
    310310        <translation type="unfinished"></translation>
    311311    </message>
    312312    <message>
    313         <location filename="details.cc" line="970"/>
     313        <location filename="details.cc" line="1013"/>
    314314        <source>State:</source>
    315315        <translation type="unfinished"></translation>
    316316    </message>
    317317    <message>
    318         <location filename="details.cc" line="971"/>
     318        <location filename="details.cc" line="1014"/>
    319319        <source>Running time:</source>
    320320        <translation type="unfinished"></translation>
    321321    </message>
    322322    <message>
    323         <location filename="details.cc" line="972"/>
     323        <location filename="details.cc" line="1015"/>
    324324        <source>Remaining time:</source>
    325325        <translation type="unfinished"></translation>
    326326    </message>
    327327    <message>
    328         <location filename="details.cc" line="973"/>
     328        <location filename="details.cc" line="1016"/>
    329329        <source>Last activity:</source>
    330330        <translation type="unfinished"></translation>
    331331    </message>
    332332    <message>
    333         <location filename="details.cc" line="974"/>
     333        <location filename="details.cc" line="1017"/>
    334334        <source>Error:</source>
    335335        <translation type="unfinished"></translation>
    336336    </message>
    337337    <message>
    338         <location filename="details.cc" line="978"/>
     338        <location filename="details.cc" line="1021"/>
    339339        <source>Details</source>
    340340        <translation type="unfinished"></translation>
    341341    </message>
    342342    <message>
    343         <location filename="details.cc" line="979"/>
     343        <location filename="details.cc" line="1022"/>
    344344        <source>Location:</source>
    345345        <translation type="unfinished"></translation>
    346346    </message>
    347347    <message>
    348         <location filename="details.cc" line="980"/>
     348        <location filename="details.cc" line="1023"/>
    349349        <source>Hash:</source>
    350350        <translation type="unfinished"></translation>
    351351    </message>
    352352    <message>
    353         <location filename="details.cc" line="981"/>
     353        <location filename="details.cc" line="1024"/>
    354354        <source>Privacy:</source>
    355355        <translation type="unfinished"></translation>
    356356    </message>
    357357    <message>
    358         <location filename="details.cc" line="982"/>
     358        <location filename="details.cc" line="1025"/>
    359359        <source>Origin:</source>
    360360        <translation type="unfinished"></translation>
    361361    </message>
    362362    <message>
    363         <location filename="details.cc" line="984"/>
     363        <location filename="details.cc" line="1027"/>
    364364        <source>Comment:</source>
    365365        <translation type="unfinished"></translation>
    366366    </message>
    367367    <message>
    368         <location filename="details.cc" line="1100"/>
     368        <location filename="details.cc" line="1125"/>
    369369        <source>Add tracker announce URL </source>
    370370        <translation type="unfinished"></translation>
    371371    </message>
    372372    <message>
    373         <location filename="details.cc" line="1124"/>
     373        <location filename="details.cc" line="1137"/>
     374        <location filename="details.cc" line="1165"/>
     375        <source>Error</source>
     376        <translation type="unfinished"></translation>
     377    </message>
     378    <message>
     379        <location filename="details.cc" line="1137"/>
     380        <source>Tracker already exists.</source>
     381        <translation type="unfinished"></translation>
     382    </message>
     383    <message>
     384        <location filename="details.cc" line="1158"/>
    374385        <source>Edit tracker announce URL </source>
    375386        <translation type="unfinished"></translation>
    376387    </message>
    377388    <message>
    378         <location filename="details.cc" line="1196"/>
     389        <location filename="details.cc" line="1165"/>
     390        <source>Invalid URL &quot;%1&quot;</source>
     391        <translation type="unfinished"></translation>
     392    </message>
     393    <message>
     394        <location filename="details.cc" line="1213"/>
    379395        <source>Speed</source>
    380396        <translation type="unfinished"></translation>
    381397    </message>
    382398    <message>
    383         <location filename="details.cc" line="1198"/>
     399        <location filename="details.cc" line="1215"/>
    384400        <source>Honor global &amp;limits</source>
    385401        <translation type="unfinished"></translation>
    386402    </message>
    387403    <message>
    388         <location filename="details.cc" line="1203"/>
     404        <location filename="details.cc" line="1220"/>
    389405        <source>Limit &amp;download speed (%1):</source>
    390406        <translation type="unfinished"></translation>
    391407    </message>
    392408    <message>
    393         <location filename="details.cc" line="1213"/>
     409        <location filename="details.cc" line="1230"/>
    394410        <source>Limit &amp;upload speed (%1):</source>
    395411        <translation type="unfinished"></translation>
    396412    </message>
    397413    <message>
    398         <location filename="details.cc" line="1224"/>
     414        <location filename="details.cc" line="1241"/>
    399415        <source>High</source>
    400416        <translation type="unfinished"></translation>
    401417    </message>
    402418    <message>
    403         <location filename="details.cc" line="1225"/>
     419        <location filename="details.cc" line="1242"/>
    404420        <source>Normal</source>
    405421        <translation type="unfinished"></translation>
    406422    </message>
    407423    <message>
    408         <location filename="details.cc" line="1226"/>
     424        <location filename="details.cc" line="1243"/>
    409425        <source>Low</source>
    410426        <translation type="unfinished"></translation>
    411427    </message>
    412428    <message>
    413         <location filename="details.cc" line="1228"/>
     429        <location filename="details.cc" line="1245"/>
    414430        <source>Torrent &amp;priority:</source>
    415431        <translation type="unfinished"></translation>
    416432    </message>
    417433    <message>
    418         <location filename="details.cc" line="1232"/>
    419         <source>Seed-Until Ratio</source>
    420         <translation type="unfinished"></translation>
    421     </message>
    422     <message>
    423         <location filename="details.cc" line="1234"/>
    424         <source>Use &amp;global settings</source>
    425         <translation type="unfinished"></translation>
    426     </message>
    427     <message>
    428         <location filename="details.cc" line="1240"/>
    429         <source>Seed &amp;regardless of ratio</source>
    430         <translation type="unfinished"></translation>
    431     </message>
    432     <message>
    433         <location filename="details.cc" line="1248"/>
    434         <source>&amp;Seed torrent until its ratio reaches:</source>
    435         <translation type="unfinished"></translation>
    436     </message>
    437     <message>
    438         <location filename="details.cc" line="1261"/>
     434        <location filename="details.cc" line="1249"/>
     435        <source>Seeding Limits</source>
     436        <translation type="unfinished"></translation>
     437    </message>
     438    <message>
     439        <location filename="details.cc" line="1254"/>
     440        <location filename="details.cc" line="1268"/>
     441        <source>Use Global Settings</source>
     442        <translation type="unfinished"></translation>
     443    </message>
     444    <message>
     445        <location filename="details.cc" line="1255"/>
     446        <source>Seed regardless of ratio</source>
     447        <translation type="unfinished"></translation>
     448    </message>
     449    <message>
     450        <location filename="details.cc" line="1256"/>
     451        <source>Stop seeding at ratio:</source>
     452        <translation type="unfinished"></translation>
     453    </message>
     454    <message>
     455        <location filename="details.cc" line="1263"/>
     456        <source>&amp;Ratio:</source>
     457        <translation type="unfinished"></translation>
     458    </message>
     459    <message>
     460        <location filename="details.cc" line="1269"/>
     461        <source>Seed regardless of activity</source>
     462        <translation type="unfinished"></translation>
     463    </message>
     464    <message>
     465        <location filename="details.cc" line="1270"/>
     466        <source>Stop seeding if idle for N minutes:</source>
     467        <translation type="unfinished"></translation>
     468    </message>
     469    <message>
     470        <location filename="details.cc" line="1277"/>
     471        <source>&amp;Idle:</source>
     472        <translation type="unfinished"></translation>
     473    </message>
     474    <message>
     475        <location filename="details.cc" line="1281"/>
    439476        <source>Peer Connections</source>
    440477        <translation type="unfinished"></translation>
    441478    </message>
    442479    <message>
    443         <location filename="details.cc" line="1267"/>
     480        <location filename="details.cc" line="1287"/>
    444481        <source>&amp;Maximum peers:</source>
    445482        <translation type="unfinished"></translation>
    446483    </message>
    447484    <message>
    448         <location filename="details.cc" line="1297"/>
    449         <source>Trackers</source>
    450         <translation type="unfinished"></translation>
    451     </message>
    452     <message>
    453         <location filename="details.cc" line="1340"/>
     485        <location filename="details.cc" line="1359"/>
    454486        <source>Show &amp;more details</source>
    455487        <translation type="unfinished"></translation>
    456488    </message>
    457489    <message>
    458         <location filename="details.cc" line="1362"/>
     490        <location filename="details.cc" line="1381"/>
    459491        <source>Up</source>
    460492        <translation type="unfinished"></translation>
    461493    </message>
    462494    <message>
    463         <location filename="details.cc" line="1362"/>
     495        <location filename="details.cc" line="1381"/>
    464496        <source>Down</source>
    465497        <translation type="unfinished"></translation>
    466498    </message>
    467499    <message>
    468         <location filename="details.cc" line="1362"/>
     500        <location filename="details.cc" line="1381"/>
    469501        <source>%</source>
    470502        <translation type="unfinished"></translation>
    471503    </message>
    472504    <message>
    473         <location filename="details.cc" line="1362"/>
     505        <location filename="details.cc" line="1381"/>
    474506        <source>Status</source>
    475507        <translation type="unfinished"></translation>
    476508    </message>
    477509    <message>
    478         <location filename="details.cc" line="1362"/>
     510        <location filename="details.cc" line="1381"/>
    479511        <source>Address</source>
    480512        <translation type="unfinished"></translation>
    481513    </message>
    482514    <message>
    483         <location filename="details.cc" line="1362"/>
     515        <location filename="details.cc" line="1381"/>
    484516        <source>Client</source>
    485517        <translation type="unfinished"></translation>
     
    537569        <location filename="formatter.cc" line="38"/>
    538570        <source>B/s</source>
    539         <translation type="unfinished"></translation>
     571        <translation></translation>
    540572    </message>
    541573    <message>
    542574        <location filename="formatter.cc" line="39"/>
    543575        <source>kB/s</source>
    544         <translation type="unfinished"></translation>
     576        <translation></translation>
    545577    </message>
    546578    <message>
    547579        <location filename="formatter.cc" line="40"/>
    548580        <source>MB/s</source>
    549         <translation type="unfinished"></translation>
     581        <translation></translation>
    550582    </message>
    551583    <message>
    552584        <location filename="formatter.cc" line="41"/>
    553585        <source>GB/s</source>
    554         <translation type="unfinished"></translation>
     586        <translation></translation>
    555587    </message>
    556588    <message>
    557589        <location filename="formatter.cc" line="42"/>
    558590        <source>TB/s</source>
    559         <translation type="unfinished"></translation>
     591        <translation></translation>
    560592    </message>
    561593    <message>
     
    563595        <location filename="formatter.cc" line="62"/>
    564596        <source>B</source>
    565         <translation type="unfinished"></translation>
     597        <translation></translation>
    566598    </message>
    567599    <message>
    568600        <location filename="formatter.cc" line="51"/>
    569601        <source>KB</source>
    570         <translation type="unfinished"></translation>
     602        <translation></translation>
    571603    </message>
    572604    <message>
    573605        <location filename="formatter.cc" line="52"/>
    574606        <source>MB</source>
    575         <translation type="unfinished"></translation>
     607        <translation></translation>
    576608    </message>
    577609    <message>
    578610        <location filename="formatter.cc" line="53"/>
    579611        <source>GB</source>
    580         <translation type="unfinished"></translation>
     612        <translation></translation>
    581613    </message>
    582614    <message>
    583615        <location filename="formatter.cc" line="54"/>
    584616        <source>TB</source>
    585         <translation type="unfinished"></translation>
     617        <translation></translation>
    586618    </message>
    587619    <message>
    588620        <location filename="formatter.cc" line="63"/>
    589621        <source>KiB</source>
    590         <translation type="unfinished"></translation>
     622        <translation></translation>
    591623    </message>
    592624    <message>
    593625        <location filename="formatter.cc" line="64"/>
    594626        <source>MiB</source>
    595         <translation type="unfinished"></translation>
     627        <translation></translation>
    596628    </message>
    597629    <message>
    598630        <location filename="formatter.cc" line="65"/>
    599631        <source>GiB</source>
    600         <translation type="unfinished"></translation>
     632        <translation></translation>
    601633    </message>
    602634    <message>
    603635        <location filename="formatter.cc" line="66"/>
    604636        <source>TiB</source>
    605         <translation type="unfinished"></translation>
     637        <translation></translation>
    606638    </message>
    607639    <message>
     
    610642        <location filename="formatter.cc" line="122"/>
    611643        <source>None</source>
    612         <translation type="unfinished"></translation>
     644        <translation></translation>
    613645    </message>
    614646    <message numerus="yes">
    615647        <location filename="formatter.cc" line="159"/>
    616648        <source>%Ln day(s)</source>
    617         <translation type="unfinished">
     649        <translation>
    618650            <numerusform>%Ln day</numerusform>
    619651            <numerusform>%Ln days</numerusform>
     
    623655        <location filename="formatter.cc" line="160"/>
    624656        <source>%Ln hour(s)</source>
    625         <translation type="unfinished">
     657        <translation>
    626658            <numerusform>%Ln hour</numerusform>
    627659            <numerusform>%Ln hours</numerusform>
     
    631663        <location filename="formatter.cc" line="161"/>
    632664        <source>%Ln minute(s)</source>
    633         <translation type="unfinished">
     665        <translation>
    634666            <numerusform>%Ln minute</numerusform>
    635667            <numerusform>%Ln minutes</numerusform>
     
    639671        <location filename="formatter.cc" line="162"/>
    640672        <source>%Ln second(s)</source>
    641         <translation type="unfinished">
     673        <translation>
    642674            <numerusform>%Ln second</numerusform>
    643675            <numerusform>%Ln seconds</numerusform>
     
    649681        <location filename="formatter.cc" line="183"/>
    650682        <source>%1, %2</source>
    651         <translation type="unfinished"></translation>
     683        <translation></translation>
    652684    </message>
    653685</context>
     
    657689        <location filename="license.cc" line="22"/>
    658690        <source>License</source>
    659         <translation type="unfinished"></translation>
     691        <translation></translation>
    660692    </message>
    661693</context>
     
    895927    <message>
    896928        <location filename="mainwin.ui" line="336"/>
    897         <source>Alt+M</source>
     929        <source>Alt+C</source>
     930        <oldsource>Alt+M</oldsource>
    898931        <translation type="unfinished"></translation>
    899932    </message>
     
    14641497    <message>
    14651498        <location filename="prefs-dialog.cc" line="373"/>
    1466         <location filename="prefs-dialog.cc" line="730"/>
     1499        <location filename="prefs-dialog.cc" line="735"/>
    14671500        <source>Status unknown</source>
    14681501        <translation type="unfinished"></translation>
     
    15031536        <translation>
    15041537            <numerusform></numerusform>
    1505             <numerusform></numerusform>
    15061538        </translation>
    15071539    </message>
     
    15431575    <message>
    15441576        <location filename="prefs-dialog.cc" line="475"/>
    1545         <location filename="prefs-dialog.cc" line="625"/>
     1577        <location filename="prefs-dialog.cc" line="630"/>
    15461578        <source>Privacy</source>
    15471579        <translation type="unfinished"></translation>
     
    16541686    <message>
    16551687        <location filename="prefs-dialog.cc" line="598"/>
    1656         <source>Seeding</source>
     1688        <source>Seeding Limits</source>
     1689        <oldsource>Seeding</oldsource>
    16571690        <translation type="unfinished"></translation>
    16581691    </message>
    16591692    <message>
    16601693        <location filename="prefs-dialog.cc" line="600"/>
    1661         <source>&amp;Seed torrent until its ratio reaches:</source>
    1662         <translation type="unfinished"></translation>
    1663     </message>
    1664     <message>
    1665         <location filename="prefs-dialog.cc" line="620"/>
     1694        <source>Stop seeding at &amp;ratio:</source>
     1695        <translation type="unfinished"></translation>
     1696    </message>
     1697    <message>
     1698        <location filename="prefs-dialog.cc" line="605"/>
     1699        <source>Stop seeding if idle for &amp;N minutes:</source>
     1700        <translation type="unfinished"></translation>
     1701    </message>
     1702    <message>
     1703        <location filename="prefs-dialog.cc" line="625"/>
    16661704        <source>Transmission Preferences</source>
    16671705        <translation type="unfinished"></translation>
    16681706    </message>
    16691707    <message>
    1670         <location filename="prefs-dialog.cc" line="623"/>
     1708        <location filename="prefs-dialog.cc" line="628"/>
    16711709        <source>Torrents</source>
    16721710        <translation type="unfinished"></translation>
    16731711    </message>
    16741712    <message>
    1675         <location filename="prefs-dialog.cc" line="624"/>
     1713        <location filename="prefs-dialog.cc" line="629"/>
    16761714        <source>Speed</source>
    16771715        <translation type="unfinished"></translation>
    16781716    </message>
    16791717    <message>
    1680         <location filename="prefs-dialog.cc" line="626"/>
     1718        <location filename="prefs-dialog.cc" line="631"/>
    16811719        <source>Network</source>
    16821720        <translation type="unfinished"></translation>
    16831721    </message>
    16841722    <message>
    1685         <location filename="prefs-dialog.cc" line="627"/>
     1723        <location filename="prefs-dialog.cc" line="632"/>
    16861724        <source>Web</source>
    16871725        <translation type="unfinished"></translation>
    16881726    </message>
    16891727    <message>
    1690         <location filename="prefs-dialog.cc" line="656"/>
     1728        <location filename="prefs-dialog.cc" line="661"/>
    16911729        <source>Not supported by remote sessions</source>
    16921730        <translation type="unfinished"></translation>
    16931731    </message>
    16941732    <message>
    1695         <location filename="prefs-dialog.cc" line="682"/>
     1733        <location filename="prefs-dialog.cc" line="687"/>
    16961734        <source>Enable &amp;blocklist</source>
    16971735        <translation type="unfinished"></translation>
    16981736    </message>
    16991737    <message numerus="yes">
    1700         <location filename="prefs-dialog.cc" line="684"/>
     1738        <location filename="prefs-dialog.cc" line="689"/>
    17011739        <source>Enable &amp;blocklist (%Ln rules)</source>
    17021740        <translation>
     
    17621800    <name>Session</name>
    17631801    <message>
    1764         <location filename="session.cc" line="765"/>
     1802        <location filename="session.cc" line="769"/>
    17651803        <source>Add Torrent</source>
    17661804        <translation type="unfinished"></translation>
     
    18691907    <name>Torrent</name>
    18701908    <message>
    1871         <location filename="torrent.cc" line="677"/>
     1909        <location filename="torrent.cc" line="683"/>
    18721910        <source>Waiting to verify local data</source>
    18731911        <translation type="unfinished"></translation>
    18741912    </message>
    18751913    <message>
    1876         <location filename="torrent.cc" line="678"/>
     1914        <location filename="torrent.cc" line="684"/>
    18771915        <source>Verifying local data</source>
    18781916        <translation type="unfinished"></translation>
    18791917    </message>
    18801918    <message>
    1881         <location filename="torrent.cc" line="679"/>
     1919        <location filename="torrent.cc" line="685"/>
    18821920        <source>Downloading</source>
    18831921        <translation type="unfinished"></translation>
    18841922    </message>
    18851923    <message>
    1886         <location filename="torrent.cc" line="680"/>
     1924        <location filename="torrent.cc" line="686"/>
    18871925        <source>Seeding</source>
    18881926        <translation type="unfinished"></translation>
    18891927    </message>
    18901928    <message>
    1891         <location filename="torrent.cc" line="681"/>
     1929        <location filename="torrent.cc" line="687"/>
    18921930        <source>Finished</source>
    18931931        <translation type="unfinished"></translation>
    18941932    </message>
    18951933    <message>
    1896         <location filename="torrent.cc" line="681"/>
     1934        <location filename="torrent.cc" line="687"/>
    18971935        <source>Paused</source>
    18981936        <translation type="unfinished"></translation>
    18991937    </message>
    19001938    <message>
    1901         <location filename="torrent.cc" line="694"/>
     1939        <location filename="torrent.cc" line="700"/>
    19021940        <source>Tracker gave a warning: %1</source>
    19031941        <translation type="unfinished"></translation>
    19041942    </message>
    19051943    <message>
    1906         <location filename="torrent.cc" line="695"/>
     1944        <location filename="torrent.cc" line="701"/>
    19071945        <source>Tracker gave an error: %1</source>
    19081946        <translation type="unfinished"></translation>
    19091947    </message>
    19101948    <message>
    1911         <location filename="torrent.cc" line="696"/>
     1949        <location filename="torrent.cc" line="702"/>
    19121950        <source>Error: %1</source>
    19131951        <translation type="unfinished"></translation>
     
    19481986    <message>
    19491987        <location filename="torrent-delegate.cc" line="150"/>
    1950         <location filename="torrent-delegate.cc" line="250"/>
     1988        <location filename="torrent-delegate.cc" line="252"/>
    19511989        <source> - </source>
    19521990        <translation type="unfinished"></translation>
     
    19632001    </message>
    19642002    <message>
    1965         <location filename="torrent-delegate.cc" line="174"/>
    1966         <source>Down: %1, Up: %2</source>
    1967         <translation type="unfinished"></translation>
    1968     </message>
    1969     <message>
    19702003        <location filename="torrent-delegate.cc" line="176"/>
    1971         <source>Down: %1</source>
     2004        <source>%1 %2, %3 %4</source>
    19722005        <translation type="unfinished"></translation>
    19732006    </message>
    19742007    <message>
    19752008        <location filename="torrent-delegate.cc" line="178"/>
    1976         <source>Up: %1</source>
    1977         <translation type="unfinished"></translation>
    1978     </message>
    1979     <message>
    19802009        <location filename="torrent-delegate.cc" line="180"/>
     2010        <source>%1 %2</source>
     2011        <oldsource>Up: %1</oldsource>
     2012        <translation type="unfinished"></translation>
     2013    </message>
     2014    <message>
     2015        <location filename="torrent-delegate.cc" line="182"/>
    19812016        <source>Idle</source>
    19822017        <translation type="unfinished"></translation>
    19832018    </message>
    19842019    <message>
    1985         <location filename="torrent-delegate.cc" line="193"/>
     2020        <location filename="torrent-delegate.cc" line="195"/>
    19862021        <source>Verifying local data (%1% tested)</source>
    19872022        <translation type="unfinished"></translation>
    19882023    </message>
    19892024    <message>
    1990         <location filename="torrent-delegate.cc" line="199"/>
     2025        <location filename="torrent-delegate.cc" line="201"/>
    19912026        <source>Ratio: %1, </source>
    19922027        <translation type="unfinished"></translation>
    19932028    </message>
    19942029    <message numerus="yes">
    1995         <location filename="torrent-delegate.cc" line="230"/>
     2030        <location filename="torrent-delegate.cc" line="232"/>
    19962031        <source>Downloading from %1 of %n connected peer(s)</source>
    19972032        <translation>
     
    20012036    </message>
    20022037    <message numerus="yes">
    2003         <location filename="torrent-delegate.cc" line="233"/>
     2038        <location filename="torrent-delegate.cc" line="235"/>
    20042039        <source>Downloading metadata from %n peer(s) (%1% done)</source>
    20052040        <translation type="unfinished">
    20062041            <numerusform></numerusform>
    2007             <numerusform></numerusform>
    20082042        </translation>
    20092043    </message>
    20102044    <message numerus="yes">
    2011         <location filename="torrent-delegate.cc" line="238"/>
     2045        <location filename="torrent-delegate.cc" line="240"/>
    20122046        <source>Seeding to %1 of %n connected peer(s)</source>
    20132047        <translation>
     
    22362270            <numerusform>%L1 of %Ln Torrents</numerusform>
    22372271        </translation>
     2272    </message>
     2273</context>
     2274<context>
     2275    <name>TrackerDelegate</name>
     2276    <message>
     2277        <location filename="tracker-delegate.cc" line="161"/>
     2278        <source>Got a list of %1%2 peers%3 %4 ago</source>
     2279        <translation type="unfinished"></translation>
     2280    </message>
     2281    <message>
     2282        <location filename="tracker-delegate.cc" line="169"/>
     2283        <source>Peer list request timed out %1%2%3 ago; will retry</source>
     2284        <translation type="unfinished"></translation>
     2285    </message>
     2286    <message>
     2287        <location filename="tracker-delegate.cc" line="176"/>
     2288        <source>Got an error %1&apos;%2&apos;%3 %4 ago</source>
     2289        <translation type="unfinished"></translation>
     2290    </message>
     2291    <message>
     2292        <location filename="tracker-delegate.cc" line="189"/>
     2293        <source>No updates scheduled</source>
     2294        <translation type="unfinished"></translation>
     2295    </message>
     2296    <message>
     2297        <location filename="tracker-delegate.cc" line="196"/>
     2298        <source>Asking for more peers in %1</source>
     2299        <translation type="unfinished"></translation>
     2300    </message>
     2301    <message>
     2302        <location filename="tracker-delegate.cc" line="202"/>
     2303        <source>Queued to ask for more peers</source>
     2304        <translation type="unfinished"></translation>
     2305    </message>
     2306    <message>
     2307        <location filename="tracker-delegate.cc" line="208"/>
     2308        <source>Asking for more peers now... &lt;small&gt;%1&lt;/small&gt;</source>
     2309        <translation type="unfinished"></translation>
     2310    </message>
     2311    <message>
     2312        <location filename="tracker-delegate.cc" line="221"/>
     2313        <source>Tracker had %1%2 seeders%3 and %4%5 leechers%6 %7 ago</source>
     2314        <translation type="unfinished"></translation>
     2315    </message>
     2316    <message>
     2317        <location filename="tracker-delegate.cc" line="232"/>
     2318        <source>Got a scrape error %1&apos;%2&apos;%3 %4 ago</source>
     2319        <translation type="unfinished"></translation>
     2320    </message>
     2321    <message>
     2322        <location filename="tracker-delegate.cc" line="248"/>
     2323        <source>Asking for peer counts in %1</source>
     2324        <translation type="unfinished"></translation>
     2325    </message>
     2326    <message>
     2327        <location filename="tracker-delegate.cc" line="254"/>
     2328        <source>Queued to ask for peer counts</source>
     2329        <translation type="unfinished"></translation>
     2330    </message>
     2331    <message>
     2332        <location filename="tracker-delegate.cc" line="261"/>
     2333        <source>Asking for peer counts now... &lt;small&gt;%1&lt;/small&gt;</source>
     2334        <translation type="unfinished"></translation>
    22382335    </message>
    22392336</context>
  • trunk/qt/transmission_ru.ts

    r10957 r11059  
    18981898    <name>Details</name>
    18991899    <message>
    1900         <location filename="details.cc" line="145"/>
     1900        <location filename="details.cc" line="151"/>
    19011901        <source>Torrent Properties</source>
    19021902        <translation>СвПйства тПрреМта</translation>
    19031903    </message>
    19041904    <message>
    1905         <location filename="details.cc" line="149"/>
     1905        <location filename="details.cc" line="155"/>
    19061906        <source>Information</source>
    19071907        <translation>СвеЎеМОя</translation>
    19081908    </message>
    19091909    <message>
    1910         <location filename="details.cc" line="151"/>
     1910        <location filename="details.cc" line="157"/>
    19111911        <source>Peers</source>
    19121912        <translation>Узлы</translation>
    19131913    </message>
    19141914    <message>
    1915         <location filename="details.cc" line="153"/>
     1915        <location filename="details.cc" line="159"/>
    19161916        <source>Tracker</source>
    19171917        <translation>Трекер</translation>
    19181918    </message>
    19191919    <message>
    1920         <location filename="details.cc" line="155"/>
     1920        <location filename="details.cc" line="161"/>
    19211921        <source>Files</source>
    19221922        <translation>Ѐайлы</translation>
    19231923    </message>
    19241924    <message>
    1925         <location filename="details.cc" line="157"/>
     1925        <location filename="details.cc" line="163"/>
    19261926        <source>Options</source>
    19271927        <translation>ПараЌетры</translation>
    19281928    </message>
    19291929    <message>
    1930         <location filename="details.cc" line="256"/>
     1930        <location filename="details.cc" line="287"/>
    19311931        <source>None</source>
    19321932        <translation>Н/Д</translation>
    19331933    </message>
    19341934    <message>
    1935         <location filename="details.cc" line="257"/>
     1935        <location filename="details.cc" line="288"/>
    19361936        <source>Mixed</source>
    19371937        <translation>СЌешаММый</translation>
    19381938    </message>
    19391939    <message>
    1940         <location filename="details.cc" line="258"/>
    1941         <location filename="details.cc" line="441"/>
     1940        <location filename="details.cc" line="289"/>
     1941        <location filename="details.cc" line="472"/>
    19421942        <source>Unknown</source>
    19431943        <translation>НеОзвестМП</translation>
    19441944    </message>
    19451945    <message>
    1946         <location filename="details.cc" line="290"/>
     1946        <location filename="details.cc" line="321"/>
    19471947        <source>Finished</source>
    19481948        <translation type="unfinished"></translation>
    19491949    </message>
    19501950    <message>
    1951         <location filename="details.cc" line="292"/>
     1951        <location filename="details.cc" line="323"/>
    19521952        <source>Paused</source>
    19531953        <translation type="unfinished">ПрОПстаМПвлеМ</translation>
    19541954    </message>
    19551955    <message>
    1956         <location filename="details.cc" line="328"/>
     1956        <location filename="details.cc" line="359"/>
    19571957        <source>%1 (%2%)</source>
    19581958        <translation></translation>
    19591959    </message>
    19601960    <message>
    1961         <location filename="details.cc" line="332"/>
     1961        <location filename="details.cc" line="363"/>
    19621962        <source>%1 (%2%); %3 Unverified</source>
    19631963        <translation>%1 (%2%); %3 МепрПвереМ</translation>
    19641964    </message>
    19651965    <message>
    1966         <location filename="details.cc" line="363"/>
     1966        <location filename="details.cc" line="394"/>
    19671967        <source>%1 (+%2 corrupt)</source>
    19681968        <translation>%1 (+%2 ОспПрчеМ)</translation>
     
    19731973    </message>
    19741974    <message>
    1975         <location filename="details.cc" line="461"/>
     1975        <location filename="details.cc" line="492"/>
    19761976        <source>Active now</source>
    19771977        <translation>АктОвОзОрПваМ</translation>
    19781978    </message>
    19791979    <message>
    1980         <location filename="details.cc" line="463"/>
     1980        <location filename="details.cc" line="494"/>
    19811981        <source>%1 ago</source>
    19821982        <translation>%1 МазаЎ</translation>
    19831983    </message>
    19841984    <message numerus="yes">
    1985         <location filename="details.cc" line="504"/>
     1985        <location filename="details.cc" line="535"/>
    19861986        <source>%1 (%Ln pieces @ %2)</source>
    19871987        <translation>
     
    19921992    </message>
    19931993    <message numerus="yes">
    1994         <location filename="details.cc" line="508"/>
     1994        <location filename="details.cc" line="539"/>
    19951995        <source>%1 (%Ln pieces)</source>
    19961996        <translation>
     
    20012001    </message>
    20022002    <message>
    2003         <location filename="details.cc" line="532"/>
     2003        <location filename="details.cc" line="563"/>
    20042004        <source>Private to this tracker -- DHT and PEX disabled</source>
    20052005        <translation>ПрОватМП Ўля этПгП трекера -- DHT О PEX выключеМы</translation>
    20062006    </message>
    20072007    <message>
    2008         <location filename="details.cc" line="533"/>
     2008        <location filename="details.cc" line="564"/>
    20092009        <source>Public torrent</source>
    20102010        <translation>ПублОчМый тПрреМт</translation>
    20112011    </message>
    20122012    <message>
    2013         <location filename="details.cc" line="572"/>
     2013        <location filename="details.cc" line="603"/>
    20142014        <source>Created by %1</source>
    20152015        <translation>СПзЎаМП прО пПЌПщО %1</translation>
    20162016    </message>
    20172017    <message>
    2018         <location filename="details.cc" line="574"/>
     2018        <location filename="details.cc" line="605"/>
    20192019        <source>Created on %1</source>
    20202020        <translation>СПзЎаМП %1</translation>
    20212021    </message>
    20222022    <message>
    2023         <location filename="details.cc" line="576"/>
     2023        <location filename="details.cc" line="607"/>
    20242024        <source>Created by %1 on %2</source>
    20252025        <translation>СПзЎаМП %2 прО пПЌПщО %1</translation>
     
    20302030    </message>
    20312031    <message>
    2032         <location filename="details.cc" line="735"/>
     2032        <location filename="details.cc" line="778"/>
    20332033        <source>Got a list of %1 peers %2 ago</source>
    20342034        <translation type="unfinished"></translation>
    20352035    </message>
    20362036    <message>
    2037         <location filename="details.cc" line="741"/>
     2037        <location filename="details.cc" line="784"/>
    20382038        <source>Peer list request timed out %1 ago; will retry</source>
    20392039        <translation type="unfinished"></translation>
    20402040    </message>
    20412041    <message>
    2042         <location filename="details.cc" line="746"/>
     2042        <location filename="details.cc" line="789"/>
    20432043        <source>Got an error %1 ago</source>
    20442044        <translation type="unfinished"></translation>
    20452045    </message>
    20462046    <message>
    2047         <location filename="details.cc" line="756"/>
     2047        <location filename="details.cc" line="799"/>
    20482048        <source>No updates scheduled</source>
    20492049        <translation type="unfinished"></translation>
    20502050    </message>
    20512051    <message>
    2052         <location filename="details.cc" line="763"/>
     2052        <location filename="details.cc" line="806"/>
    20532053        <source>Asking for more peers in %1</source>
    20542054        <translation type="unfinished"></translation>
    20552055    </message>
    20562056    <message>
    2057         <location filename="details.cc" line="769"/>
     2057        <location filename="details.cc" line="812"/>
    20582058        <source>Queued to ask for more peers</source>
    20592059        <translation type="unfinished"></translation>
    20602060    </message>
    20612061    <message>
    2062         <location filename="details.cc" line="775"/>
     2062        <location filename="details.cc" line="818"/>
    20632063        <source>Asking for more peers now... %1</source>
    20642064        <translation type="unfinished"></translation>
    20652065    </message>
    20662066    <message>
    2067         <location filename="details.cc" line="788"/>
     2067        <location filename="details.cc" line="831"/>
    20682068        <source>Tracker had %1 seeders and %2 leechers %3 ago</source>
    20692069        <translation type="unfinished"></translation>
    20702070    </message>
    20712071    <message>
    2072         <location filename="details.cc" line="795"/>
     2072        <location filename="details.cc" line="838"/>
    20732073        <source>Got a scrape error %1 ago</source>
    20742074        <translation type="unfinished"></translation>
    20752075    </message>
    20762076    <message>
    2077         <location filename="details.cc" line="807"/>
     2077        <location filename="details.cc" line="850"/>
    20782078        <source>Asking for peer counts in %1</source>
    20792079        <translation type="unfinished"></translation>
    20802080    </message>
    20812081    <message>
    2082         <location filename="details.cc" line="813"/>
     2082        <location filename="details.cc" line="856"/>
    20832083        <source>Queued to ask for peer counts</source>
    20842084        <translation type="unfinished"></translation>
    20852085    </message>
    20862086    <message>
    2087         <location filename="details.cc" line="819"/>
     2087        <location filename="details.cc" line="862"/>
    20882088        <source>Asking for peer counts now... %1</source>
    20892089        <translation type="unfinished"></translation>
    20902090    </message>
    20912091    <message>
    2092         <location filename="details.cc" line="883"/>
    2093         <location filename="details.cc" line="904"/>
     2092        <location filename="details.cc" line="926"/>
     2093        <location filename="details.cc" line="947"/>
    20942094        <source>Encrypted connection</source>
    20952095        <translation>ЗашОфрПваММПе сПеЎОМеМОе</translation>
    20962096    </message>
    20972097    <message>
    2098         <location filename="details.cc" line="897"/>
     2098        <location filename="details.cc" line="940"/>
    20992099        <source>Optimistic unchoke</source>
    21002100        <translation>БлагПпрОятМая переЎача</translation>
    21012101    </message>
    21022102    <message>
    2103         <location filename="details.cc" line="898"/>
     2103        <location filename="details.cc" line="941"/>
    21042104        <source>Downloading from this peer</source>
    21052105        <translation>Загрузка с этПгП узла</translation>
    21062106    </message>
    21072107    <message>
    2108         <location filename="details.cc" line="899"/>
     2108        <location filename="details.cc" line="942"/>
    21092109        <source>We would download from this peer if they would let us</source>
    21102110        <translation>ВПзЌПжеМ прОёЌ ЎаММыÑ
     
    21122112    </message>
    21132113    <message>
    2114         <location filename="details.cc" line="900"/>
     2114        <location filename="details.cc" line="943"/>
    21152115        <source>Uploading to peer</source>
    21162116        <translation>ПереЎача узлу</translation>
    21172117    </message>
    21182118    <message>
    2119         <location filename="details.cc" line="901"/>
     2119        <location filename="details.cc" line="944"/>
    21202120        <source>We would upload to this peer if they asked</source>
    21212121        <translation>ВПзЌПжМа разЎача ЎаММыÑ
     
    21232123    </message>
    21242124    <message>
    2125         <location filename="details.cc" line="902"/>
     2125        <location filename="details.cc" line="945"/>
    21262126        <source>Peer has unchoked us, but we&apos;re not interested</source>
    21272127        <translation>Узел сПгласеМ переЎавать ЎаММые, МП Ќы Ме заОМтересПваМы</translation>
    21282128    </message>
    21292129    <message>
    2130         <location filename="details.cc" line="903"/>
     2130        <location filename="details.cc" line="946"/>
    21312131        <source>We unchoked this peer, but they&apos;re not interested</source>
    21322132        <translation>ПереЎача узлу была разрешеМа, МП ПМ Ме заОМтересПваМ</translation>
    21332133    </message>
    21342134    <message>
    2135         <location filename="details.cc" line="905"/>
     2135        <location filename="details.cc" line="948"/>
    21362136        <source>Peer was discovered through DHT</source>
    21372137        <translation type="unfinished"></translation>
    21382138    </message>
    21392139    <message>
    2140         <location filename="details.cc" line="906"/>
     2140        <location filename="details.cc" line="949"/>
    21412141        <source>Peer was discovered through Peer Exchange (PEX)</source>
    21422142        <translation>Узел был ПбМаружеМ с пПЌПщью ПбЌеМа узлаЌО (PEX)</translation>
    21432143    </message>
    21442144    <message>
    2145         <location filename="details.cc" line="907"/>
     2145        <location filename="details.cc" line="950"/>
    21462146        <source>Peer is an incoming connection</source>
    21472147        <translation>Узел рабПтает в режОЌе прОёЌа</translation>
    21482148    </message>
    21492149    <message>
    2150         <location filename="details.cc" line="963"/>
     2150        <location filename="details.cc" line="1006"/>
    21512151        <source>Activity</source>
    21522152        <translation>АктОвМПсть</translation>
    21532153    </message>
    21542154    <message>
    2155         <location filename="details.cc" line="964"/>
     2155        <location filename="details.cc" line="1007"/>
    21562156        <source>Torrent size:</source>
    21572157        <translation>РазЌер тПрреМта:</translation>
    21582158    </message>
    21592159    <message>
    2160         <location filename="details.cc" line="965"/>
     2160        <location filename="details.cc" line="1008"/>
    21612161        <source>Have:</source>
    21622162        <translation>В МалОчОО:</translation>
    21632163    </message>
    21642164    <message>
    2165         <location filename="details.cc" line="966"/>
     2165        <location filename="details.cc" line="1009"/>
    21662166        <source>Availability:</source>
    21672167        <translation type="unfinished"></translation>
    21682168    </message>
    21692169    <message>
    2170         <location filename="details.cc" line="967"/>
     2170        <location filename="details.cc" line="1010"/>
    21712171        <source>Downloaded:</source>
    21722172        <translation>ЗагружеМП:</translation>
    21732173    </message>
    21742174    <message>
    2175         <location filename="details.cc" line="968"/>
     2175        <location filename="details.cc" line="1011"/>
    21762176        <source>Uploaded:</source>
    21772177        <translation>РПзЎаМП:</translation>
    21782178    </message>
    21792179    <message>
    2180         <location filename="details.cc" line="969"/>
     2180        <location filename="details.cc" line="1012"/>
    21812181        <source>Ratio:</source>
    21822182        <translation>РейтОМг:</translation>
    21832183    </message>
    21842184    <message>
    2185         <location filename="details.cc" line="970"/>
     2185        <location filename="details.cc" line="1013"/>
    21862186        <source>State:</source>
    21872187        <translation>СПстПяМОе:</translation>
    21882188    </message>
    21892189    <message>
    2190         <location filename="details.cc" line="971"/>
     2190        <location filename="details.cc" line="1014"/>
    21912191        <source>Running time:</source>
    21922192        <translation>ДлОтельМПсть:</translation>
    21932193    </message>
    21942194    <message>
    2195         <location filename="details.cc" line="972"/>
     2195        <location filename="details.cc" line="1015"/>
    21962196        <source>Remaining time:</source>
    21972197        <translation type="unfinished"></translation>
    21982198    </message>
    21992199    <message>
    2200         <location filename="details.cc" line="973"/>
     2200        <location filename="details.cc" line="1016"/>
    22012201        <source>Last activity:</source>
    22022202        <translation>ППслеЎМяя актОвМПсть:</translation>
    22032203    </message>
    22042204    <message>
    2205         <location filename="details.cc" line="974"/>
     2205        <location filename="details.cc" line="1017"/>
    22062206        <source>Error:</source>
    22072207        <translation>ОшОбка:</translation>
    22082208    </message>
    22092209    <message>
    2210         <location filename="details.cc" line="978"/>
     2210        <location filename="details.cc" line="1021"/>
    22112211        <source>Details</source>
    22122212        <translation>ППЎрПбМПстО</translation>
    22132213    </message>
    22142214    <message>
    2215         <location filename="details.cc" line="979"/>
     2215        <location filename="details.cc" line="1022"/>
    22162216        <source>Location:</source>
    22172217        <translation>МестПМаÑ
     
    22192219    </message>
    22202220    <message>
    2221         <location filename="details.cc" line="980"/>
     2221        <location filename="details.cc" line="1023"/>
    22222222        <source>Hash:</source>
    22232223        <translation>Хеш:</translation>
    22242224    </message>
    22252225    <message>
    2226         <location filename="details.cc" line="981"/>
     2226        <location filename="details.cc" line="1024"/>
    22272227        <source>Privacy:</source>
    22282228        <translation>КПМфОЎеМцОальМПсть:</translation>
    22292229    </message>
    22302230    <message>
    2231         <location filename="details.cc" line="982"/>
     2231        <location filename="details.cc" line="1025"/>
    22322232        <source>Origin:</source>
    22332233        <translation>ПрПОсÑ
     
    22352235    </message>
    22362236    <message>
    2237         <location filename="details.cc" line="984"/>
     2237        <location filename="details.cc" line="1027"/>
    22382238        <source>Comment:</source>
    22392239        <translation>КПЌЌеМтарОй:</translation>
    22402240    </message>
    22412241    <message>
    2242         <location filename="details.cc" line="1100"/>
     2242        <location filename="details.cc" line="1125"/>
    22432243        <source>Add tracker announce URL </source>
    22442244        <translation type="unfinished"></translation>
    22452245    </message>
    22462246    <message>
    2247         <location filename="details.cc" line="1124"/>
     2247        <location filename="details.cc" line="1137"/>
     2248        <location filename="details.cc" line="1165"/>
     2249        <source>Error</source>
     2250        <translation type="unfinished">ПшОбПк</translation>
     2251    </message>
     2252    <message>
     2253        <location filename="details.cc" line="1137"/>
     2254        <source>Tracker already exists.</source>
     2255        <translation type="unfinished"></translation>
     2256    </message>
     2257    <message>
     2258        <location filename="details.cc" line="1158"/>
    22482259        <source>Edit tracker announce URL </source>
    22492260        <translation type="unfinished"></translation>
    22502261    </message>
    22512262    <message>
    2252         <location filename="details.cc" line="1196"/>
     2263        <location filename="details.cc" line="1165"/>
     2264        <source>Invalid URL &quot;%1&quot;</source>
     2265        <translation type="unfinished"></translation>
     2266    </message>
     2267    <message>
     2268        <location filename="details.cc" line="1213"/>
    22532269        <source>Speed</source>
    22542270        <translation>СкПрПсть</translation>
    22552271    </message>
    22562272    <message>
    2257         <location filename="details.cc" line="1198"/>
     2273        <location filename="details.cc" line="1215"/>
    22582274        <source>Honor global &amp;limits</source>
    22592275        <translation>ИспПльзПвать &amp;глПбальМые ПграМОчеМОя</translation>
    22602276    </message>
    22612277    <message>
    2262         <location filename="details.cc" line="1203"/>
     2278        <location filename="details.cc" line="1220"/>
    22632279        <source>Limit &amp;download speed (%1):</source>
    22642280        <translation type="unfinished"></translation>
    22652281    </message>
    22662282    <message>
    2267         <location filename="details.cc" line="1213"/>
     2283        <location filename="details.cc" line="1230"/>
    22682284        <source>Limit &amp;upload speed (%1):</source>
    22692285        <translation type="unfinished"></translation>
    22702286    </message>
    22712287    <message>
    2272         <location filename="details.cc" line="1297"/>
     2288        <location filename="details.cc" line="1249"/>
     2289        <source>Seeding Limits</source>
     2290        <translation type="unfinished">РазЎача</translation>
     2291    </message>
     2292    <message>
     2293        <location filename="details.cc" line="1254"/>
     2294        <location filename="details.cc" line="1268"/>
     2295        <source>Use Global Settings</source>
     2296        <translation type="unfinished"></translation>
     2297    </message>
     2298    <message>
     2299        <location filename="details.cc" line="1255"/>
     2300        <source>Seed regardless of ratio</source>
     2301        <translation type="unfinished"></translation>
     2302    </message>
     2303    <message>
     2304        <location filename="details.cc" line="1256"/>
     2305        <source>Stop seeding at ratio:</source>
     2306        <translation type="unfinished"></translation>
     2307    </message>
     2308    <message>
     2309        <location filename="details.cc" line="1263"/>
     2310        <source>&amp;Ratio:</source>
     2311        <translation type="unfinished"></translation>
     2312    </message>
     2313    <message>
     2314        <location filename="details.cc" line="1269"/>
     2315        <source>Seed regardless of activity</source>
     2316        <translation type="unfinished"></translation>
     2317    </message>
     2318    <message>
     2319        <location filename="details.cc" line="1270"/>
     2320        <source>Stop seeding if idle for N minutes:</source>
     2321        <translation type="unfinished"></translation>
     2322    </message>
     2323    <message>
     2324        <location filename="details.cc" line="1277"/>
     2325        <source>&amp;Idle:</source>
     2326        <translation type="unfinished"></translation>
     2327    </message>
     2328    <message>
    22732329        <source>Trackers</source>
    2274         <translation type="unfinished">Трекеры</translation>
    2275     </message>
    2276     <message>
    2277         <location filename="details.cc" line="1340"/>
     2330        <translation type="obsolete">Трекеры</translation>
     2331    </message>
     2332    <message>
     2333        <location filename="details.cc" line="1359"/>
    22782334        <source>Show &amp;more details</source>
    22792335        <translation type="unfinished"></translation>
     
    22882344    </message>
    22892345    <message>
    2290         <location filename="details.cc" line="1224"/>
     2346        <location filename="details.cc" line="1241"/>
    22912347        <source>High</source>
    22922348        <translation>ВысПкОй</translation>
    22932349    </message>
    22942350    <message>
    2295         <location filename="details.cc" line="1225"/>
     2351        <location filename="details.cc" line="1242"/>
    22962352        <source>Normal</source>
    22972353        <translation>ОбычМый</translation>
    22982354    </message>
    22992355    <message>
    2300         <location filename="details.cc" line="1226"/>
     2356        <location filename="details.cc" line="1243"/>
    23012357        <source>Low</source>
    23022358        <translation>НОзкОй</translation>
    23032359    </message>
    23042360    <message>
    2305         <location filename="details.cc" line="1228"/>
     2361        <location filename="details.cc" line="1245"/>
    23062362        <source>Torrent &amp;priority:</source>
    23072363        <translation>&amp;ПрОПрОтет тПрреМта:</translation>
    23082364    </message>
    23092365    <message>
    2310         <location filename="details.cc" line="1232"/>
    23112366        <source>Seed-Until Ratio</source>
    2312         <translation>РейтОМг Ўля завершеМОя разЎачО</translation>
    2313     </message>
    2314     <message>
    2315         <location filename="details.cc" line="1234"/>
     2367        <translation type="obsolete">РейтОМг Ўля завершеМОя разЎачО</translation>
     2368    </message>
     2369    <message>
    23162370        <source>Use &amp;global settings</source>
    2317         <translation>ИспПльзПвать &amp;глПбальМые МастрПйкО</translation>
    2318     </message>
    2319     <message>
    2320         <location filename="details.cc" line="1240"/>
     2371        <translation type="obsolete">ИспПльзПвать &amp;глПбальМые МастрПйкО</translation>
     2372    </message>
     2373    <message>
    23212374        <source>Seed &amp;regardless of ratio</source>
    2322         <translation>РазЎавать &amp;МесЌПтря Ма рейтОМг</translation>
    2323     </message>
    2324     <message>
    2325         <location filename="details.cc" line="1248"/>
     2375        <translation type="obsolete">РазЎавать &amp;МесЌПтря Ма рейтОМг</translation>
     2376    </message>
     2377    <message>
    23262378        <source>&amp;Seed torrent until its ratio reaches:</source>
    2327         <translation>&amp;РазЎавать ЎП ЎПстОжеМОя рейтОМга:</translation>
    2328     </message>
    2329     <message>
    2330         <location filename="details.cc" line="1261"/>
     2379        <translation type="obsolete">&amp;РазЎавать ЎП ЎПстОжеМОя рейтОМга:</translation>
     2380    </message>
     2381    <message>
     2382        <location filename="details.cc" line="1281"/>
    23312383        <source>Peer Connections</source>
    23322384        <translation>СПеЎОМеМОя с узлаЌО</translation>
    23332385    </message>
    23342386    <message>
    2335         <location filename="details.cc" line="1267"/>
     2387        <location filename="details.cc" line="1287"/>
    23362388        <source>&amp;Maximum peers:</source>
    23372389        <translation>&amp;МаксОЌальМПе кПлОчествП узлПв:</translation>
     
    23752427    </message>
    23762428    <message>
    2377         <location filename="details.cc" line="1362"/>
     2429        <location filename="details.cc" line="1381"/>
    23782430        <source>Up</source>
    23792431        <translation>РазЎача</translation>
    23802432    </message>
    23812433    <message>
    2382         <location filename="details.cc" line="1362"/>
     2434        <location filename="details.cc" line="1381"/>
    23832435        <source>Down</source>
    23842436        <translation>ПрОёЌ</translation>
    23852437    </message>
    23862438    <message>
    2387         <location filename="details.cc" line="1362"/>
     2439        <location filename="details.cc" line="1381"/>
    23882440        <source>%</source>
    23892441        <translation>%</translation>
    23902442    </message>
    23912443    <message>
    2392         <location filename="details.cc" line="1362"/>
     2444        <location filename="details.cc" line="1381"/>
    23932445        <source>Status</source>
    23942446        <translation>СПстПяМОе</translation>
    23952447    </message>
    23962448    <message>
    2397         <location filename="details.cc" line="1362"/>
     2449        <location filename="details.cc" line="1381"/>
    23982450        <source>Address</source>
    23992451        <translation>АЎрес</translation>
    24002452    </message>
    24012453    <message>
    2402         <location filename="details.cc" line="1362"/>
     2454        <location filename="details.cc" line="1381"/>
    24032455        <source>Client</source>
    24042456        <translation>КлОеМт</translation>
     
    28362888    <message>
    28372889        <location filename="mainwin.ui" line="336"/>
    2838         <source>Alt+M</source>
    2839         <translation></translation>
     2890        <source>Alt+C</source>
     2891        <oldsource>Alt+M</oldsource>
     2892        <translation type="unfinished"></translation>
    28402893    </message>
    28412894    <message>
     
    34913544    <message>
    34923545        <location filename="prefs-dialog.cc" line="373"/>
    3493         <location filename="prefs-dialog.cc" line="730"/>
     3546        <location filename="prefs-dialog.cc" line="735"/>
    34943547        <source>Status unknown</source>
    34953548        <translation>Статус МеОзвестеМ</translation>
     
    35733626    <message>
    35743627        <location filename="prefs-dialog.cc" line="475"/>
    3575         <location filename="prefs-dialog.cc" line="625"/>
     3628        <location filename="prefs-dialog.cc" line="630"/>
    35763629        <source>Privacy</source>
    35773630        <translation>КПМфОЎеМцОальМПсть</translation>
     
    36653718        <location filename="prefs-dialog.cc" line="583"/>
    36663719        <source>Call scrip&amp;t when torrent is completed</source>
     3720        <translation type="unfinished"></translation>
     3721    </message>
     3722    <message>
     3723        <location filename="prefs-dialog.cc" line="600"/>
     3724        <source>Stop seeding at &amp;ratio:</source>
     3725        <translation type="unfinished"></translation>
     3726    </message>
     3727    <message>
     3728        <location filename="prefs-dialog.cc" line="605"/>
     3729        <source>Stop seeding if idle for &amp;N minutes:</source>
    36673730        <translation type="unfinished"></translation>
    36683731    </message>
     
    36973760    <message>
    36983761        <location filename="prefs-dialog.cc" line="598"/>
    3699         <source>Seeding</source>
     3762        <source>Seeding Limits</source>
     3763        <oldsource>Seeding</oldsource>
    37003764        <translation type="unfinished">РазЎача</translation>
    37013765    </message>
    37023766    <message>
    3703         <location filename="prefs-dialog.cc" line="600"/>
    37043767        <source>&amp;Seed torrent until its ratio reaches:</source>
    3705         <translation>&amp;РазЎавать ЎП ЎПстОжеМОя рейтОМга:</translation>
    3706     </message>
    3707     <message>
    3708         <location filename="prefs-dialog.cc" line="620"/>
     3768        <translation type="obsolete">&amp;РазЎавать ЎП ЎПстОжеМОя рейтОМга:</translation>
     3769    </message>
     3770    <message>
     3771        <location filename="prefs-dialog.cc" line="625"/>
    37093772        <source>Transmission Preferences</source>
    37103773        <translation>ПараЌетры Transmission</translation>
    37113774    </message>
    37123775    <message>
    3713         <location filename="prefs-dialog.cc" line="623"/>
     3776        <location filename="prefs-dialog.cc" line="628"/>
    37143777        <source>Torrents</source>
    37153778        <translation>ТПрреМты</translation>
    37163779    </message>
    37173780    <message>
    3718         <location filename="prefs-dialog.cc" line="624"/>
     3781        <location filename="prefs-dialog.cc" line="629"/>
    37193782        <source>Speed</source>
    37203783        <translation>СкПрПсть</translation>
    37213784    </message>
    37223785    <message>
    3723         <location filename="prefs-dialog.cc" line="626"/>
     3786        <location filename="prefs-dialog.cc" line="631"/>
    37243787        <source>Network</source>
    37253788        <translation>Сеть</translation>
    37263789    </message>
    37273790    <message>
    3728         <location filename="prefs-dialog.cc" line="627"/>
     3791        <location filename="prefs-dialog.cc" line="632"/>
    37293792        <source>Web</source>
    37303793        <translation>Веб-ОМтерфейс</translation>
    37313794    </message>
    37323795    <message>
    3733         <location filename="prefs-dialog.cc" line="656"/>
     3796        <location filename="prefs-dialog.cc" line="661"/>
    37343797        <source>Not supported by remote sessions</source>
    37353798        <translation>Не пПЎЎержОвается уЎалеММыЌО сеаМсаЌО</translation>
    37363799    </message>
    37373800    <message>
    3738         <location filename="prefs-dialog.cc" line="682"/>
     3801        <location filename="prefs-dialog.cc" line="687"/>
    37393802        <source>Enable &amp;blocklist</source>
    37403803        <translation>&amp;ВключОть черМый спОсПк</translation>
    37413804    </message>
    37423805    <message numerus="yes">
    3743         <location filename="prefs-dialog.cc" line="684"/>
     3806        <location filename="prefs-dialog.cc" line="689"/>
    37443807        <source>Enable &amp;blocklist (%Ln rules)</source>
    37453808        <translation>
     
    38063869    <name>Session</name>
    38073870    <message>
    3808         <location filename="session.cc" line="765"/>
     3871        <location filename="session.cc" line="769"/>
    38093872        <source>Add Torrent</source>
    38103873        <translation>ДПбавОть тПрреМт</translation>
     
    39143977    <name>Torrent</name>
    39153978    <message>
    3916         <location filename="torrent.cc" line="677"/>
     3979        <location filename="torrent.cc" line="683"/>
    39173980        <source>Waiting to verify local data</source>
    39183981        <translation>ОжОЎается прПверка лПкальМыÑ
     
    39213984    </message>
    39223985    <message>
    3923         <location filename="torrent.cc" line="678"/>
     3986        <location filename="torrent.cc" line="684"/>
    39243987        <source>Verifying local data</source>
    39253988        <translation>ПрПверка лПкальМыÑ
     
    39283991    </message>
    39293992    <message>
    3930         <location filename="torrent.cc" line="679"/>
     3993        <location filename="torrent.cc" line="685"/>
    39313994        <source>Downloading</source>
    39323995        <translation>ПрОёЌ</translation>
    39333996    </message>
    39343997    <message>
    3935         <location filename="torrent.cc" line="680"/>
     3998        <location filename="torrent.cc" line="686"/>
    39363999        <source>Seeding</source>
    39374000        <translation>РазЎача</translation>
    39384001    </message>
    39394002    <message>
    3940         <location filename="torrent.cc" line="681"/>
     4003        <location filename="torrent.cc" line="687"/>
    39414004        <source>Paused</source>
    39424005        <translation>ПрОПстаМПвлеМ</translation>
    39434006    </message>
    39444007    <message>
    3945         <location filename="torrent.cc" line="681"/>
     4008        <location filename="torrent.cc" line="687"/>
    39464009        <source>Finished</source>
    39474010        <translation type="unfinished"></translation>
    39484011    </message>
    39494012    <message>
    3950         <location filename="torrent.cc" line="694"/>
     4013        <location filename="torrent.cc" line="700"/>
    39514014        <source>Tracker gave a warning: %1</source>
    39524015        <translation type="unfinished"></translation>
    39534016    </message>
    39544017    <message>
    3955         <location filename="torrent.cc" line="695"/>
     4018        <location filename="torrent.cc" line="701"/>
    39564019        <source>Tracker gave an error: %1</source>
    39574020        <translation type="unfinished"></translation>
    39584021    </message>
    39594022    <message>
    3960         <location filename="torrent.cc" line="696"/>
     4023        <location filename="torrent.cc" line="702"/>
    39614024        <source>Error: %1</source>
    39624025        <translation type="unfinished"></translation>
     
    39974060    <message>
    39984061        <location filename="torrent-delegate.cc" line="150"/>
    3999         <location filename="torrent-delegate.cc" line="250"/>
     4062        <location filename="torrent-delegate.cc" line="252"/>
    40004063        <source> - </source>
    40014064        <translation> - </translation>
     
    40124075    </message>
    40134076    <message>
    4014         <location filename="torrent-delegate.cc" line="174"/>
     4077        <location filename="torrent-delegate.cc" line="176"/>
     4078        <source>%1 %2, %3 %4</source>
     4079        <translation type="unfinished">%1, %3 %4 {1 %2,?}</translation>
     4080    </message>
     4081    <message>
    40154082        <source>Down: %1, Up: %2</source>
    4016         <translation>ПрОёЌ: %1, разЎача: %2</translation>
    4017     </message>
    4018     <message>
    4019         <location filename="torrent-delegate.cc" line="176"/>
     4083        <translation type="obsolete">ПрОёЌ: %1, разЎача: %2</translation>
     4084    </message>
     4085    <message>
    40204086        <source>Down: %1</source>
    4021         <translation>ПрОёЌ: %1</translation>
     4087        <translation type="obsolete">ПрОёЌ: %1</translation>
    40224088    </message>
    40234089    <message>
    40244090        <location filename="torrent-delegate.cc" line="178"/>
    4025         <source>Up: %1</source>
    4026         <translation>РазЎача: %1</translation>
    4027     </message>
    4028     <message>
    40294091        <location filename="torrent-delegate.cc" line="180"/>
     4092        <source>%1 %2</source>
     4093        <oldsource>Up: %1</oldsource>
     4094        <translation type="unfinished">РазЎача: %1</translation>
     4095    </message>
     4096    <message>
     4097        <location filename="torrent-delegate.cc" line="182"/>
    40304098        <source>Idle</source>
    40314099        <translation>Нет актОвМПстО</translation>
     
    40424110    </message>
    40434111    <message>
    4044         <location filename="torrent-delegate.cc" line="193"/>
     4112        <location filename="torrent-delegate.cc" line="195"/>
    40454113        <source>Verifying local data (%1% tested)</source>
    40464114        <translation>ПрПверка лПкальМыÑ
     
    40494117    </message>
    40504118    <message>
    4051         <location filename="torrent-delegate.cc" line="199"/>
     4119        <location filename="torrent-delegate.cc" line="201"/>
    40524120        <source>Ratio: %1, </source>
    40534121        <translation>РейтОМг: %1</translation>
    40544122    </message>
    40554123    <message numerus="yes">
    4056         <location filename="torrent-delegate.cc" line="230"/>
     4124        <location filename="torrent-delegate.cc" line="232"/>
    40574125        <source>Downloading from %1 of %n connected peer(s)</source>
    40584126        <translation>
     
    40654133    </message>
    40664134    <message numerus="yes">
    4067         <location filename="torrent-delegate.cc" line="233"/>
     4135        <location filename="torrent-delegate.cc" line="235"/>
    40684136        <source>Downloading metadata from %n peer(s) (%1% done)</source>
    40694137        <translation type="unfinished">
     
    40744142    </message>
    40754143    <message numerus="yes">
    4076         <location filename="torrent-delegate.cc" line="238"/>
     4144        <location filename="torrent-delegate.cc" line="240"/>
    40774145        <source>Seeding to %1 of %n connected peer(s)</source>
    40784146        <translation>
     
    43164384</context>
    43174385<context>
     4386    <name>TrackerDelegate</name>
     4387    <message>
     4388        <location filename="tracker-delegate.cc" line="161"/>
     4389        <source>Got a list of %1%2 peers%3 %4 ago</source>
     4390        <translation type="unfinished"></translation>
     4391    </message>
     4392    <message>
     4393        <location filename="tracker-delegate.cc" line="169"/>
     4394        <source>Peer list request timed out %1%2%3 ago; will retry</source>
     4395        <translation type="unfinished"></translation>
     4396    </message>
     4397    <message>
     4398        <location filename="tracker-delegate.cc" line="176"/>
     4399        <source>Got an error %1&apos;%2&apos;%3 %4 ago</source>
     4400        <translation type="unfinished"></translation>
     4401    </message>
     4402    <message>
     4403        <location filename="tracker-delegate.cc" line="189"/>
     4404        <source>No updates scheduled</source>
     4405        <translation type="unfinished"></translation>
     4406    </message>
     4407    <message>
     4408        <location filename="tracker-delegate.cc" line="196"/>
     4409        <source>Asking for more peers in %1</source>
     4410        <translation type="unfinished"></translation>
     4411    </message>
     4412    <message>
     4413        <location filename="tracker-delegate.cc" line="202"/>
     4414        <source>Queued to ask for more peers</source>
     4415        <translation type="unfinished"></translation>
     4416    </message>
     4417    <message>
     4418        <location filename="tracker-delegate.cc" line="208"/>
     4419        <source>Asking for more peers now... &lt;small&gt;%1&lt;/small&gt;</source>
     4420        <translation type="unfinished"></translation>
     4421    </message>
     4422    <message>
     4423        <location filename="tracker-delegate.cc" line="221"/>
     4424        <source>Tracker had %1%2 seeders%3 and %4%5 leechers%6 %7 ago</source>
     4425        <translation type="unfinished"></translation>
     4426    </message>
     4427    <message>
     4428        <location filename="tracker-delegate.cc" line="232"/>
     4429        <source>Got a scrape error %1&apos;%2&apos;%3 %4 ago</source>
     4430        <translation type="unfinished"></translation>
     4431    </message>
     4432    <message>
     4433        <location filename="tracker-delegate.cc" line="248"/>
     4434        <source>Asking for peer counts in %1</source>
     4435        <translation type="unfinished"></translation>
     4436    </message>
     4437    <message>
     4438        <location filename="tracker-delegate.cc" line="254"/>
     4439        <source>Queued to ask for peer counts</source>
     4440        <translation type="unfinished"></translation>
     4441    </message>
     4442    <message>
     4443        <location filename="tracker-delegate.cc" line="261"/>
     4444        <source>Asking for peer counts now... &lt;small&gt;%1&lt;/small&gt;</source>
     4445        <translation type="unfinished"></translation>
     4446    </message>
     4447</context>
     4448<context>
    43184449    <name>Utils</name>
    43194450    <message>
Note: See TracChangeset for help on using the changeset viewer.