Changeset 10908


Ignore:
Timestamp:
Jun 30, 2010, 5:55:46 AM (12 years ago)
Author:
Longinus00
Message:

(qt) #3362:Edit trackers in transmission-qt

Location:
trunk/qt
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/qt/details.cc

    r10872 r10908  
    2626#include <QHBoxLayout>
    2727#include <QHeaderView>
     28#include <QInputDialog>
    2829#include <QLabel>
     30#include <QMessageBox>
    2931#include <QPushButton>
    3032#include <QRadioButton>
     
    4042
    4143#include <libtransmission/transmission.h>
     44#include <libtransmission/bencode.h>
    4245
    4346#include "details.h"
     
    4548#include "hig.h"
    4649#include "prefs.h"
     50#include "qticonloader.h"
    4751#include "session.h"
    4852#include "squeezelabel.h"
     
    118122***/
    119123
     124QIcon
     125Details :: getStockIcon( const QString& freedesktop_name, int fallback )
     126{
     127    QIcon fallbackIcon;
     128
     129    if( fallback > 0 )
     130        fallbackIcon = style()->standardIcon( QStyle::StandardPixmap( fallback ), 0, this );
     131
     132    return QtIconLoader::icon( freedesktop_name, fallbackIcon );
     133}
     134
    120135Details :: Details( Session& session, Prefs& prefs, TorrentModel& model, QWidget * parent ):
    121136    QDialog( parent, Qt::Dialog ),
     
    658673    // tracker tab
    659674    //
    660     QMap<QString,QTreeWidgetItem*> trackers2;
    661     QList<QTreeWidgetItem*> newItems2;
     675    QMap<QString,QTreeWidgetItem*> trackerTiers;
     676    QMap<QString,QTreeWidgetItem*> trackerItems;
    662677    const time_t now( time( 0 ) );
    663     const bool showBackup = myPrefs.getBool( Prefs::SHOW_BACKUP_TRACKERS );
    664678    const bool showScrape = myPrefs.getBool( Prefs::SHOW_TRACKER_SCRAPES );
    665679    foreach( const Torrent * t, torrents )
    666680    {
    667681        const QString idStr( QString::number( t->id( ) ) );
    668         TrackerStatsList trackerStats = t->trackerStats( );
     682        const TrackerStatsList trackerStats = t->trackerStats( );
    669683
    670684        foreach( const TrackerStat& trackerStat, trackerStats )
    671685        {
    672             const QString key( idStr + ":" + QString::number(trackerStat.id) );
    673             QTreeWidgetItem * item = (QTreeWidgetItem*) myTrackerStats.value( key, 0 );
     686            QFont font;
    674687            QString str;
     688            const QString tierKey( QString::number(trackerStat.tier) );
     689            QTreeWidgetItem * tier = (QTreeWidgetItem*) myTrackerTiers.value( tierKey, 0 );
     690
     691            if( tier == 0 ) // new tier
     692            {
     693                QFont tierFont;
     694                tier = new QTreeWidgetItem( myTrackerTree );
     695                myTrackerTree->addTopLevelItem( tier );
     696                str = "Tier: " + QString::number( trackerStat.tier + 1 );
     697                tier->setText( 0, str );
     698                tierFont.setBold( true );
     699                tier->setFont( 0, tierFont );
     700            }
     701
     702            const QString key( idStr + tierKey + ":" + QString::number( trackerStat.id ) );
     703            QTreeWidgetItem * item = (QTreeWidgetItem*) myTrackerItems.value( key, 0 );
    675704
    676705            if( item == 0 ) // new tracker
    677706            {
    678                 item = new QTreeWidgetItem( myTrackerTree );
    679                 newItems2 << item;
     707                item = new QTreeWidgetItem( tier );
     708                tier->addChild( item );
     709                if( tier->childCount() == 1 )
     710                    tier->setExpanded( true );
    680711            }
    681712            str = trackerStat.host;
    682             if( showBackup || !trackerStat.isBackup)
     713
     714            if( trackerStat.isBackup )
    683715            {
     716                font.setItalic( true );
     717                if( showScrape )
     718                {
     719                    str += "\n";
     720                    str += "Tracker will be used as a backup";
     721                }
     722            }
     723            else
     724            {
     725                font.setItalic( false );
    684726                if( trackerStat.hasAnnounced )
    685727                {
     
    779821                }
    780822            }
    781 
    782823            item->setText( 0, str );
    783 
    784             trackers2.insert( key, item );
    785         }
    786     }
    787     myTrackerTree->addTopLevelItems( newItems2 );
    788     foreach( QString key, myTrackerStats.keys() ) {
    789         if( !trackers2.contains( key ) ) { // tracker has disappeared
    790             QTreeWidgetItem * item = myTrackerStats.value( key, 0 );
    791             myTrackerTree->takeTopLevelItem( myTrackerTree->indexOfTopLevelItem( item ) );
    792             delete item;
    793         }
    794     }
    795     myTrackerStats = trackers2;
     824            item->setFont( 0, font );
     825            item->setData( 0, TRACKERID, trackerStat.id );
     826            item->setData( 0, TRACKERURL, trackerStat.announce );
     827            item->setData( 0, TRACKERTIER, trackerStat.tier );
     828            item->setData( 0, TORRENTID, t->id() );
     829
     830            tier->setData( 0, TRACKERID, -1 );
     831            tier->setData( 0, TRACKERURL, QString() );
     832            tier->setData( 0, TRACKERTIER, trackerStat.tier );
     833            tier->setData( 0, TORRENTID, torrents.count() > 1 ? -1 : t->id() );
     834
     835            trackerTiers.insert( tierKey, tier );
     836            trackerItems.insert( key, item );
     837        }
     838    }
     839    QList<QTreeWidgetItem*> tierList = trackerTiers.values();
     840    QList<QTreeWidgetItem*> itemList = trackerItems.values();
     841    for( int i = 0; i < myTrackerTree->topLevelItemCount(); ++i )
     842    {
     843        QTreeWidgetItem * tier = myTrackerTree->topLevelItem( i );
     844        for( int j = 0; j < tier->childCount(); ++j )
     845        {
     846            if( !itemList.contains( tier->child( j ) ) ) // tracker has disappeared
     847                delete tier->takeChild( j-- );
     848        }
     849        if( !tierList.contains( tier ) ) // tier has disappeared
     850            delete myTrackerTree->takeTopLevelItem( i-- );
     851    }
     852    myTrackerTiers = trackerTiers;
     853    myTrackerItems = trackerItems;
    796854
    797855    ///
     
    935993
    936994void
    937 Details :: onShowBackupTrackersToggled( bool val )
    938 {
    939     myPrefs.set( Prefs::SHOW_BACKUP_TRACKERS, val );
    940 }
    941 
    942 void
    943995Details :: onShowTrackerScrapesToggled( bool val )
    944996{
     
    10101062        mySession.torrentSet( myIds, "bandwidthPriority", priority );
    10111063    }
     1064}
     1065
     1066void
     1067Details :: onTrackerSelectionChanged( )
     1068{
     1069    const QList<QTreeWidgetItem*> items = myTrackerTree->selectedItems();
     1070    if( items.count() == 1 )
     1071        myEditTrackerButton->setEnabled( items.first()->data( 0, TRACKERID ).toInt() >= 0 );
     1072    else
     1073        myEditTrackerButton->setEnabled( false );
     1074    myRemoveTrackerButton->setEnabled( !items.isEmpty() );
     1075}
     1076
     1077bool
     1078Details :: findTrackerByURL( const QString& url, int torId )
     1079{
     1080    bool duplicate = false;
     1081    foreach( QTreeWidgetItem * tracker, myTrackerItems.values() )
     1082    {
     1083        if( tracker->data( 0, TRACKERURL ).toString() == url &&
     1084          ( torId == -1 || tracker->data( 0, TORRENTID ).toInt() == torId ) )
     1085        {
     1086            duplicate = true;
     1087            break;
     1088        }
     1089    }
     1090    return duplicate;
     1091}
     1092
     1093void
     1094Details :: onAddTrackerPushed( )
     1095{
     1096    const QString urlString = QInputDialog::getText( this,
     1097                                                     tr( "Add tracker announce URL " ),
     1098                                                     NULL );
     1099    if( !urlString.isEmpty() )
     1100    {
     1101        if( !findTrackerByURL( urlString, -1 ) )
     1102        {
     1103            QByteArray url = urlString.toUtf8();
     1104            tr_benc top;
     1105
     1106            tr_bencInitDict( &top, 1 );
     1107            tr_bencDictAddStr( &top, "announce", url );
     1108
     1109            mySession.torrentSet( myIds, "trackerAdd", &top );
     1110        }
     1111        else
     1112            QMessageBox::warning( this, "Error", "Tracker already exists." );
     1113    }
     1114}
     1115
     1116void
     1117Details :: onEditTrackerPushed( )
     1118{
     1119    const QTreeWidgetItem * item = myTrackerTree->selectedItems().first();
     1120    const QString urlString = QInputDialog::getText( this,
     1121                                                     tr( "Edit tracker announce URL " ),
     1122                                                     NULL,
     1123                                                     QLineEdit::Normal,
     1124                                                     item->data( 0, TRACKERURL ).toString() );
     1125    if( !urlString.isEmpty() )
     1126    {
     1127        const int torId = item->data( 0, TORRENTID ).toInt();
     1128        if( !findTrackerByURL( urlString, torId ) )
     1129        {
     1130            QByteArray url = urlString.toUtf8();
     1131            QSet<int> ids;
     1132            tr_benc top;
     1133
     1134            ids << torId;
     1135            tr_bencInitDict( &top, 2 );
     1136            tr_bencDictAddStr( &top, "announce", item->data( 0, TRACKERURL ).toByteArray() );
     1137            tr_bencDictAddStr( &top, "announce-new", url );
     1138
     1139            mySession.torrentSet( ids, "trackerEdit", &top );
     1140        }
     1141        else
     1142            QMessageBox::warning( this, "Error", "Tracker already exists." );
     1143    }
     1144}
     1145
     1146void
     1147Details :: removeTracker( const QTreeWidgetItem * item )
     1148{
     1149    QByteArray url = item->data( 0, TRACKERURL ).toByteArray();
     1150    const int torId = item->data( 0, TORRENTID ).toInt();
     1151    QSet<int> ids;
     1152    tr_benc top;
     1153
     1154    ids << torId;
     1155    tr_bencInitDict( &top, 1 );
     1156    tr_bencDictAddStr( &top, "announce", url );
     1157
     1158    mySession.torrentSet( ids, "trackerRemove", &top );
     1159}
     1160
     1161void
     1162Details :: onRemoveTrackerPushed( )
     1163{
     1164    const QTreeWidgetItem * item = myTrackerTree->selectedItems().first();
     1165    const bool isTier = item->data( 0, TRACKERID ).toInt() == -1;
     1166    if( isTier )
     1167    {
     1168        for( int i = 0; i < item->childCount(); ++i )
     1169            removeTracker( item->child( i ) );
     1170    }
     1171    else
     1172        removeTracker( item );
    10121173}
    10131174
     
    11101271{
    11111272    QCheckBox * c;
     1273    QPushButton * p;
    11121274    QWidget * top = new QWidget;
    11131275    QVBoxLayout * v = new QVBoxLayout( top );
    1114 
    1115     v->setSpacing( HIG :: PAD_BIG );
     1276    QHBoxLayout * h = new QHBoxLayout();
     1277    QVBoxLayout * v2 = new QVBoxLayout();
     1278
     1279    v->setSpacing( HIG::PAD_BIG );
    11161280    v->setContentsMargins( HIG::PAD_BIG, HIG::PAD_BIG, HIG::PAD_BIG, HIG::PAD_BIG );
     1281
     1282    h->setSpacing( HIG::PAD );
     1283    h->setContentsMargins( HIG::PAD_SMALL, HIG::PAD_SMALL, HIG::PAD_SMALL, HIG::PAD_SMALL );
     1284
     1285    v2->setSpacing( HIG::PAD );
    11171286
    11181287    QStringList headers;
     
    11201289    myTrackerTree = new QTreeWidget;
    11211290    myTrackerTree->setHeaderLabels( headers );
    1122     myTrackerTree->setSelectionMode( QTreeWidget::NoSelection );
     1291    myTrackerTree->setSelectionMode( QTreeWidget::SingleSelection );
    11231292    myTrackerTree->setRootIsDecorated( false );
     1293    myTrackerTree->setIndentation( 2 );
     1294    myTrackerTree->setItemsExpandable( false );
    11241295    myTrackerTree->setTextElideMode( Qt::ElideRight );
    11251296    myTrackerTree->setAlternatingRowColors( true );
    1126     v->addWidget( myTrackerTree, 1 );
     1297    connect( myTrackerTree, SIGNAL(itemSelectionChanged()), this, SLOT(onTrackerSelectionChanged()));
     1298    h->addWidget( myTrackerTree, 1 );
     1299
     1300    p = new QPushButton();
     1301    p->setIcon( getStockIcon( "list-add", QStyle::SP_DialogOpenButton ) );
     1302    p->setToolTip( "Add Tracker" );
     1303    myAddTrackerButton = p;
     1304    v2->addWidget( p, 1 );
     1305    connect( p, SIGNAL(clicked(bool)), this, SLOT(onAddTrackerPushed()));
     1306
     1307    p = new QPushButton();
     1308    p->setIcon( getStockIcon( "document-properties", QStyle::SP_DesktopIcon ) );
     1309    p->setToolTip( "Edit Tracker" );
     1310    myAddTrackerButton = p;
     1311    p->setEnabled( false );
     1312    myEditTrackerButton = p;
     1313    v2->addWidget( p, 1 );
     1314    connect( p, SIGNAL(clicked(bool)), this, SLOT(onEditTrackerPushed()));
     1315
     1316    p = new QPushButton();
     1317    p->setIcon( getStockIcon( "list-remove", QStyle::SP_TrashIcon ) );
     1318    p->setToolTip( "Remove Trackers" );
     1319    p->setEnabled( false );
     1320    myRemoveTrackerButton = p;
     1321    v2->addWidget( p, 1 );
     1322    connect( p, SIGNAL(clicked(bool)), this, SLOT(onRemoveTrackerPushed()));
     1323
     1324    v2->addStretch( 1 );
     1325
     1326    h->addLayout( v2, 1 );
     1327    h->setStretch( 1, 0 );
     1328
     1329    v->addLayout( h, 1 );
    11271330
    11281331    c = new QCheckBox( tr( "Show &more details" ) );
     
    11311334    v->addWidget( c, 1 );
    11321335    connect( c, SIGNAL(clicked(bool)), this, SLOT(onShowTrackerScrapesToggled(bool)) );
    1133 
    1134     c = new QCheckBox( tr( "Show &backup trackers" ) );
    1135     c->setChecked( myPrefs.getBool( Prefs::SHOW_BACKUP_TRACKERS ) );
    1136     myShowBackupTrackersCheck = c;
    1137     v->addWidget( c, 1 );
    1138     connect( c, SIGNAL(clicked(bool)), this, SLOT(onShowBackupTrackersToggled(bool)) );
    11391336
    11401337    return top;
  • trunk/qt/details.h

    r10627 r10908  
    4242        Q_OBJECT
    4343
     44    private:
     45        enum
     46        {
     47            TRACKERID = Qt::UserRole,
     48            TRACKERURL,
     49            TRACKERTIER,
     50            TORRENTID
     51        };
     52
    4453    private slots:
    4554        void onTorrentChanged( );
     
    5968
    6069    private:
     70        QIcon getStockIcon( const QString& freedesktop_name, int fallback );
    6171        QString timeToStringRounded( int seconds );
    6272        QString trimToDesiredWidth( const QString& str );
    6373        void enableWhenChecked( QCheckBox *, QWidget * );
     74        bool findTrackerByURL( const QString& url, int torId );
     75        void removeTracker( const QTreeWidgetItem * item );
    6476
    6577    private:
    66 
    6778        Session& mySession;
    6879        Prefs& myPrefs;
     
    8899        QCheckBox * mySingleUpCheck;
    89100        QCheckBox * myShowTrackerScrapesCheck;
    90         QCheckBox * myShowBackupTrackersCheck;
     101        QPushButton * myAddTrackerButton;
     102        QPushButton * myEditTrackerButton;
     103        QPushButton * myRemoveTrackerButton;
    91104        QSpinBox * mySingleDownSpin;
    92105        QSpinBox * mySingleUpSpin;
     
    116129        QTreeWidget * myTrackerTree;
    117130        QTreeWidget * myPeerTree;
    118         QMap<QString,QTreeWidgetItem*> myTrackerStats;
     131        QMap<QString,QTreeWidgetItem*> myTrackerTiers;
     132        QMap<QString,QTreeWidgetItem*> myTrackerItems;
    119133        QMap<QString,QTreeWidgetItem*> myPeers;
    120134        QWidgetList myWidgets;
     
    133147        void onSeedUntilChanged( bool );
    134148        void onSeedRatioLimitChanged( double );
    135         void onShowBackupTrackersToggled( bool );
    136149        void onShowTrackerScrapesToggled( bool );
     150        void onTrackerSelectionChanged( );
     151        void onAddTrackerPushed( );
     152        void onEditTrackerPushed( );
     153        void onRemoveTrackerPushed( );
    137154        void onMaxPeersChanged( int );
    138155        void refresh( );
  • trunk/qt/prefs.cc

    r10638 r10908  
    4343    { SORT_REVERSED, "sort-reversed", QVariant::Bool },
    4444    { COMPACT_VIEW, "compact-view", QVariant::Bool },
    45     { SHOW_BACKUP_TRACKERS, "show-backup-trackers", QVariant::Bool },
    4645    { FILTERBAR, "show-filterbar", QVariant::Bool },
    4746    { STATUSBAR, "show-statusbar", QVariant::Bool },
     
    245244    tr_bencDictAddInt( d, keyStr(BLOCKLIST_UPDATES_ENABLED), true );
    246245    tr_bencDictAddStr( d, keyStr(OPEN_DIALOG_FOLDER), QDir::home().absolutePath().toLatin1() );
    247     tr_bencDictAddInt( d, keyStr(SHOW_BACKUP_TRACKERS), false );
    248246    tr_bencDictAddInt( d, keyStr(SHOW_TRACKER_SCRAPES), false );
    249247    tr_bencDictAddInt( d, keyStr(TOOLBAR), true );
  • trunk/qt/prefs.h

    r10638 r10908  
    4646            SORT_REVERSED,
    4747            COMPACT_VIEW,
    48             SHOW_BACKUP_TRACKERS,
    4948            FILTERBAR,
    5049            STATUSBAR,
  • trunk/qt/session.cc

    r10786 r10908  
    415415    foreach( int i, value )
    416416        tr_bencListAddInt( list, i );
     417    exec( &top );
     418    tr_bencFree( &top );
     419}
     420
     421void
     422Session :: torrentSet( const QSet<int>& ids, const QString& key, const tr_benc * value )
     423{
     424    tr_benc top;
     425    tr_bencInitDict( &top, 2 );
     426    tr_bencDictAddStr( &top, "method", "torrent-set" );
     427    tr_benc * args( tr_bencDictAddDict( &top, "arguments", 2 ) );
     428    addOptionalIds( args, ids );
     429    tr_benc * child( tr_bencDictAdd( args, key.toUtf8().constData() ) );
     430    memcpy( child, value, sizeof(tr_benc) );
    417431    exec( &top );
    418432    tr_bencFree( &top );
  • trunk/qt/session.h

    r10769 r10908  
    101101        void torrentSet( const QSet<int>& ids, const QString& key, double val );
    102102        void torrentSet( const QSet<int>& ids, const QString& key, const QList<int>& val );
     103        void torrentSet( const QSet<int>& ids, const QString& key, const tr_benc * value );
    103104        void torrentSetLocation( const QSet<int>& ids, const QString& path, bool doMove );
    104105
Note: See TracChangeset for help on using the changeset viewer.