source: trunk/wx/xmission.cc @ 5975

Last change on this file since 5975 was 5975, checked in by charles, 13 years ago

API cleanup: s/tr_torrentRates/tr_sessionGetSpeed/

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author Id
File size: 19.6 KB
Line 
1/*
2 * Xmission - a cross-platform bittorrent client
3 * Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 *
18 * $Id: xmission.cc 5975 2008-05-30 15:19:07Z charles $
19 */
20
21#include <ctype.h>
22#include <inttypes.h>
23#include <set>
24#include <map>
25#include <string>
26#include <vector>
27#include <iostream>
28
29#include <wx/artprov.h>
30#include <wx/bitmap.h>
31#include <wx/cmdline.h>
32#include <wx/config.h>
33#include <wx/dcmemory.h>
34#include <wx/defs.h>
35#include <wx/filename.h>
36#include <wx/image.h>
37#include <wx/intl.h>
38#include <wx/listctrl.h>
39#include <wx/notebook.h>
40#include <wx/snglinst.h>
41#include <wx/splitter.h>
42#include <wx/statline.h>
43#include <wx/taskbar.h>
44#include <wx/tglbtn.h>
45#include <wx/toolbar.h>
46#include <wx/wx.h>
47#if wxCHECK_VERSION(2,8,0)
48#include <wx/aboutdlg.h>
49#endif
50
51extern "C"
52{
53  #include <libtransmission/transmission.h>
54  #include <libtransmission/utils.h>
55
56  #include <images/play.xpm>
57  #include <images/stop.xpm>
58  #include <images/plus.xpm>
59  #include <images/minus.xpm>
60
61  #include <images/systray.xpm>
62  #include <images/transmission.xpm>
63}
64
65#include "foreach.h"
66#include "speed-stats.h"
67#include "filter.h"
68#include "torrent-list.h"
69#include "torrent-stats.h"
70
71/***
72****
73***/
74
75namespace
76{
77    int bestDecimal( double num ) {
78        if ( num < 10 ) return 2;
79        if ( num < 100 ) return 1;
80        return 0;
81    }
82
83    wxString toWxStr( const char * s )
84    {
85        return wxString( s, wxConvUTF8 );
86    }
87
88    std::string toStr( const wxString& xstr )
89    {
90        return std::string( xstr.mb_str( *wxConvCurrent ) );
91    }
92
93    wxString getReadableSize( uint64_t size )
94    {
95        int i;
96        static const char *sizestrs[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB" };
97        for ( i=0; size>>10; ++i ) size = size>>10;
98        char buf[512];
99        snprintf( buf, sizeof(buf), "%.*f %s", bestDecimal(size), (double)size, sizestrs[i] );
100        return toWxStr( buf );
101    }
102
103    wxString getReadableSize( float f )
104    {
105        return getReadableSize( (uint64_t)f );
106    }
107
108    wxString getReadableSpeed( float kib_sec )
109    {
110        wxString xstr = getReadableSize(1024*kib_sec);
111        xstr += _T("/s");
112        return xstr;
113    }
114}
115
116namespace
117{
118    const wxCmdLineEntryDesc cmdLineDesc[] =
119    {
120        { wxCMD_LINE_SWITCH, _T("p"), _("pause"), _("pauses all the torrents on startup"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
121        { wxCMD_LINE_NONE, NULL, NULL, NULL, wxCMD_LINE_VAL_STRING, 0 }
122    };
123}
124
125/***
126****
127***/
128
129class MyApp : public wxApp
130{
131    virtual bool OnInit();
132    virtual ~MyApp();
133    wxSingleInstanceChecker * myChecker;
134};
135
136namespace
137{
138    tr_handle * handle = NULL;
139
140    typedef std::vector<tr_torrent*> torrents_v;
141}
142
143class MyFrame : public wxFrame, public TorrentListCtrl::Listener
144{
145public:
146    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, bool paused);
147    virtual ~MyFrame();
148
149public:
150    void OnExit( wxCommandEvent& );
151    void OnAbout( wxCommandEvent& );
152    void OnOpen( wxCommandEvent& );
153
154    void OnStart( wxCommandEvent& );
155    void OnStartUpdate( wxUpdateUIEvent& );
156
157    void OnStop( wxCommandEvent& );
158    void OnStopUpdate( wxUpdateUIEvent& );
159
160    void OnRemove( wxCommandEvent& );
161    void OnRemoveUpdate( wxUpdateUIEvent& );
162
163    void OnRecheck( wxCommandEvent& );
164    void OnRecheckUpdate( wxUpdateUIEvent& );
165
166    void OnSelectAll( wxCommandEvent& );
167    void OnSelectAllUpdate( wxUpdateUIEvent& );
168    void OnDeselectAll( wxCommandEvent& );
169    void OnDeselectAllUpdate( wxUpdateUIEvent& );
170
171    void OnFilterChanged( wxCommandEvent& );
172
173    void OnPulse( wxTimerEvent& );
174
175    virtual void OnTorrentListSelectionChanged( TorrentListCtrl*, const std::set<tr_torrent*>& );
176
177private:
178    void RefreshFilterCounts( );
179    void ApplyCurrentFilter( );
180
181protected:
182    wxConfig * myConfig;
183    wxTimer myPulseTimer;
184
185private:
186    TorrentListCtrl * myTorrentList;
187    TorrentStats * myTorrentStats;
188    wxListCtrl * myFilters;
189    wxTaskBarIcon * myTrayIcon;
190    wxIcon myLogoIcon;
191    wxIcon myTrayIconIcon;
192    SpeedStats * mySpeedStats;
193    torrents_v myTorrents;
194    torrents_v mySelectedTorrents;
195    int myFilter;
196    std::string mySavePath;
197    time_t myExitTime;
198    wxToggleButton* myFilterButtons[TorrentFilter::N_FILTERS];
199
200private:
201    DECLARE_EVENT_TABLE()
202};
203
204enum
205{
206    ID_START,
207    ID_DESELECTALL,
208    ID_EDIT_PREFS,
209    ID_SHOW_DEBUG_WINDOW,
210    ID_Pulse,
211    ID_Filter
212};
213
214BEGIN_EVENT_TABLE(MyFrame, wxFrame)
215    EVT_COMMAND_RANGE( ID_Filter, ID_Filter+TorrentFilter::N_FILTERS, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, MyFrame::OnFilterChanged )
216    EVT_MENU     ( wxID_ABOUT, MyFrame::OnAbout )
217    EVT_TIMER    ( ID_Pulse, MyFrame::OnPulse )
218    EVT_MENU     ( wxID_EXIT, MyFrame::OnExit )
219    EVT_MENU     ( wxID_OPEN, MyFrame::OnOpen )
220    EVT_MENU     ( ID_START, MyFrame::OnStart )
221    EVT_UPDATE_UI( ID_START, MyFrame::OnStartUpdate )
222    EVT_MENU     ( wxID_STOP, MyFrame::OnStop )
223    EVT_UPDATE_UI( wxID_STOP, MyFrame::OnStopUpdate )
224    EVT_MENU     ( wxID_REFRESH, MyFrame::OnRecheck )
225    EVT_UPDATE_UI( wxID_REFRESH, MyFrame::OnRecheckUpdate )
226    EVT_MENU     ( wxID_REMOVE, MyFrame::OnRemove )
227    EVT_UPDATE_UI( wxID_REMOVE, MyFrame::OnRemoveUpdate )
228    EVT_MENU     ( wxID_SELECTALL, MyFrame::OnSelectAll )
229    EVT_UPDATE_UI( wxID_SELECTALL, MyFrame::OnSelectAllUpdate )
230    EVT_MENU     ( ID_DESELECTALL, MyFrame::OnDeselectAll )
231    EVT_UPDATE_UI( ID_DESELECTALL, MyFrame::OnDeselectAllUpdate )
232END_EVENT_TABLE()
233
234IMPLEMENT_APP(MyApp)
235
236
237void
238MyFrame :: OnFilterChanged( wxCommandEvent& e )
239{
240    static bool ignore = false;
241
242    if( !ignore )
243    {
244        myFilter = e.GetId() - ID_Filter;
245        std::cerr << " OnFilterChanged, myFilter is now " << myFilter << std::endl;
246        ApplyCurrentFilter ( );
247
248        ignore = true;
249        for( int i=0; i<TorrentFilter::N_FILTERS; ++i )
250            myFilterButtons[i]->SetValue( i==myFilter );
251        ignore = false;
252    }
253}
254
255void
256MyFrame :: OnSelectAll( wxCommandEvent& )
257{
258    myTorrentList->SelectAll( );
259}
260
261void
262MyFrame :: OnSelectAllUpdate( wxUpdateUIEvent& event )
263{
264    event.Enable( mySelectedTorrents.size() < myTorrents.size() );
265}
266
267void
268MyFrame :: OnDeselectAll( wxCommandEvent& )
269{
270    myTorrentList->DeselectAll ( );
271}
272
273void
274MyFrame :: OnDeselectAllUpdate( wxUpdateUIEvent& event )
275{
276    event.Enable( !mySelectedTorrents.empty() );
277}
278
279/**
280**/
281
282void
283MyFrame :: OnStartUpdate( wxUpdateUIEvent& event )
284{
285    bool enable = false;
286    foreach( torrents_v, mySelectedTorrents, it )
287        if( tr_torrentStatCached(*it)->status == TR_STATUS_STOPPED )
288            enable = true;
289    event.Enable( enable );
290}
291void
292MyFrame :: OnStart( wxCommandEvent& WXUNUSED(unused) )
293{
294    foreach( torrents_v, mySelectedTorrents, it )
295        if( tr_torrentStatCached(*it)->status == TR_STATUS_STOPPED )
296            tr_torrentStart( *it );
297}
298
299/**
300**/
301
302void
303MyFrame :: OnStopUpdate( wxUpdateUIEvent& event )
304{
305    bool enable = false;
306    foreach( torrents_v, mySelectedTorrents, it )
307        if( tr_torrentStatCached(*it)->status != TR_STATUS_STOPPED )
308            enable = true;
309    event.Enable( enable );
310}
311void
312MyFrame :: OnStop( wxCommandEvent& WXUNUSED(unused) )
313{
314    foreach( torrents_v, mySelectedTorrents, it )
315        if( tr_torrentStat(*it)->status != TR_STATUS_STOPPED )
316            tr_torrentStop( *it );
317}
318
319/**
320**/
321
322void
323MyFrame :: OnRemoveUpdate( wxUpdateUIEvent& event )
324{
325    event.Enable( !mySelectedTorrents.empty() );
326}
327void
328MyFrame :: OnRemove( wxCommandEvent& WXUNUSED(unused) )
329{
330    foreach( torrents_v, mySelectedTorrents, it )
331        tr_torrentRemove( *it );
332}
333
334/**
335**/
336
337void
338MyFrame :: OnRecheckUpdate( wxUpdateUIEvent& event )
339{
340   event.Enable( !mySelectedTorrents.empty() );
341}
342void
343MyFrame :: OnRecheck( wxCommandEvent& WXUNUSED(unused) )
344{
345    foreach( torrents_v, mySelectedTorrents, it )
346        tr_torrentRecheck( *it );
347}
348
349/**
350**/
351
352void MyFrame :: OnOpen( wxCommandEvent& WXUNUSED(event) )
353{
354    const wxString key = _T("prev-directory");
355    wxString directory;
356    myConfig->Read( key, &directory );
357    wxFileDialog * w = new wxFileDialog( this, _T("message"),
358                                         directory,
359                                         _T(""), /* default file */
360                                         _T("Torrent files|*.torrent"),
361                                         wxOPEN|wxMULTIPLE );
362
363    if( w->ShowModal() == wxID_OK )
364    {
365        wxArrayString paths;
366        w->GetPaths( paths );
367        size_t nPaths = paths.GetCount();
368        for( size_t i=0; i<nPaths; ++i )
369        {
370            const std::string filename = toStr( paths[i] );
371            tr_ctor * ctor = tr_ctorNew( handle );
372            tr_ctorSetMetainfoFromFile( ctor, filename.c_str() );
373            tr_ctorSetDestination( ctor, TR_FALLBACK, mySavePath.c_str() );
374            tr_torrent * tor = tr_torrentNew( handle, ctor, NULL );
375            tr_ctorFree( ctor );
376
377            if( tor )
378                myTorrents.push_back( tor );
379        }
380        ApplyCurrentFilter( );
381
382        myConfig->Write( key, w->GetDirectory() );
383    }
384
385    delete w;
386}
387
388
389bool
390MyApp :: OnInit( )
391{
392    handle = tr_sessionInit( "wx" );
393
394    wxCmdLineParser cmdParser( cmdLineDesc, argc, argv );
395    if( cmdParser.Parse ( ) )
396        return false;
397
398    const wxString name = wxString::Format( _T("Xmission-%s"), wxGetUserId().c_str());
399    myChecker = new wxSingleInstanceChecker( name );
400    if ( myChecker->IsAnotherRunning() ) {
401        wxLogError(_("An instance of Xmission is already running."));
402        return false;
403    }
404
405    const bool paused = cmdParser.Found( _("p") );
406
407    MyFrame * frame = new MyFrame( _("Xmission"),
408                                   wxPoint(50,50),
409                                   wxSize(900,600),
410                                   paused);
411
412    frame->Show( true );
413    SetTopWindow( frame );
414    return true;
415}
416
417MyApp :: ~MyApp()
418{
419    delete myChecker;
420}
421
422/***
423****
424***/
425
426void
427MyFrame :: RefreshFilterCounts( )
428{
429    int hits[ TorrentFilter :: N_FILTERS ];
430    TorrentFilter::CountHits( myTorrents, hits );
431    for( int i=0; i<TorrentFilter::N_FILTERS; ++i )
432        myFilterButtons[i]->SetLabel( TorrentFilter::GetName( i, hits[i] ) );
433}
434
435void
436MyFrame :: ApplyCurrentFilter( )
437{
438    torrents_v tmp( myTorrents );
439    TorrentFilter :: RemoveFailures( myFilter, tmp );
440    myTorrentList->Assign( tmp );
441}
442
443void
444MyFrame :: OnTorrentListSelectionChanged( TorrentListCtrl* list,
445                                          const std::set<tr_torrent*>& torrents )
446{
447    assert( list == myTorrentList );
448    mySelectedTorrents.assign( torrents.begin(), torrents.end() );
449
450    tr_torrent * tor = mySelectedTorrents.empty() ? NULL : mySelectedTorrents.front();
451    mySpeedStats->SetTorrent( tor );
452}
453
454void
455MyFrame :: OnPulse(wxTimerEvent& WXUNUSED(event) )
456{
457    if( myExitTime ) {
458        if ( !tr_sessionCountTorrents(handle) ||  myExitTime<time(0) ) {
459            delete myTrayIcon;
460            myTrayIcon = 0;
461            Destroy( );
462            return;
463        }
464    }
465
466    RefreshFilterCounts( );
467    ApplyCurrentFilter( );
468
469    mySpeedStats->Pulse( handle );
470
471    float down, up;
472    tr_sessionGetSpeed( handle, &down, &up );
473    wxString xstr = _("Total DL: ");
474    xstr += getReadableSpeed( down );
475    SetStatusText( xstr, 1 );
476    xstr = _("Total UL: ");
477    xstr += getReadableSpeed( up );
478    SetStatusText( xstr, 2 );
479
480    xstr = _("Download: ");
481    xstr += getReadableSpeed( down );
482    xstr += _T("\n");
483    xstr +=_("Upload: ");
484    xstr +=  getReadableSpeed( up );
485    myTrayIcon->SetIcon( myTrayIconIcon, xstr );
486
487    myTorrentList->Refresh ( );
488}
489
490MyFrame::~MyFrame()
491{
492    myTorrentList->RemoveListener( this );
493    delete myTorrentList;
494
495    delete myConfig;
496}
497
498MyFrame :: MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, bool paused):
499    wxFrame((wxFrame*)NULL,-1,title,pos,size),
500    myConfig( new wxConfig( _T("xmission") ) ),
501    myPulseTimer( this, ID_Pulse ),
502    myLogoIcon( transmission_xpm ),
503    myTrayIconIcon( systray_xpm ),
504    mySpeedStats( 0 ),
505    myFilter( TorrentFilter::ALL ),
506    myExitTime( 0 )
507{
508    myTrayIcon = new wxTaskBarIcon;
509    SetIcon( myLogoIcon );
510
511    /**
512    ***  Prefs
513    **/
514
515    long port;
516    wxString key = _T("port");
517    if( !myConfig->Read( key, &port, TR_DEFAULT_PORT ) )
518        myConfig->Write( key, port );
519    tr_setBindPort( handle, port );
520
521    key = _T("save-path");
522    wxString wxstr;
523    if( !myConfig->Read( key, &wxstr, wxFileName::GetHomeDir() ) )
524         myConfig->Write( key, wxstr );
525    mySavePath = toStr( wxstr );
526
527    const wxString default_colors[SpeedStats::N_COLORS] = {
528        _T("#000000"), // background
529        _T("#32cd32"), // frame
530        _T("#ff0000"), // all up
531        _T("#ff00ff"), // all down
532        _T("#ffff00"), // torrent up
533        _T("#00ff88")  // torrent down
534    };
535    wxColor speedColors[SpeedStats::N_COLORS];
536    for( int i=0; i<SpeedStats::N_COLORS; ++i )
537    {
538        key = SpeedStats::GetColorName( i );
539        myConfig->Read( key, &wxstr, _T("") );
540        std::string str = toStr( wxstr );
541        if( (str.size()!=7)
542            || (str[0]!='#')
543            || !isxdigit(str[1]) || !isxdigit(str[2])
544            || !isxdigit(str[3]) || !isxdigit(str[4])
545            || !isxdigit(str[5]) || !isxdigit(str[6]))
546        {
547            myConfig->Write( key, default_colors[i] );
548            str = toStr( default_colors[i] );
549        }
550        int r, g, b;
551        sscanf( str.c_str()+1, "%02x%02x%02x", &r, &g, &b );
552        speedColors[i].Set( r, g, b );
553    }
554
555    /**
556    ***  Menu
557    **/
558
559    wxMenuBar *menuBar = new wxMenuBar;
560
561    wxMenu * m = new wxMenu;
562    m->Append( wxID_OPEN, _T("&Open") );
563    m->Append( ID_START, _T("&Start") );
564    m->Append( wxID_STOP, _T("Sto&p") ) ;
565    m->Append( wxID_REFRESH, _T("Re&check") );
566    m->Append( wxID_REMOVE, _T("&Remove") );
567    m->AppendSeparator();
568    m->Append( wxID_NEW, _T("Create &New Torrent") );
569    m->AppendSeparator();
570    m->Append( wxID_CLOSE, _T("&Close") );
571    m->Append( wxID_EXIT, _T("&Exit") );
572    menuBar->Append( m, _T("&File") );
573
574    m = new wxMenu;
575    m->Append( wxID_SELECTALL, _T("Select &All") );
576    m->Append( ID_DESELECTALL, _T("&Deselect All") );
577    m->AppendSeparator();
578    m->Append( wxID_PREFERENCES, _T("Edit &Preferences") );
579    menuBar->Append( m, _T("&Edit") );
580
581    m = new wxMenu;
582    m->Append( ID_SHOW_DEBUG_WINDOW, _T("Show &Debug Window") );
583    m->AppendSeparator();
584    m->Append( wxID_ABOUT, _T("&About Xmission") );
585    menuBar->Append( m, _T("&Help") );
586
587    SetMenuBar(menuBar);
588
589    /**
590    ***  Toolbar
591    **/
592
593    wxIcon open_icon( plus_xpm );
594    wxIcon exec_icon( play_xpm );
595    wxIcon stop_icon( stop_xpm );
596    wxIcon drop_icon( minus_xpm );
597    wxBitmap bitmap;
598
599    wxToolBar* toolbar = CreateToolBar( wxTB_FLAT );
600    toolbar->SetToolBitmapSize( wxSize( 24, 24 ) );
601    bitmap.CopyFromIcon( open_icon );
602    toolbar->AddTool( wxID_OPEN,   _T("Open"), bitmap );
603    bitmap.CopyFromIcon( exec_icon );
604    toolbar->AddTool( ID_START,    _T("Start"), bitmap );
605    bitmap.CopyFromIcon( stop_icon );
606    toolbar->AddTool( wxID_STOP,   _T("Stop"), bitmap );
607    bitmap.CopyFromIcon( drop_icon );
608    toolbar->AddTool( wxID_REMOVE, _T("Remove"), bitmap );
609    toolbar->Realize();
610
611    /**
612    ***  Row 1
613    **/
614
615    wxSplitterWindow * hsplit = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH );
616#if wxCHECK_VERSION(2,5,4)
617    hsplit->SetSashGravity( 0.8 );
618#endif
619
620    wxPanel * panel_1 = new wxPanel( hsplit, wxID_ANY );
621
622    wxBoxSizer * buttonSizer = new wxBoxSizer( wxVERTICAL );
623
624    for( int i=0; i<TorrentFilter::N_FILTERS; ++i ) {
625        wxToggleButton * b = new wxToggleButton( panel_1, ID_Filter+i, TorrentFilter::GetName(i), wxDefaultPosition, wxDefaultSize, (i==0)?wxRB_GROUP:0 );
626        b->SetValue( i==0 );
627        myFilterButtons[i] = b;
628        buttonSizer->Add( b, 1, wxGROW, 0 );
629    }
630
631    myTorrentList = new TorrentListCtrl( handle, myConfig, panel_1 );
632    myTorrentList->AddListener( this );
633
634    wxBoxSizer * panelSizer = new wxBoxSizer( wxHORIZONTAL );
635    panelSizer->Add( buttonSizer, 0, wxALL, 5 );
636    panelSizer->Add( myTorrentList, 1, wxGROW|wxALL, 5 );
637
638    panel_1->SetSizer( panelSizer );
639
640
641    wxNotebook * notebook = new wxNotebook( hsplit, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
642    myTorrentStats = new TorrentStats( notebook );
643    notebook->AddPage( myTorrentStats, _T("General"), false );
644    wxButton * tmp = new wxButton( notebook, wxID_ANY, _T("Hello &World"));
645    notebook->AddPage( tmp, _T("Peers") );
646    tmp = new wxButton( notebook, wxID_ANY, _T("&Hello World"));
647    notebook->AddPage( tmp, _T("Pieces") );
648    tmp = new wxButton( notebook, wxID_ANY, _T("Hello World"));
649    notebook->AddPage( tmp, _T("Files") );
650    mySpeedStats = new SpeedStats( notebook, wxID_ANY );
651    for( int i=0; i<SpeedStats::N_COLORS; ++i )
652        mySpeedStats->SetColor( i, speedColors[i] );
653    notebook->AddPage( mySpeedStats, _T("Speed"), true );
654    tmp = new wxButton( notebook, wxID_ANY, _T("Hello World"));
655    notebook->AddPage( tmp, _T("Logger") );
656
657    hsplit->SplitHorizontally( panel_1, notebook );
658
659    /**
660    ***  Statusbar
661    **/
662
663    const int widths[] = { -1, 150, 150 };
664    wxStatusBar * statusBar = CreateStatusBar( WXSIZEOF(widths) );
665    SetStatusWidths( WXSIZEOF(widths), widths );
666    const int styles[] = { wxSB_FLAT, wxSB_NORMAL, wxSB_NORMAL };
667    statusBar->SetStatusStyles(  WXSIZEOF(widths), styles );
668
669    /**
670    ***  Refresh
671    **/
672
673    myPulseTimer.Start( 500 );
674
675    /**
676    ***  Load the torrents
677    **/
678
679    int count = 0;
680    tr_ctor * ctor = tr_ctorNew( handle );
681    tr_ctorSetPaused( ctor, TR_FORCE, paused );
682    tr_ctorSetDestination( ctor, TR_FALLBACK, mySavePath.c_str() );
683    tr_torrent ** torrents = tr_loadTorrents ( handle, ctor, &count );
684    myTorrents.insert( myTorrents.end(), torrents, torrents+count );
685    tr_free( torrents );
686    tr_ctorFree( ctor );
687
688    wxTimerEvent dummy;
689    OnPulse( dummy );
690}
691
692void
693MyFrame :: OnExit( wxCommandEvent& WXUNUSED( event ) )
694{
695    Enable( false );
696
697    myTorrents.clear( );
698    mySelectedTorrents.clear( );
699    ApplyCurrentFilter( );
700
701    tr_sessionClose( handle );
702
703    /* give the connections a max of 10 seconds to shut themselves down */
704    myExitTime = time(0) + 10;
705}
706
707void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
708{
709    wxIcon ico( transmission_xpm );
710
711#if wxCHECK_VERSION(2,8,0)
712    wxAboutDialogInfo info;
713    info.SetName(_T("Xmission"));
714    info.SetVersion(_T(LONG_VERSION_STRING));
715    info.SetCopyright(_T("Copyright 2005-2007 The Transmission Project"));
716    info.SetDescription(_T("A fast and easy BitTorrent client"));
717    info.SetWebSite( _T( "http://www.transmissionbt.com/" ) );
718    info.SetIcon( ico );
719    info.AddDeveloper( _T("Charles Kerr (Back-end, GTK+, wxWidgets)") );
720    info.AddDeveloper( _T("Mitchell Livingston (Back-end; OS X)")  );
721    info.AddDeveloper( _T("Eric Petit (Back-end; OS X)")  );
722    info.AddDeveloper( _T("Josh Elsasser (Back-end; GTK+)") );
723    info.AddDeveloper( _T("Bryan Varner (BeOS)")  );
724    wxAboutBox( info );
725#else
726    wxMessageBox(_T("Xmission " LONG_VERSION_STRING "\n"
727                    "Copyright 2005-2007 The Transmission Project"),
728                 _T("About Xmission"),
729                wxOK|wxICON_INFORMATION, this);
730#endif
731
732}
Note: See TracBrowser for help on using the repository browser.