Changeset 2465


Ignore:
Timestamp:
Jul 23, 2007, 3:20:47 PM (15 years ago)
Author:
charles
Message:
  • make torrent list's columns sortable.
  • remember torrent sort order between sessions.
  • torrent list is getting too big; move it into its own file --This line, and those below, will be ignored--

M wx/Makefile.am
A wx/torrent-list.cc
A wx/torrent-list.h
M wx/xmission.cc

Location:
trunk/wx
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wx/Makefile.am

    r2433 r2465  
    55bin_PROGRAMS = Xmission
    66
    7 Xmission_SOURCES = xmission.cc
     7Xmission_SOURCES = xmission.cc torrent-list.cc
    88
    99Xmission_LDADD = ../libtransmission/libtransmission.a @WX_LIBS@ $(PTHREAD_LIBS) -lm
  • trunk/wx/xmission.cc

    r2464 r2465  
    3131  #include <libtransmission/utils.h>
    3232}
     33#include "torrent-list.h"
    3334
    3435class MyApp : public wxApp
     
    3940IMPLEMENT_APP(MyApp)
    4041
    41 tr_handle_t * handle = NULL;
     42namespace
     43{
     44    tr_handle_t * handle = NULL;
     45
     46    typedef std::vector<tr_torrent_t*> torrents_t;
     47}
    4248
    4349class MyFrame : public wxFrame
     
    4652    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
    4753    virtual ~MyFrame();
    48     void OnQuit(wxCommandEvent& event);
    49     void OnAbout(wxCommandEvent& event);
    50     void OnOpen(wxCommandEvent& event);
    51     void OnTimer(wxTimerEvent& event);
     54    void OnQuit( wxCommandEvent& );
     55    void OnAbout( wxCommandEvent& );
     56    void OnOpen( wxCommandEvent& );
     57    void OnTimer( wxTimerEvent& );
    5258
    5359protected:
     
    5662
    5763private:
    58     void rebuildTorrentList();
    59     void repopulateTorrentList ();
    60     void refreshTorrentList ();
    61     typedef std::vector<tr_torrent_t*> torrents_t;
    62     torrents_t myTorrents;
    63     void refreshTorrent( tr_torrent_t*, int, const std::vector<int>& );
    64 
    65     typedef std::map<std::string,int> str2int_t;
    66 
    67     /** torrent hash -> the torrent's row in myTorrentList */
    68     str2int_t myHashToRow;
    69 
    70     wxListCtrl * myTorrentList;
     64    TorrentListCtrl * myTorrentList;
    7165    wxTaskBarIcon * myTaskBarIcon;
    7266    wxIcon * myLogoIcon;
     
    122116    MyFrame * frame = new MyFrame( _T("Xmission"),
    123117                                   wxPoint(50,50),
    124                                    wxSize(450,350));
     118                                   wxSize(900,600));
    125119
    126120    frame->Connect( wxID_OPEN, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction) &MyFrame::OnOpen );
     
    138132***/
    139133
    140 
    141134namespace
    142135{
    143     enum
    144     {
    145         COL_NUMBER,
    146         COL_DONE,
    147         COL_DOWNLOAD_SPEED,
    148         COL_ETA,
    149         COL_HASH,
    150         COL_NAME,
    151         COL_PEERS,
    152         COL_RATIO,
    153         COL_RECEIVED,
    154         COL_REMAINING,
    155         COL_SEEDS,
    156         COL_SENT,
    157         COL_SIZE,
    158         COL_STATE,
    159         COL_STATUS,
    160         COL_TOTAL,
    161         COL_UPLOAD_SPEED,
    162         N_COLS
    163     };
    164 
    165     int getTorrentColumn( const wxString& key )
    166     {
    167         typedef std::map<wxString,int> string2key_t;
    168         static string2key_t columns;
    169 
    170         if( columns.empty() )
    171         {
    172             columns[_T("#")]         = COL_NUMBER;
    173             columns[_T("done")]      = COL_DONE;
    174             columns[_T("dspeed")]    = COL_DOWNLOAD_SPEED;
    175             columns[_T("eta")]       = COL_ETA;
    176             columns[_T("hash")]      = COL_HASH;
    177             columns[_T("name")]      = COL_NAME;
    178             columns[_T("peers")]     = COL_PEERS;
    179             columns[_T("ratio")]     = COL_RATIO;
    180             columns[_T("received")]  = COL_RECEIVED;
    181             columns[_T("remaining")] = COL_REMAINING;
    182             columns[_T("seeds")]     = COL_SEEDS;
    183             columns[_T("sent")]      = COL_SENT;
    184             columns[_T("size")]      = COL_SIZE;
    185             columns[_T("state")]     = COL_STATE;
    186             columns[_T("status")]    = COL_STATUS;
    187             columns[_T("total")]     = COL_TOTAL;
    188             columns[_T("uspeed")]    = COL_UPLOAD_SPEED;
    189         }
    190 
    191         int i = -1;
    192         string2key_t::const_iterator it = columns.find( key );
    193         if( it != columns.end() )
    194             i = it->second;
    195 
    196         return i;
    197     }
    198 
    199     typedef std::vector<int> int_v;
    200 
    201     int_v getTorrentColumns( wxConfig * config )
    202     {
    203         const wxString key = _T("TorrentListColumns");
    204         wxString columnStr;
    205         if( !config->Read( key, &columnStr ) )
    206             columnStr = _T("name|dspeed|uspeed|eta|peers|size|done|status|seeds");
    207 
    208         int_v cols;
    209         while( !columnStr.IsEmpty() )
    210         {
    211             const wxString key = columnStr.BeforeFirst(_T('|'));
    212             columnStr.Remove( 0, key.Len() + 1 );
    213             cols.push_back( getTorrentColumn( key ) );
    214         }
    215         return cols;
    216     }
    217 
    218136    int bestDecimal( double num ) {
    219137        if ( num < 10 ) return 2;
    220138        if ( num < 100 ) return 1;
    221139        return 0;
    222     }
    223 
    224     wxString toWxStr( const std::string& s )
    225     {
    226         return wxString( s.c_str(), wxConvUTF8 );
    227140    }
    228141
     
    253166        return xstr;
    254167    }
    255 
    256     wxString getReadableTime( int i /*seconds*/ )  /*FIXME*/
    257     {
    258         const int s = i % 60; i /= 60;
    259         const int m = i % 60; i /= 60;
    260         const int h = i;
    261         return wxString::Format( _T("%d:%02d:%02d"), h, m, s );
    262     }
    263 }
    264 
    265 
    266 /***
    267 ****
    268 ****  PEERS LIST
    269 ****
    270 ****
    271 ***/
    272 
    273 
    274 /***
    275 ****
    276 ****  TORRENT LIST
    277 ****
    278 ****
    279 ***/
    280 
    281 void
    282 MyFrame :: refreshTorrent( tr_torrent_t  * tor,
    283                            int             myTorrents_index,
    284                            const int_v   & cols )
    285 {
    286     int row = -1;
    287     int col = 0;
    288     char buf[512];
    289     std::string str;
    290     const tr_stat_t * s = tr_torrentStat( tor );
    291     const tr_info_t* info = tr_torrentInfo( tor );
    292 
    293     for( int_v::const_iterator it(cols.begin()), end(cols.end()); it!=end; ++it )
    294     {
    295         wxString xstr;
    296 
    297         switch( *it )
    298         {
    299             case COL_NUMBER:
    300                 snprintf( buf, sizeof(buf), "%d", 666 );
    301                 xstr = toWxStr( buf );
    302                 break;
    303 
    304             case COL_DONE:
    305                 snprintf( buf, sizeof(buf), "%d%%", (int)(s->percentDone*100.0) );
    306                 xstr = toWxStr( buf );
    307                 break;
    308 
    309             case COL_DOWNLOAD_SPEED: break;
    310                 xstr = getReadableSpeed( s->rateDownload );
    311                 break;
    312 
    313             case COL_ETA:
    314                 if( (int)(s->percentDone*100) >= 100 )
    315                     xstr = wxString ();
    316                 else if( s->eta < 0 )
    317                     xstr = toWxStr( "\xE2\x88\x9E" ); /* infinity, in utf-8 */
    318                 else
    319                     xstr = getReadableTime( s->eta );
    320                 break;
    321                
    322             case COL_HASH:
    323                 xstr = toWxStr( info->hashString );
    324                 break;
    325 
    326             case COL_NAME:
    327                 xstr = toWxStr( info->name );
    328                 break;
    329 
    330             case COL_PEERS:
    331                 /* FIXME: this is all peers, not just leechers */
    332                 snprintf( buf, sizeof(buf), "%d (%d)", s->peersTotal, s->peersConnected );
    333                 xstr = toWxStr( buf );
    334                 break;
    335 
    336             case COL_RATIO:
    337                 snprintf( buf, sizeof(buf), "%%%d", (int)(s->uploaded / (double)s->downloadedValid) );
    338                 xstr = toWxStr( buf );
    339                 break;
    340 
    341             case COL_RECEIVED:
    342                 xstr = getReadableSize( s->downloaded );
    343                 break;
    344 
    345             case COL_REMAINING:
    346                 xstr = getReadableSize( s->left );
    347                 break;
    348 
    349             case COL_SEEDS:
    350                 snprintf( buf, sizeof(buf), "%d", s->seeders ); /* FIXME: %d (%d) */
    351                 xstr = toWxStr( buf );
    352                 break;
    353 
    354             case COL_SENT:
    355                 xstr = getReadableSize( s->uploaded );
    356                 break;
    357 
    358             case COL_SIZE:
    359                 xstr = getReadableSize( info->totalSize );
    360                 break;
    361 
    362             case COL_STATE:
    363                 xstr = _T("Fixme");
    364                 break;
    365 
    366             case COL_STATUS:
    367                 xstr = _T("Fixme");
    368                 break;
    369 
    370             case COL_TOTAL:
    371                 xstr = _T("Fixme");
    372                 break;
    373 
    374             case COL_UPLOAD_SPEED:
    375                 xstr = getReadableSpeed( s->rateUpload );
    376                 break;
    377 
    378             default:
    379                 xstr = _T("Fixme");
    380         }
    381 
    382         if( col ) {
    383             myTorrentList->SetItem( row, col++, xstr );
    384         }
    385         else {
    386             // first column... find the right row to put the info in.
    387             // if the torrent's in the list already, update that row.
    388             // otherwise, add a new row.
    389             if( row < 0 ) {
    390                 str2int_t::const_iterator it = myHashToRow.find( info->hashString );
    391                 if( it != myHashToRow.end() ) {
    392                     row = it->second;
    393                 }
    394             }
    395             if( row >= 0 ) {
    396                 myTorrentList->SetItem( row, col++, xstr );
    397             }
    398             else {
    399                 row = myTorrentList->InsertItem( myTorrentList->GetItemCount(), xstr );
    400                 col = 1;
    401                 myHashToRow[info->hashString] = row;
    402                 myTorrentList->SetItemData( row, myTorrents_index );
    403             }
    404         }
    405     }
    406 }
    407 
    408 void
    409 MyFrame :: refreshTorrentList ()
    410 {
    411     const int_v  cols = getTorrentColumns( myConfig );
    412     const int rowCount = myTorrentList->GetItemCount();
    413     for( int row=0; row<rowCount; ++row )
    414     {
    415         int array_index = myTorrentList->GetItemData( row );
    416         tr_torrent_t * tor = myTorrents[array_index];
    417         refreshTorrent( tor, array_index, cols );
    418     }
    419 }
    420 
    421 void
    422 MyFrame :: repopulateTorrentList ()
    423 {
    424     myTorrentList->DeleteAllItems();
    425     myHashToRow.clear ();
    426 
    427     const int_v cols = getTorrentColumns( myConfig );
    428     int i = 0;
    429     for( torrents_t::const_iterator it(myTorrents.begin()),
    430                                    end(myTorrents.end()); it!=end; ++it )
    431         refreshTorrent( *it, i++, cols );
    432 }
    433 
    434 void
    435 MyFrame :: rebuildTorrentList()
    436 {
    437     myTorrentList->ClearAll( );
    438     myHashToRow.clear ();
    439 
    440     int i = 0;
    441     const int_v  cols = getTorrentColumns( myConfig );
    442     for( int_v ::const_iterator it(cols.begin()), end(cols.end()); it!=end; ++it )
    443     {
    444         int format = wxLIST_FORMAT_LEFT;
    445         int width = -1;
    446         wxString h;
    447 
    448         switch( *it )
    449         {
    450             case COL_NUMBER:          h = _T("#"); format = wxLIST_FORMAT_CENTRE; break;
    451             case COL_DONE:            h = _T("Done"); format = wxLIST_FORMAT_RIGHT; break;
    452             case COL_DOWNLOAD_SPEED:  h = _T("Download"); break;
    453             case COL_ETA:             h = _T("ETA"); format = wxLIST_FORMAT_RIGHT; break;
    454             case COL_HASH:            h = _T("SHA1 Hash"); break;
    455             case COL_NAME:            h = _T("Name"); width = 500; break;
    456             case COL_PEERS:           h = _T("Peers"); format = wxLIST_FORMAT_RIGHT; break;
    457             case COL_RATIO:           h = _T("Ratio"); format = wxLIST_FORMAT_RIGHT; break;
    458             case COL_RECEIVED:        h = _T("Received"); format = wxLIST_FORMAT_RIGHT; break;
    459             case COL_REMAINING:       h = _T("Remaining"); format = wxLIST_FORMAT_RIGHT; break;
    460             case COL_SEEDS:           h = _T("Seeds"); format = wxLIST_FORMAT_RIGHT; break;
    461             case COL_SENT:            h = _T("Sent"); format = wxLIST_FORMAT_RIGHT; break;
    462             case COL_SIZE:            h = _T("Size");  format = wxLIST_FORMAT_RIGHT; break;
    463             case COL_STATE:           h = _T("State"); break;
    464             case COL_STATUS:          h = _T("Status"); break;
    465             case COL_TOTAL:           h = _T("Total"); break;
    466             case COL_UPLOAD_SPEED:    h = _T("Upload"); format = wxLIST_FORMAT_RIGHT;break;
    467             default:                  h = _T("Error"); break;
    468         }
    469 
    470         myTorrentList->InsertColumn( i++, h, format, width );
    471     }
    472 
    473     repopulateTorrentList ();
    474 }
    475 
    476 /***
    477 ****
    478 ***/
     168}
    479169
    480170void
    481171MyFrame :: OnTimer(wxTimerEvent& event)
    482172{
    483     refreshTorrentList ();
    484 
     173    myTorrentList->Refresh ();
    485174
    486175    float dl, ul;
     
    517206    myTrayLogo->CopyFromBitmap( wxBitmap( transmission_logo ) );
    518207
    519     /**
    520     ***  Torrents
    521     **/
    522 
    523     const int flags = TR_FLAG_PAUSED;
    524     const char * destination = "/home/charles/torrents";
    525     int count = 0;
    526     tr_torrent_t ** torrents = tr_loadTorrents ( handle, destination, flags, &count );
    527     myTorrents.insert( myTorrents.end(), torrents, torrents+count );
    528     tr_free( torrents );
    529 
    530208
    531209    /**
     
    604282    /* Torrent List */
    605283
    606     myTorrentList = new wxListCtrl( row1, wxID_ANY, wxDefaultPosition, wxDefaultSize,
    607                                     wxLC_REPORT|wxLC_SINGLE_SEL );
    608     rebuildTorrentList();
     284    myTorrentList = new TorrentListCtrl( handle, myConfig, row1 );
    609285
    610286    wxBoxSizer * boxSizer = new wxBoxSizer( wxHORIZONTAL );
     
    642318
    643319    myTaskBarIcon = new wxTaskBarIcon( );
     320
     321    /**
     322    ***  Load the torrents
     323    **/
     324
     325    const int flags = TR_FLAG_PAUSED;
     326    const char * destination = "/home/charles/torrents";
     327    int count = 0;
     328    tr_torrent_t ** torrents = tr_loadTorrents ( handle, destination, flags, &count );
     329    myTorrentList->Add( std::vector<tr_torrent_t*>( torrents, torrents+count ) );
     330    tr_free( torrents );
    644331}
    645332
Note: See TracChangeset for help on using the changeset viewer.