mirror of
https://github.com/transmission/transmission
synced 2025-03-03 18:25:35 +00:00
torrent filter counts work now.
This commit is contained in:
parent
5ee729223e
commit
d14d21bebd
6 changed files with 263 additions and 25 deletions
|
@ -4,6 +4,9 @@ SUBDIRS = images
|
|||
|
||||
bin_PROGRAMS = Xmission
|
||||
|
||||
Xmission_SOURCES = xmission.cc torrent-list.cc
|
||||
Xmission_SOURCES = \
|
||||
xmission.cc \
|
||||
torrent-filter.cc \
|
||||
torrent-list.cc
|
||||
|
||||
Xmission_LDADD = ../libtransmission/libtransmission.a @WX_LIBS@ $(PTHREAD_LIBS) -lm
|
||||
|
|
83
wx/torrent-filter.cc
Normal file
83
wx/torrent-filter.cc
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#include "torrent-filter.h"
|
||||
|
||||
bool
|
||||
TorrentFilter :: Test( int show, tr_torrent_t * tor )
|
||||
{
|
||||
if( show == SHOW_ALL )
|
||||
return true;
|
||||
|
||||
const tr_stat_t * stat = tr_torrentStat( tor );
|
||||
|
||||
if( show == SHOW_DOWNLOADING )
|
||||
return stat->status == TR_STATUS_DOWNLOAD;
|
||||
|
||||
if( show == SHOW_UPLOADING )
|
||||
return stat->status == TR_STATUS_SEED;
|
||||
|
||||
if( show == SHOW_COMPLETE )
|
||||
return stat->cpStatus != TR_CP_INCOMPLETE;
|
||||
|
||||
if( show == SHOW_INCOMPLETE )
|
||||
return stat->cpStatus == TR_CP_INCOMPLETE;
|
||||
|
||||
if( show == SHOW_ACTIVE )
|
||||
return ( stat->rateUpload + stat->rateDownload ) >= 0.01;
|
||||
|
||||
if( show == SHOW_INACTIVE )
|
||||
return ( stat->rateUpload + stat->rateDownload ) < 0.01;
|
||||
|
||||
abort ();
|
||||
}
|
||||
|
||||
int
|
||||
TorrentFilter :: CountHits ( int show, const torrents_v& torrents )
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for( torrents_v::const_iterator it(torrents.begin()), end(torrents.end()); it!=end; ++it )
|
||||
if( Test( show, *it ) )
|
||||
++i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
TorrentFilter :: RemoveFailures( int show, torrents_v& torrents )
|
||||
{
|
||||
torrents_v tmp;
|
||||
|
||||
for( torrents_v::iterator it(torrents.begin()), end(torrents.end()); it!=end; ++it )
|
||||
if( Test( show, *it ) )
|
||||
tmp.push_back( *it );
|
||||
|
||||
torrents.swap( tmp );
|
||||
}
|
||||
|
||||
|
||||
wxString
|
||||
TorrentFilter :: getFilterName( int show )
|
||||
{
|
||||
switch( show )
|
||||
{
|
||||
case SHOW_ALL: return _("All");
|
||||
case SHOW_DOWNLOADING: return _("Downloading");
|
||||
case SHOW_UPLOADING: return _("Uploading");
|
||||
case SHOW_COMPLETE: return _("Complete");
|
||||
case SHOW_INCOMPLETE: return _("Incomplete");
|
||||
case SHOW_ACTIVE: return _("Active");
|
||||
case SHOW_INACTIVE: return _("Inactive");
|
||||
default: abort();
|
||||
}
|
||||
|
||||
return _T(""); //notreached
|
||||
}
|
50
wx/torrent-filter.h
Normal file
50
wx/torrent-filter.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
|
||||
*
|
||||
* This file is licensed by the GPL version 2. Works owned by the
|
||||
* Transmission project are granted a special exemption to clause 2(b)
|
||||
* so that the bulk of its code can remain under the MIT license.
|
||||
* This exemption does not extend to derived works not owned by
|
||||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#ifndef __XMISSION_TORRENT_FILTER_H__
|
||||
#define __XMISSION_TORRENT_FILTER_H__
|
||||
|
||||
#include <vector>
|
||||
#include <wx/intl.h>
|
||||
#include <libtransmission/transmission.h>
|
||||
|
||||
class TorrentFilter
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::vector<tr_torrent_t*> torrents_v;
|
||||
|
||||
enum Show
|
||||
{
|
||||
SHOW_ALL,
|
||||
SHOW_DOWNLOADING,
|
||||
SHOW_UPLOADING,
|
||||
SHOW_COMPLETE,
|
||||
SHOW_INCOMPLETE,
|
||||
SHOW_ACTIVE,
|
||||
SHOW_INACTIVE,
|
||||
N_FILTERS
|
||||
};
|
||||
|
||||
static wxString getFilterName( int show );
|
||||
|
||||
|
||||
static void RemoveFailures( int show,
|
||||
torrents_v & torrents );
|
||||
|
||||
static int CountHits ( int show,
|
||||
const torrents_v & torrents );
|
||||
|
||||
static bool Test( int show,
|
||||
tr_torrent_t * torrent );
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -165,7 +165,9 @@ enum
|
|||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(TorrentListCtrl, wxListCtrl)
|
||||
EVT_LIST_COL_CLICK(TORRENT_LIST_CTRL, TorrentListCtrl::OnSort)
|
||||
EVT_LIST_COL_CLICK( TORRENT_LIST_CTRL, TorrentListCtrl::OnSort )
|
||||
EVT_LIST_ITEM_SELECTED( TORRENT_LIST_CTRL, TorrentListCtrl::OnItemSelected )
|
||||
EVT_LIST_ITEM_DESELECTED( TORRENT_LIST_CTRL, TorrentListCtrl::OnItemDeselected )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
TorrentListCtrl :: TorrentListCtrl( tr_handle_t * handle,
|
||||
|
@ -173,7 +175,7 @@ TorrentListCtrl :: TorrentListCtrl( tr_handle_t * handle,
|
|||
wxWindow * parent,
|
||||
const wxPoint & pos,
|
||||
const wxSize & size):
|
||||
wxListCtrl( parent, TORRENT_LIST_CTRL, pos, size, wxLC_REPORT|wxLC_SINGLE_SEL ),
|
||||
wxListCtrl( parent, TORRENT_LIST_CTRL, pos, size, wxLC_REPORT ),
|
||||
myHandle( handle ),
|
||||
myConfig( config )
|
||||
{
|
||||
|
@ -317,6 +319,42 @@ TorrentListCtrl :: RefreshTorrent( tr_torrent_t * tor,
|
|||
}
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
void
|
||||
TorrentListCtrl :: OnSort( wxListEvent& event )
|
||||
{
|
||||
const int_v cols = getTorrentColumns( myConfig );
|
||||
const int key = cols[ event.GetColumn() ];
|
||||
Sort( key );
|
||||
}
|
||||
|
||||
void
|
||||
TorrentListCtrl :: OnItemSelected( wxListEvent& event )
|
||||
{
|
||||
std::set<tr_torrent_t*> sel;
|
||||
long item = -1;
|
||||
for ( ;; ) {
|
||||
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
||||
if ( item == -1 )
|
||||
break;
|
||||
sel.insert( myTorrents[GetItemData(item)] );
|
||||
}
|
||||
fire_selection_changed( sel );
|
||||
}
|
||||
|
||||
void
|
||||
TorrentListCtrl :: OnItemDeselected( wxListEvent& event )
|
||||
{
|
||||
OnItemSelected( event );
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
static torrents_t * uglyHack = NULL;
|
||||
|
||||
int
|
||||
|
@ -415,14 +453,6 @@ TorrentListCtrl :: Compare( long item1, long item2, long sortData )
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
TorrentListCtrl :: OnSort( wxListEvent& event )
|
||||
{
|
||||
const int_v cols = getTorrentColumns( myConfig );
|
||||
const int key = cols[ event.GetColumn() ];
|
||||
Sort( key );
|
||||
}
|
||||
|
||||
void
|
||||
TorrentListCtrl :: Sort( int column )
|
||||
{
|
||||
|
@ -453,6 +483,10 @@ TorrentListCtrl :: Resort( )
|
|||
uglyHack = NULL;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
void
|
||||
TorrentListCtrl :: Refresh ()
|
||||
{
|
||||
|
|
|
@ -28,6 +28,48 @@ class TorrentListCtrl: public wxListCtrl
|
|||
const wxSize & size = wxDefaultSize );
|
||||
virtual ~TorrentListCtrl();
|
||||
|
||||
public:
|
||||
|
||||
enum ShowMode
|
||||
{
|
||||
SHOW_ALL,
|
||||
SHOW_DOWNLOADING,
|
||||
SHOW_UPLOADING,
|
||||
SHOW_COMPLETE,
|
||||
SHOW_INCOMPLETE,
|
||||
SHOW_ACTIVE,
|
||||
SHOW_INACTIVE,
|
||||
N_FILTERS
|
||||
};
|
||||
|
||||
void SetShowMode( ShowMode );
|
||||
|
||||
int GetShowModeCounts( ShowMode ) const;
|
||||
|
||||
public:
|
||||
|
||||
struct Listener
|
||||
{
|
||||
Listener() {}
|
||||
|
||||
virtual ~Listener() {}
|
||||
|
||||
virtual void OnTorrentListSelectionChanged(
|
||||
TorrentListCtrl*,
|
||||
const std::set<tr_torrent_t*>& ) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
typedef std::set<Listener*> listeners_t;
|
||||
listeners_t myListeners;
|
||||
void fire_selection_changed( const std::set<tr_torrent_t*>& t ) {
|
||||
for( listeners_t::iterator it(myListeners.begin()), end(myListeners.end()); it!=end; )
|
||||
(*it++)->OnTorrentListSelectionChanged( this, t );
|
||||
}
|
||||
public:
|
||||
void AddListener( Listener* l ) { myListeners.insert(l); }
|
||||
void RemoveListener( Listener* l ) { myListeners.erase(l); }
|
||||
|
||||
public:
|
||||
void Rebuild ();
|
||||
void Repopulate ();
|
||||
|
@ -40,7 +82,6 @@ class TorrentListCtrl: public wxListCtrl
|
|||
private:
|
||||
void Sort( int column );
|
||||
void Resort( );
|
||||
void OnSort( wxListEvent& );
|
||||
void RefreshTorrent( tr_torrent_t*, int, const std::vector<int>& );
|
||||
static int Compare( long, long, long );
|
||||
|
||||
|
@ -48,6 +89,11 @@ class TorrentListCtrl: public wxListCtrl
|
|||
typedef std::map<std::string,int> str2int_t;
|
||||
str2int_t myHashToRow;
|
||||
|
||||
private:
|
||||
void OnSort( wxListEvent& );
|
||||
void OnItemSelected( wxListEvent& );
|
||||
void OnItemDeselected( wxListEvent& );
|
||||
|
||||
private:
|
||||
tr_handle_t * myHandle;
|
||||
wxConfig * myConfig;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <wx/defs.h>
|
||||
#include <wx/config.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/splitter.h>
|
||||
|
@ -42,6 +43,7 @@ extern "C"
|
|||
#include <images/transmission.xpm>
|
||||
}
|
||||
|
||||
#include "torrent-filter.h"
|
||||
#include "torrent-list.h"
|
||||
|
||||
class MyApp : public wxApp
|
||||
|
@ -55,7 +57,7 @@ namespace
|
|||
{
|
||||
tr_handle_t * handle = NULL;
|
||||
|
||||
typedef std::vector<tr_torrent_t*> torrents_t;
|
||||
typedef std::vector<tr_torrent_t*> torrents_v;
|
||||
}
|
||||
|
||||
class MyFrame : public wxFrame
|
||||
|
@ -63,20 +65,27 @@ class MyFrame : public wxFrame
|
|||
public:
|
||||
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
|
||||
virtual ~MyFrame();
|
||||
|
||||
public:
|
||||
void OnQuit( wxCommandEvent& );
|
||||
void OnAbout( wxCommandEvent& );
|
||||
void OnOpen( wxCommandEvent& );
|
||||
void OnTimer( wxTimerEvent& );
|
||||
|
||||
private:
|
||||
void RefreshFilterCounts( );
|
||||
|
||||
protected:
|
||||
wxConfig * myConfig;
|
||||
wxTimer myPulseTimer;
|
||||
|
||||
private:
|
||||
TorrentListCtrl * myTorrentList;
|
||||
wxListCtrl * myFilters;
|
||||
wxTaskBarIcon * myTaskBarIcon;
|
||||
wxIcon * myLogoIcon;
|
||||
wxIcon * myTrayLogo;
|
||||
torrents_v myTorrents;
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -179,10 +188,25 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
MyFrame :: RefreshFilterCounts( )
|
||||
{
|
||||
for( int i=0; i<TorrentFilter::N_FILTERS; ++i )
|
||||
{
|
||||
wxString xstr = TorrentFilter::getFilterName( i );
|
||||
const int count = TorrentFilter::CountHits( i, myTorrents );
|
||||
if( count )
|
||||
xstr += wxString::Format(_T(" (%d)"), count );
|
||||
myFilters->SetItem( i, 0, xstr );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MyFrame :: OnTimer(wxTimerEvent& event)
|
||||
{
|
||||
myTorrentList->Refresh ();
|
||||
RefreshFilterCounts( );
|
||||
|
||||
myTorrentList->Refresh ( );
|
||||
|
||||
float dl, ul;
|
||||
tr_torrentRates( handle, &dl, &ul );
|
||||
|
@ -286,24 +310,21 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size):
|
|||
|
||||
/* Filters */
|
||||
|
||||
wxListCtrl * filters = new wxListCtrl( row1, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_NO_HEADER );
|
||||
filters->InsertColumn( wxLIST_FORMAT_LEFT, _T("YYZ") );
|
||||
int i = 0;
|
||||
filters->InsertItem( i++, _T("All") );
|
||||
filters->InsertItem( i++, _T("Downloading (1)") );
|
||||
filters->InsertItem( i++, _T("Completed") );
|
||||
filters->InsertItem( i++, _T("Active (1)") );
|
||||
filters->InsertItem( i++, _T("Inactive") );
|
||||
myFilters = new wxListCtrl( row1, wxID_ANY, wxDefaultPosition, wxSize(120,-1),
|
||||
wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_NO_HEADER );
|
||||
myFilters->InsertColumn( wxLIST_FORMAT_LEFT, _("Filters"), wxLIST_FORMAT_LEFT, 120 );
|
||||
for( int i=0; i<TorrentFilter::N_FILTERS; ++i )
|
||||
myFilters->InsertItem( i, TorrentFilter::getFilterName(i) );
|
||||
|
||||
/* Torrent List */
|
||||
|
||||
myTorrentList = new TorrentListCtrl( handle, myConfig, row1 );
|
||||
|
||||
wxBoxSizer * boxSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
boxSizer->Add( filters, 0, wxEXPAND|wxRIGHT, 5 );
|
||||
boxSizer->Add( myFilters, 0, wxEXPAND|wxRIGHT, 5 );
|
||||
boxSizer->Add( myTorrentList, 1, wxEXPAND, 0 );
|
||||
row1->SetSizer( boxSizer );
|
||||
//boxSizer->SetSizeHints( row1 );
|
||||
|
||||
|
||||
wxNotebook * notebook = new wxNotebook( hsplit, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
|
||||
|
@ -343,7 +364,8 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size):
|
|||
const char * destination = "/home/charles/torrents";
|
||||
int count = 0;
|
||||
tr_torrent_t ** torrents = tr_loadTorrents ( handle, destination, flags, &count );
|
||||
myTorrentList->Add( std::vector<tr_torrent_t*>( torrents, torrents+count ) );
|
||||
myTorrents.insert( myTorrents.end(), torrents, torrents+count );
|
||||
myTorrentList->Add( myTorrents );
|
||||
tr_free( torrents );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue