~ubuntu-branches/ubuntu/precise/transmission/precise

« back to all changes in this revision

Viewing changes to wx/xmission.cc

  • Committer: Bazaar Package Importer
  • Author(s): Leo Costela
  • Date: 2009-05-17 19:39:51 UTC
  • mto: (1.3.4 upstream) (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: james.westby@ubuntu.com-20090517193951-k8x15sqoxzf7cuyx
ImportĀ upstreamĀ versionĀ 1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 4495 2008-01-05 18:17:23Z 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
 
 
51
 
extern "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
 
 
75
 
namespace
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
 
 
116
 
namespace
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
 
 
129
 
class MyApp : public wxApp
130
 
{
131
 
    virtual bool OnInit();
132
 
    virtual ~MyApp();
133
 
    wxSingleInstanceChecker * myChecker;
134
 
};
135
 
 
136
 
namespace
137
 
{
138
 
    tr_handle * handle = NULL;
139
 
 
140
 
    typedef std::vector<tr_torrent*> torrents_v;
141
 
}
142
 
 
143
 
class MyFrame : public wxFrame, public TorrentListCtrl::Listener
144
 
{
145
 
public:
146
 
    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, bool paused);
147
 
    virtual ~MyFrame();
148
 
 
149
 
public:
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
 
 
177
 
private:
178
 
    void RefreshFilterCounts( );
179
 
    void ApplyCurrentFilter( );
180
 
 
181
 
protected:
182
 
    wxConfig * myConfig;
183
 
    wxTimer myPulseTimer;
184
 
 
185
 
private:
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
 
 
200
 
private:
201
 
    DECLARE_EVENT_TABLE()
202
 
};
203
 
 
204
 
enum
205
 
{
206
 
    ID_START,
207
 
    ID_DESELECTALL,
208
 
    ID_EDIT_PREFS,
209
 
    ID_SHOW_DEBUG_WINDOW,
210
 
    ID_Pulse,
211
 
    ID_Filter
212
 
};
213
 
 
214
 
BEGIN_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 )
232
 
END_EVENT_TABLE()
233
 
 
234
 
IMPLEMENT_APP(MyApp)
235
 
 
236
 
 
237
 
void
238
 
MyFrame :: 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
 
 
255
 
void
256
 
MyFrame :: OnSelectAll( wxCommandEvent& )
257
 
{
258
 
    myTorrentList->SelectAll( );
259
 
}
260
 
 
261
 
void
262
 
MyFrame :: OnSelectAllUpdate( wxUpdateUIEvent& event )
263
 
{
264
 
    event.Enable( mySelectedTorrents.size() < myTorrents.size() );
265
 
}
266
 
 
267
 
void
268
 
MyFrame :: OnDeselectAll( wxCommandEvent& )
269
 
{
270
 
    myTorrentList->DeselectAll ( );
271
 
}
272
 
 
273
 
void
274
 
MyFrame :: OnDeselectAllUpdate( wxUpdateUIEvent& event )
275
 
{
276
 
    event.Enable( !mySelectedTorrents.empty() );
277
 
}
278
 
 
279
 
/**
280
 
**/
281
 
 
282
 
void
283
 
MyFrame :: 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
 
}
291
 
void
292
 
MyFrame :: 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
 
 
302
 
void
303
 
MyFrame :: 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
 
}
311
 
void
312
 
MyFrame :: 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
 
 
322
 
void
323
 
MyFrame :: OnRemoveUpdate( wxUpdateUIEvent& event )
324
 
{
325
 
    event.Enable( !mySelectedTorrents.empty() );
326
 
}
327
 
void
328
 
MyFrame :: OnRemove( wxCommandEvent& WXUNUSED(unused) )
329
 
{
330
 
    foreach( torrents_v, mySelectedTorrents, it ) {
331
 
        tr_torrentRemoveSaved( *it );
332
 
        tr_torrentClose( *it );
333
 
    }
334
 
}
335
 
 
336
 
/**
337
 
**/
338
 
 
339
 
void
340
 
MyFrame :: OnRecheckUpdate( wxUpdateUIEvent& event )
341
 
{
342
 
   event.Enable( !mySelectedTorrents.empty() );
343
 
}
344
 
void
345
 
MyFrame :: OnRecheck( wxCommandEvent& WXUNUSED(unused) )
346
 
{
347
 
    foreach( torrents_v, mySelectedTorrents, it )
348
 
        tr_torrentRecheck( *it );
349
 
}
350
 
 
351
 
/**
352
 
**/
353
 
 
354
 
void MyFrame :: OnOpen( wxCommandEvent& WXUNUSED(event) )
355
 
{
356
 
    const wxString key = _T("prev-directory");
357
 
    wxString directory;
358
 
    myConfig->Read( key, &directory );
359
 
    wxFileDialog * w = new wxFileDialog( this, _T("message"),
360
 
                                         directory,
361
 
                                         _T(""), /* default file */
362
 
                                         _T("Torrent files|*.torrent"),
363
 
                                         wxOPEN|wxMULTIPLE );
364
 
 
365
 
    if( w->ShowModal() == wxID_OK )
366
 
    {
367
 
        wxArrayString paths;
368
 
        w->GetPaths( paths );
369
 
        size_t nPaths = paths.GetCount();
370
 
        for( size_t i=0; i<nPaths; ++i )
371
 
        {
372
 
            const std::string filename = toStr( paths[i] );
373
 
            tr_ctor * ctor = tr_ctorNew( handle );
374
 
            tr_ctorSetMetainfoFromFile( ctor, filename.c_str() );
375
 
            tr_ctorSetDestination( ctor, TR_FALLBACK, mySavePath.c_str() );
376
 
            tr_torrent * tor = tr_torrentNew( handle, ctor, NULL );
377
 
            tr_ctorFree( ctor );
378
 
 
379
 
            if( tor )
380
 
                myTorrents.push_back( tor );
381
 
        }
382
 
        ApplyCurrentFilter( );
383
 
 
384
 
        myConfig->Write( key, w->GetDirectory() );
385
 
    }
386
 
 
387
 
    delete w;
388
 
}
389
 
 
390
 
 
391
 
bool
392
 
MyApp :: OnInit( )
393
 
{
394
 
    handle = tr_init( "wx" );
395
 
 
396
 
    wxCmdLineParser cmdParser( cmdLineDesc, argc, argv );
397
 
    if( cmdParser.Parse ( ) )
398
 
        return false;
399
 
 
400
 
    const wxString name = wxString::Format( _T("Xmission-%s"), wxGetUserId().c_str());
401
 
    myChecker = new wxSingleInstanceChecker( name );
402
 
    if ( myChecker->IsAnotherRunning() ) {
403
 
        wxLogError(_("An instance of Xmission is already running."));
404
 
        return false;
405
 
    }
406
 
 
407
 
    const bool paused = cmdParser.Found( _("p") );
408
 
 
409
 
    MyFrame * frame = new MyFrame( _("Xmission"),
410
 
                                   wxPoint(50,50),
411
 
                                   wxSize(900,600),
412
 
                                   paused);
413
 
 
414
 
    frame->Show( true );
415
 
    SetTopWindow( frame );
416
 
    return true;
417
 
}
418
 
 
419
 
MyApp :: ~MyApp()
420
 
{
421
 
    delete myChecker;
422
 
}
423
 
 
424
 
/***
425
 
****
426
 
***/
427
 
 
428
 
void
429
 
MyFrame :: RefreshFilterCounts( )
430
 
{
431
 
    int hits[ TorrentFilter :: N_FILTERS ];
432
 
    TorrentFilter::CountHits( myTorrents, hits );
433
 
    for( int i=0; i<TorrentFilter::N_FILTERS; ++i )
434
 
        myFilterButtons[i]->SetLabel( TorrentFilter::GetName( i, hits[i] ) );
435
 
}
436
 
 
437
 
void
438
 
MyFrame :: ApplyCurrentFilter( )
439
 
{
440
 
    torrents_v tmp( myTorrents );
441
 
    TorrentFilter :: RemoveFailures( myFilter, tmp );
442
 
    myTorrentList->Assign( tmp );
443
 
}
444
 
 
445
 
void
446
 
MyFrame :: OnTorrentListSelectionChanged( TorrentListCtrl* list,
447
 
                                          const std::set<tr_torrent*>& torrents )
448
 
{
449
 
    assert( list == myTorrentList );
450
 
    mySelectedTorrents.assign( torrents.begin(), torrents.end() );
451
 
 
452
 
    tr_torrent * tor = mySelectedTorrents.empty() ? NULL : mySelectedTorrents.front();
453
 
    mySpeedStats->SetTorrent( tor );
454
 
}
455
 
 
456
 
void
457
 
MyFrame :: OnPulse(wxTimerEvent& WXUNUSED(event) )
458
 
{
459
 
    if( myExitTime ) {
460
 
        if ( !tr_torrentCount(handle) ||  myExitTime<time(0) ) {
461
 
            delete myTrayIcon;
462
 
            myTrayIcon = 0;
463
 
            Destroy( );
464
 
            return;
465
 
        }
466
 
    }
467
 
 
468
 
    RefreshFilterCounts( );
469
 
    ApplyCurrentFilter( );
470
 
 
471
 
    mySpeedStats->Pulse( handle );
472
 
 
473
 
    float down, up;
474
 
    tr_torrentRates( handle, &down, &up );
475
 
    wxString xstr = _("Total DL: ");
476
 
    xstr += getReadableSpeed( down );
477
 
    SetStatusText( xstr, 1 );
478
 
    xstr = _("Total UL: ");
479
 
    xstr += getReadableSpeed( up );
480
 
    SetStatusText( xstr, 2 );
481
 
 
482
 
    xstr = _("Download: ");
483
 
    xstr += getReadableSpeed( down );
484
 
    xstr += _T("\n");
485
 
    xstr +=_("Upload: ");
486
 
    xstr +=  getReadableSpeed( up );
487
 
    myTrayIcon->SetIcon( myTrayIconIcon, xstr );
488
 
 
489
 
    myTorrentList->Refresh ( );
490
 
}
491
 
 
492
 
MyFrame::~MyFrame()
493
 
{
494
 
    myTorrentList->RemoveListener( this );
495
 
    delete myTorrentList;
496
 
 
497
 
    delete myConfig;
498
 
}
499
 
 
500
 
MyFrame :: MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, bool paused):
501
 
    wxFrame((wxFrame*)NULL,-1,title,pos,size),
502
 
    myConfig( new wxConfig( _T("xmission") ) ),
503
 
    myPulseTimer( this, ID_Pulse ),
504
 
    myLogoIcon( transmission_xpm ),
505
 
    myTrayIconIcon( systray_xpm ),
506
 
    mySpeedStats( 0 ),
507
 
    myFilter( TorrentFilter::ALL ),
508
 
    myExitTime( 0 )
509
 
{
510
 
    myTrayIcon = new wxTaskBarIcon;
511
 
    SetIcon( myLogoIcon );
512
 
 
513
 
    /**
514
 
    ***  Prefs
515
 
    **/
516
 
 
517
 
    long port;
518
 
    wxString key = _T("port");
519
 
    if( !myConfig->Read( key, &port, TR_DEFAULT_PORT ) )
520
 
        myConfig->Write( key, port );
521
 
    tr_setBindPort( handle, port );
522
 
 
523
 
    key = _T("save-path");
524
 
    wxString wxstr;
525
 
    if( !myConfig->Read( key, &wxstr, wxFileName::GetHomeDir() ) )
526
 
         myConfig->Write( key, wxstr );
527
 
    mySavePath = toStr( wxstr );
528
 
 
529
 
    const wxString default_colors[SpeedStats::N_COLORS] = {
530
 
        _T("#000000"), // background
531
 
        _T("#32cd32"), // frame
532
 
        _T("#ff0000"), // all up
533
 
        _T("#ff00ff"), // all down
534
 
        _T("#ffff00"), // torrent up
535
 
        _T("#00ff88")  // torrent down
536
 
    };
537
 
    wxColor speedColors[SpeedStats::N_COLORS];
538
 
    for( int i=0; i<SpeedStats::N_COLORS; ++i )
539
 
    {
540
 
        key = SpeedStats::GetColorName( i );
541
 
        myConfig->Read( key, &wxstr, _T("") );
542
 
        std::string str = toStr( wxstr );
543
 
        if( (str.size()!=7)
544
 
            || (str[0]!='#')
545
 
            || !isxdigit(str[1]) || !isxdigit(str[2])
546
 
            || !isxdigit(str[3]) || !isxdigit(str[4])
547
 
            || !isxdigit(str[5]) || !isxdigit(str[6]))
548
 
        {
549
 
            myConfig->Write( key, default_colors[i] );
550
 
            str = toStr( default_colors[i] );
551
 
        }
552
 
        int r, g, b;
553
 
        sscanf( str.c_str()+1, "%02x%02x%02x", &r, &g, &b );
554
 
        speedColors[i].Set( r, g, b );
555
 
    }
556
 
 
557
 
    /**
558
 
    ***  Menu
559
 
    **/
560
 
 
561
 
    wxMenuBar *menuBar = new wxMenuBar;
562
 
 
563
 
    wxMenu * m = new wxMenu;
564
 
    m->Append( wxID_OPEN, _T("&Open") );
565
 
    m->Append( ID_START, _T("&Start") );
566
 
    m->Append( wxID_STOP, _T("Sto&p") ) ;
567
 
    m->Append( wxID_REFRESH, _T("Re&check") );
568
 
    m->Append( wxID_REMOVE, _T("&Remove") );
569
 
    m->AppendSeparator();
570
 
    m->Append( wxID_NEW, _T("Create &New Torrent") );
571
 
    m->AppendSeparator();
572
 
    m->Append( wxID_CLOSE, _T("&Close") );
573
 
    m->Append( wxID_EXIT, _T("&Exit") );
574
 
    menuBar->Append( m, _T("&File") );
575
 
 
576
 
    m = new wxMenu;
577
 
    m->Append( wxID_SELECTALL, _T("Select &All") );
578
 
    m->Append( ID_DESELECTALL, _T("&Deselect All") );
579
 
    m->AppendSeparator();
580
 
    m->Append( wxID_PREFERENCES, _T("Edit &Preferences") );
581
 
    menuBar->Append( m, _T("&Edit") );
582
 
 
583
 
    m = new wxMenu;
584
 
    m->Append( ID_SHOW_DEBUG_WINDOW, _T("Show &Debug Window") );
585
 
    m->AppendSeparator();
586
 
    m->Append( wxID_ABOUT, _T("&About Xmission") );
587
 
    menuBar->Append( m, _T("&Help") );
588
 
 
589
 
    SetMenuBar(menuBar);
590
 
 
591
 
    /**
592
 
    ***  Toolbar
593
 
    **/
594
 
 
595
 
    wxIcon open_icon( plus_xpm );
596
 
    wxIcon exec_icon( play_xpm );
597
 
    wxIcon stop_icon( stop_xpm );
598
 
    wxIcon drop_icon( minus_xpm );
599
 
    wxBitmap bitmap;
600
 
 
601
 
    wxToolBar* toolbar = CreateToolBar( wxTB_FLAT );
602
 
    toolbar->SetToolBitmapSize( wxSize( 24, 24 ) );
603
 
    bitmap.CopyFromIcon( open_icon );
604
 
    toolbar->AddTool( wxID_OPEN,   _T("Open"), bitmap );
605
 
    bitmap.CopyFromIcon( exec_icon );
606
 
    toolbar->AddTool( ID_START,    _T("Start"), bitmap );
607
 
    bitmap.CopyFromIcon( stop_icon );
608
 
    toolbar->AddTool( wxID_STOP,   _T("Stop"), bitmap );
609
 
    bitmap.CopyFromIcon( drop_icon );
610
 
    toolbar->AddTool( wxID_REMOVE, _T("Remove"), bitmap );
611
 
    toolbar->Realize();
612
 
 
613
 
    /**
614
 
    ***  Row 1
615
 
    **/
616
 
 
617
 
    wxSplitterWindow * hsplit = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH );
618
 
#if wxCHECK_VERSION(2,5,4)
619
 
    hsplit->SetSashGravity( 0.8 );
620
 
#endif
621
 
 
622
 
    wxPanel * panel_1 = new wxPanel( hsplit, wxID_ANY );
623
 
 
624
 
    wxBoxSizer * buttonSizer = new wxBoxSizer( wxVERTICAL );
625
 
 
626
 
    for( int i=0; i<TorrentFilter::N_FILTERS; ++i ) {
627
 
        wxToggleButton * b = new wxToggleButton( panel_1, ID_Filter+i, TorrentFilter::GetName(i), wxDefaultPosition, wxDefaultSize, (i==0)?wxRB_GROUP:0 );
628
 
        b->SetValue( i==0 );
629
 
        myFilterButtons[i] = b;
630
 
        buttonSizer->Add( b, 1, wxGROW, 0 );
631
 
    }
632
 
 
633
 
    myTorrentList = new TorrentListCtrl( handle, myConfig, panel_1 );
634
 
    myTorrentList->AddListener( this );
635
 
 
636
 
    wxBoxSizer * panelSizer = new wxBoxSizer( wxHORIZONTAL );
637
 
    panelSizer->Add( buttonSizer, 0, wxALL, 5 );
638
 
    panelSizer->Add( myTorrentList, 1, wxGROW|wxALL, 5 );
639
 
 
640
 
    panel_1->SetSizer( panelSizer );
641
 
 
642
 
 
643
 
    wxNotebook * notebook = new wxNotebook( hsplit, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP );
644
 
    myTorrentStats = new TorrentStats( notebook );
645
 
    notebook->AddPage( myTorrentStats, _T("General"), false );
646
 
    wxButton * tmp = new wxButton( notebook, wxID_ANY, _T("Hello &World"));
647
 
    notebook->AddPage( tmp, _T("Peers") );
648
 
    tmp = new wxButton( notebook, wxID_ANY, _T("&Hello World"));
649
 
    notebook->AddPage( tmp, _T("Pieces") );
650
 
    tmp = new wxButton( notebook, wxID_ANY, _T("Hello World"));
651
 
    notebook->AddPage( tmp, _T("Files") );
652
 
    mySpeedStats = new SpeedStats( notebook, wxID_ANY );
653
 
    for( int i=0; i<SpeedStats::N_COLORS; ++i )
654
 
        mySpeedStats->SetColor( i, speedColors[i] );
655
 
    notebook->AddPage( mySpeedStats, _T("Speed"), true );
656
 
    tmp = new wxButton( notebook, wxID_ANY, _T("Hello World"));
657
 
    notebook->AddPage( tmp, _T("Logger") );
658
 
 
659
 
    hsplit->SplitHorizontally( panel_1, notebook );
660
 
 
661
 
    /**
662
 
    ***  Statusbar
663
 
    **/
664
 
 
665
 
    const int widths[] = { -1, 150, 150 };
666
 
    wxStatusBar * statusBar = CreateStatusBar( WXSIZEOF(widths) );
667
 
    SetStatusWidths( WXSIZEOF(widths), widths );
668
 
    const int styles[] = { wxSB_FLAT, wxSB_NORMAL, wxSB_NORMAL };
669
 
    statusBar->SetStatusStyles(  WXSIZEOF(widths), styles );
670
 
 
671
 
    /**
672
 
    ***  Refresh
673
 
    **/
674
 
 
675
 
    myPulseTimer.Start( 500 );
676
 
 
677
 
    /**
678
 
    ***  Load the torrents
679
 
    **/
680
 
 
681
 
    int count = 0;
682
 
    tr_ctor * ctor = tr_ctorNew( handle );
683
 
    tr_ctorSetPaused( ctor, TR_FORCE, paused );
684
 
    tr_ctorSetDestination( ctor, TR_FALLBACK, mySavePath.c_str() );
685
 
    tr_torrent ** torrents = tr_loadTorrents ( handle, ctor, &count );
686
 
    myTorrents.insert( myTorrents.end(), torrents, torrents+count );
687
 
    tr_free( torrents );
688
 
    tr_ctorFree( ctor );
689
 
 
690
 
    wxTimerEvent dummy;
691
 
    OnPulse( dummy );
692
 
}
693
 
 
694
 
void
695
 
MyFrame :: OnExit( wxCommandEvent& WXUNUSED( event ) )
696
 
{
697
 
    Enable( false );
698
 
 
699
 
    myTorrents.clear( );
700
 
    mySelectedTorrents.clear( );
701
 
    ApplyCurrentFilter( );
702
 
 
703
 
    tr_close( handle );
704
 
 
705
 
    /* give the connections a max of 10 seconds to shut themselves down */
706
 
    myExitTime = time(0) + 10;
707
 
}
708
 
 
709
 
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
710
 
{
711
 
    wxIcon ico( transmission_xpm );
712
 
 
713
 
#if wxCHECK_VERSION(2,8,0)
714
 
    wxAboutDialogInfo info;
715
 
    info.SetName(_T("Xmission"));
716
 
    info.SetVersion(_T(LONG_VERSION_STRING));
717
 
    info.SetCopyright(_T("Copyright 2005-2007 The Transmission Project"));
718
 
    info.SetDescription(_T("A fast and easy BitTorrent client"));
719
 
    info.SetWebSite( _T( "http://www.transmissionbt.com/" ) );
720
 
    info.SetIcon( ico );
721
 
    info.AddDeveloper( _T("Charles Kerr (Back-end, GTK+, wxWidgets)") );
722
 
    info.AddDeveloper( _T("Mitchell Livingston (Back-end; OS X)")  );
723
 
    info.AddDeveloper( _T("Eric Petit (Back-end; OS X)")  );
724
 
    info.AddDeveloper( _T("Josh Elsasser (Back-end; GTK+)") );
725
 
    info.AddDeveloper( _T("Bryan Varner (BeOS)")  );
726
 
    wxAboutBox( info );
727
 
#else
728
 
    wxMessageBox(_T("Xmission " LONG_VERSION_STRING "\n"
729
 
                    "Copyright 2005-2007 The Transmission Project"),
730
 
                 _T("About Xmission"),
731
 
                wxOK|wxICON_INFORMATION, this);
732
 
#endif
733
 
 
734
 
}