source: trunk/qt/mainwin.cc @ 8194

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

(trunk qt) remember sorting & filtering mode between sessions

File size: 29.6 KB
Line 
1/*
2 * This file Copyright (C) 2009 Charles Kerr <charles@transmissionbt.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id:$
11 */
12
13#include <cassert>
14#include <iostream>
15
16#include <QCheckBox>
17#include <QDesktopServices>
18#include <QFileDialog>
19#include <QSize>
20#include <QStyle>
21#include <QHBoxLayout>
22#include <QSystemTrayIcon>
23#include <QUrl>
24
25#include "about.h"
26#include "details.h"
27#include "mainwin.h"
28#include "make-dialog.h"
29#include "options.h"
30#include "prefs.h"
31#include "prefs-dialog.h"
32#include "session.h"
33#include "speed.h"
34#include "stats-dialog.h"
35#include "torrent-delegate.h"
36#include "torrent-delegate-min.h"
37#include "torrent-filter.h"
38#include "torrent-model.h"
39#include "ui_mainwin.h"
40#include "utils.h"
41#include "qticonloader.h"
42
43#define PREFS_KEY "prefs-key";
44
45QIcon
46TrMainWindow :: getStockIcon( const QString& freedesktop_name, int fallback )
47{
48    QIcon fallbackIcon;
49
50    if( fallback > 0 )
51        fallbackIcon = style()->standardIcon( QStyle::StandardPixmap( fallback ), 0, this );
52
53    return QtIconLoader::icon( freedesktop_name, fallbackIcon );
54}
55
56namespace
57{
58    QSize calculateTextButtonSizeHint( QPushButton * button )
59    {
60        QStyleOptionButton opt;
61        opt.initFrom( button );
62        QString s( button->text( ) );
63        if( s.isEmpty( ) )
64            s = QString::fromLatin1( "XXXX" );
65        QFontMetrics fm = button->fontMetrics( );
66        QSize sz = fm.size( Qt::TextShowMnemonic, s );
67        return button->style()->sizeFromContents( QStyle::CT_PushButton, &opt, sz, button ).expandedTo( QApplication::globalStrut( ) );
68    }
69
70    void setTextButtonSizeHint( QPushButton * button )
71    {
72        /* this is kind of a hack, possibly coming from my being new to Qt.
73         * Qt 4.4's sizeHint calculations for QPushButton have it include
74         * space for an icon, even if no icon is used.  because of this,
75         * default pushbuttons look way too wide in the filterbar...
76         * so this routine recalculates the sizeHint without icons.
77         * If there's a Right Way to do this that I've missed, let me know */
78        button->setMaximumSize( calculateTextButtonSizeHint( button ) );
79    }
80}
81
82
83TrMainWindow :: TrMainWindow( Session& session, Prefs& prefs, TorrentModel& model, bool minimized ):
84    myLastFullUpdateTime( 0 ),
85    myPrefsDialog( new PrefsDialog( session, prefs, this ) ),
86    myAboutDialog( new AboutDialog( this ) ),
87    myStatsDialog( new StatsDialog( session, this ) ),
88    myFileDialog( 0 ),
89    myFilterModel( prefs ),
90    myTorrentDelegate( new TorrentDelegate( this ) ),
91    myTorrentDelegateMin( new TorrentDelegateMin( this ) ),
92    mySession( session ),
93    myPrefs( prefs ),
94    myModel( model ),
95    mySpeedModeOffIcon( ":/icons/alt-limit-off.png" ),
96    mySpeedModeOnIcon( ":/icons/alt-limit-on.png" ),
97    myLastSendTime( 0 ),
98    myLastReadTime( 0 ),
99    myNetworkTimer( this )
100{
101    QAction * sep = new QAction( this );
102    sep->setSeparator( true );
103
104    ui.setupUi( this );
105
106    QString title( "Transmission" );
107    const QUrl remoteUrl( session.getRemoteUrl( ) );
108    if( !remoteUrl.isEmpty( ) )
109        title += tr( " - %1" ).arg( remoteUrl.toString() );
110    setWindowTitle( title );
111
112    QStyle * style = this->style();
113
114    int i = style->pixelMetric( QStyle::PM_SmallIconSize, 0, this );
115    const QSize smallIconSize( i, i );
116
117    // icons
118    ui.action_Add->setIcon( getStockIcon( "list-add", QStyle::SP_DialogOpenButton ) );
119    ui.action_New->setIcon( getStockIcon( "document-new", QStyle::SP_DesktopIcon ) );
120    ui.action_Properties->setIcon( getStockIcon( "document-properties", QStyle::SP_DesktopIcon ) );
121    ui.action_OpenFolder->setIcon( getStockIcon( "folder-open", QStyle::SP_DirOpenIcon ) );
122    ui.action_Start->setIcon( getStockIcon( "media-playback-start", QStyle::SP_MediaPlay ) );
123    ui.action_Announce->setIcon( getStockIcon( "network-transmit-receive" ) );
124    ui.action_Pause->setIcon( getStockIcon( "media-playback-pause", QStyle::SP_MediaPause ) );
125    ui.action_Remove->setIcon( getStockIcon( "list-remove", QStyle::SP_TrashIcon ) );
126    ui.action_Delete->setIcon( getStockIcon( "edit-delete", QStyle::SP_TrashIcon ) );
127    ui.action_StartAll->setIcon( getStockIcon( "media-playback-start", QStyle::SP_MediaPlay ) );
128    ui.action_PauseAll->setIcon( getStockIcon( "media-playback-pause", QStyle::SP_MediaPause ) );
129    ui.action_Quit->setIcon( getStockIcon( "application-exit" ) );
130    ui.action_SelectAll->setIcon( getStockIcon( "edit-select-all" ) );
131    ui.action_ReverseSortOrder->setIcon( getStockIcon( "view-sort-ascending", QStyle::SP_ArrowDown ) );
132    ui.action_Preferences->setIcon( getStockIcon( "preferences-system" ) );
133    ui.action_Contents->setIcon( getStockIcon( "help-contents", QStyle::SP_DialogHelpButton ) );
134    ui.action_About->setIcon( getStockIcon( "help-about" ) );
135    ui.statusbarStatsButton->setIcon( getStockIcon( "view-refresh", QStyle::SP_BrowserReload ) );
136    ui.downloadIconLabel->setPixmap( getStockIcon( "go-down", QStyle::SP_ArrowDown ).pixmap( smallIconSize ) );
137    ui.uploadIconLabel->setPixmap( getStockIcon( "go-up", QStyle::SP_ArrowUp ).pixmap( smallIconSize ) );
138    ui.filterEntryModeButton->setIcon( getStockIcon( "edit-find", QStyle::SP_ArrowForward ) );
139    ui.filterEntryClearButton->setIcon( getStockIcon( "edit-clear", QStyle::SP_DialogCloseButton ) );
140
141    // ui signals
142    // ccc
143    connect( ui.action_Toolbar, SIGNAL(toggled(bool)), this, SLOT(setToolbarVisible(bool)));
144    connect( ui.action_TrayIcon, SIGNAL(toggled(bool)), this, SLOT(setTrayIconVisible(bool)));
145    connect( ui.action_Filterbar, SIGNAL(toggled(bool)), this, SLOT(setFilterbarVisible(bool)));
146    connect( ui.action_Statusbar, SIGNAL(toggled(bool)), this, SLOT(setStatusbarVisible(bool)));
147    connect( ui.action_MinimalView, SIGNAL(toggled(bool)), this, SLOT(setMinimalView(bool)));
148    connect( ui.action_SortByActivity, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortByActivity()) );
149    connect( ui.action_SortByAge, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortByAge()) );
150    connect( ui.action_SortByETA, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortByETA()));
151    connect( ui.action_SortByName, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortByName()));
152    connect( ui.action_SortByProgress, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortByProgress()));
153    connect( ui.action_SortByRatio, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortByRatio()));
154    connect( ui.action_SortBySize, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortBySize()));
155    connect( ui.action_SortByState, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortByState()));
156    connect( ui.action_SortByTracker, SIGNAL(toggled(bool)), &myFilterModel, SLOT(sortByTracker()));
157    connect( ui.action_ReverseSortOrder, SIGNAL(toggled(bool)), &myFilterModel, SLOT(setAscending(bool)));
158    connect( ui.action_Start, SIGNAL(triggered()), this, SLOT(startSelected()));
159    connect( ui.action_Pause, SIGNAL(triggered()), this, SLOT(pauseSelected()));
160    connect( ui.action_Remove, SIGNAL(triggered()), this, SLOT(removeSelected()));
161    connect( ui.action_Delete, SIGNAL(triggered()), this, SLOT(deleteSelected()));
162    connect( ui.action_Verify, SIGNAL(triggered()), this, SLOT(verifySelected()) );
163    connect( ui.action_Announce, SIGNAL(triggered()), this, SLOT(reannounceSelected()) );
164    connect( ui.action_StartAll, SIGNAL(triggered()), this, SLOT(startAll()));
165    connect( ui.action_PauseAll, SIGNAL(triggered()), this, SLOT(pauseAll()));
166    connect( ui.action_Add, SIGNAL(triggered()), this, SLOT(openTorrent()));
167    connect( ui.action_New, SIGNAL(triggered()), this, SLOT(newTorrent()));
168    connect( ui.action_Preferences, SIGNAL(triggered()), myPrefsDialog, SLOT(show()));
169    connect( ui.action_Statistics, SIGNAL(triggered()), myStatsDialog, SLOT(show()));
170    connect( ui.action_About, SIGNAL(triggered()), myAboutDialog, SLOT(show()));
171    connect( ui.action_Contents, SIGNAL(triggered()), this, SLOT(openHelp()));
172    connect( ui.action_OpenFolder, SIGNAL(triggered()), this, SLOT(openFolder()));
173    connect( ui.action_Properties, SIGNAL(triggered()), this, SLOT(openProperties()));
174    connect( ui.listView, SIGNAL(activated(const QModelIndex&)), ui.action_Properties, SLOT(trigger()));
175
176    // context menu
177    QList<QAction*> actions;
178    actions << ui.action_Properties
179            << ui.action_OpenFolder
180            << sep
181            << ui.action_Start
182            << ui.action_Pause
183            << ui.action_Verify
184            << ui.action_Announce
185            << sep
186            << ui.action_Remove
187            << ui.action_Delete;
188    addActions( actions );
189    setContextMenuPolicy( Qt::ActionsContextMenu );
190
191    // signals
192    connect( ui.speedLimitModeButton, SIGNAL(clicked()), this, SLOT(toggleSpeedMode()));
193    connect( ui.filterAll, SIGNAL(clicked()), this, SLOT(showAll()));
194    connect( ui.filterActive, SIGNAL(clicked()), this, SLOT(showActive()));
195    connect( ui.filterDownloading, SIGNAL(clicked()), this, SLOT(showDownloading()));
196    connect( ui.filterSeeding, SIGNAL(clicked()), this, SLOT(showSeeding()));
197    connect( ui.filterPaused, SIGNAL(clicked()), this, SLOT(showPaused()));
198    connect( ui.filterEntryClearButton, SIGNAL(clicked()), ui.filterEntry, SLOT(clear()));
199    connect( ui.filterEntry, SIGNAL(textChanged(QString)), &myFilterModel, SLOT(setText(QString)));
200    connect( ui.action_SelectAll, SIGNAL(triggered()), ui.listView, SLOT(selectAll()));
201    connect( ui.action_DeselectAll, SIGNAL(triggered()), ui.listView, SLOT(clearSelection()));
202    setTextButtonSizeHint( ui.filterAll );
203    setTextButtonSizeHint( ui.filterActive );
204    setTextButtonSizeHint( ui.filterDownloading );
205    setTextButtonSizeHint( ui.filterSeeding );
206    setTextButtonSizeHint( ui.filterPaused );
207    setShowMode( myFilterModel.getShowMode( ) );
208
209    connect( &myFilterModel, SIGNAL(rowsInserted(const QModelIndex&,int,int)), this, SLOT(refreshVisibleCount()));
210    connect( &myFilterModel, SIGNAL(rowsRemoved(const QModelIndex&,int,int)), this, SLOT(refreshVisibleCount()));
211    connect( &myFilterModel, SIGNAL(rowsInserted(const QModelIndex&,int,int)), this, SLOT(refreshActionSensitivity()));
212    connect( &myFilterModel, SIGNAL(rowsRemoved(const QModelIndex&,int,int)), this, SLOT(refreshActionSensitivity()));
213
214    connect( ui.action_Quit, SIGNAL(triggered()), QCoreApplication::instance(), SLOT(quit()) );
215
216    // torrent view
217    myFilterModel.setSourceModel( &myModel );
218    ui.listView->setModel( &myFilterModel );
219    connect( ui.listView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)), this, SLOT(refreshActionSensitivity()));
220
221    QActionGroup * actionGroup = new QActionGroup( this );
222    actionGroup->addAction( ui.action_FilterByName );
223    actionGroup->addAction( ui.action_FilterByFiles );
224    actionGroup->addAction( ui.action_FilterByTracker );
225    QMenu * menu = new QMenu( );
226    menu->addAction( ui.action_FilterByName );
227    menu->addAction( ui.action_FilterByFiles );
228    menu->addAction( ui.action_FilterByTracker );
229    ui.filterEntryModeButton->setMenu( menu );
230    connect( ui.action_FilterByName, SIGNAL(triggered()), this, SLOT(filterByName()));
231    connect( ui.action_FilterByFiles, SIGNAL(triggered()), this, SLOT(filterByFiles()));
232    connect( ui.action_FilterByTracker, SIGNAL(triggered()), this, SLOT(filterByTracker()));
233    ui.action_FilterByName->setChecked( true );
234
235    actionGroup = new QActionGroup( this );
236    actionGroup->addAction( ui.action_TotalRatio );
237    actionGroup->addAction( ui.action_TotalTransfer );
238    actionGroup->addAction( ui.action_SessionRatio );
239    actionGroup->addAction( ui.action_SessionTransfer );
240    menu = new QMenu( );
241    menu->addAction( ui.action_TotalRatio );
242    menu->addAction( ui.action_TotalTransfer );
243    menu->addAction( ui.action_SessionRatio );
244    menu->addAction( ui.action_SessionTransfer );
245    connect( ui.action_TotalRatio, SIGNAL(triggered()), this, SLOT(showTotalRatio()));
246    connect( ui.action_TotalTransfer, SIGNAL(triggered()), this, SLOT(showTotalTransfer()));
247    connect( ui.action_SessionRatio, SIGNAL(triggered()), this, SLOT(showSessionRatio()));
248    connect( ui.action_SessionTransfer, SIGNAL(triggered()), this, SLOT(showSessionTransfer()));
249    ui.statusbarStatsButton->setMenu( menu );
250
251    actionGroup = new QActionGroup( this );
252    actionGroup->addAction( ui.action_SortByActivity );
253    actionGroup->addAction( ui.action_SortByAge );
254    actionGroup->addAction( ui.action_SortByETA );
255    actionGroup->addAction( ui.action_SortByName );
256    actionGroup->addAction( ui.action_SortByProgress );
257    actionGroup->addAction( ui.action_SortByRatio );
258    actionGroup->addAction( ui.action_SortBySize );
259    actionGroup->addAction( ui.action_SortByState );
260    actionGroup->addAction( ui.action_SortByTracker );
261
262    menu = new QMenu( );
263    menu->addAction( ui.action_Add );
264    menu->addSeparator( );
265    menu->addAction( ui.action_ShowMainWindow );
266    menu->addAction( ui.action_ShowMessageLog );
267    menu->addAction( ui.action_About );
268    menu->addSeparator( );
269    menu->addAction( ui.action_StartAll );
270    menu->addAction( ui.action_PauseAll );
271    menu->addSeparator( );
272    menu->addAction( ui.action_Quit );
273    myTrayIcon.setContextMenu( menu );
274    myTrayIcon.setIcon( QApplication::windowIcon( ) );
275
276    connect( ui.action_ShowMainWindow, SIGNAL(toggled(bool)), this, SLOT(toggleWindows()));
277    connect( &myTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
278    connect( &myPrefs, SIGNAL(changed(int)), this, SLOT(refreshPref(int)) );
279
280    ui.action_ShowMainWindow->setChecked( !minimized );
281    ui.action_TrayIcon->setChecked( minimized || prefs.getBool( Prefs::SHOW_TRAY_ICON ) );
282
283    QList<int> initKeys;
284    initKeys << Prefs :: MAIN_WINDOW_X
285             << Prefs :: SHOW_TRAY_ICON
286             << Prefs :: SORT_REVERSED
287             << Prefs :: SORT_MODE
288             << Prefs :: FILTER_MODE
289             << Prefs :: FILTERBAR
290             << Prefs :: STATUSBAR
291             << Prefs :: STATUSBAR_STATS
292             << Prefs :: TOOLBAR
293             << Prefs :: ALT_SPEED_LIMIT_ENABLED
294             << Prefs :: MINIMAL_VIEW;
295    foreach( int key, initKeys )
296        refreshPref( key );
297
298    connect( &mySession, SIGNAL(statsUpdated()), this, SLOT(refreshStatusBar()) );
299    connect( &mySession, SIGNAL(dataReadProgress()), this, SLOT(dataReadProgress()) );
300    connect( &mySession, SIGNAL(dataSendProgress()), this, SLOT(dataSendProgress()) );
301
302    if( mySession.isServer( ) )
303        ui.networkLabel->hide( );
304    else {
305        connect( &myNetworkTimer, SIGNAL(timeout()), this, SLOT(onNetworkTimer()));
306        myNetworkTimer.start( 1000 );
307    }
308
309    refreshActionSensitivity( );
310    refreshStatusBar( );
311    refreshVisibleCount( );
312}
313
314TrMainWindow :: ~TrMainWindow( )
315{
316}
317
318/****
319*****
320****/
321
322void
323TrMainWindow :: openProperties( )
324{
325    const int id( *getSelectedTorrents().begin() );
326    Torrent * torrent( myModel.getTorrentFromId( id ) );
327    assert( torrent != 0 );
328    QDialog * d( new Details( mySession, *torrent, this ) );
329    d->show( );
330}
331
332void
333TrMainWindow :: openFolder( )
334{
335    const int torrentId( *getSelectedTorrents().begin() );
336    const Torrent * tor( myModel.getTorrentFromId( torrentId ) );
337    const QString path( tor->getPath( ) );
338    QDesktopServices :: openUrl( QUrl::fromLocalFile( path ) );
339}
340
341void
342TrMainWindow :: openHelp( )
343{
344    const char * fmt = "http://www.transmissionbt.com/help/gtk/%d.%dx";
345    int major, minor;
346    sscanf( SHORT_VERSION_STRING, "%d.%d", &major, &minor );
347    char url[128];
348    snprintf( url, sizeof( url ), fmt, major, minor/10 );
349    QDesktopServices :: openUrl( QUrl( QString( url ) ) );
350}
351
352void
353TrMainWindow :: refreshVisibleCount( )
354{
355    const int visibleCount( myFilterModel.rowCount( ) );
356    const int totalCount( visibleCount + myFilterModel.hiddenRowCount( ) );
357    QString str;
358    if( visibleCount == totalCount )
359        str = tr( "%Ln Torrent(s)", 0, totalCount );
360    else
361        str = tr( "%L1 of %Ln Torrent(s)", 0, totalCount ).arg( visibleCount );
362    ui.visibleCountLabel->setText( str );
363}
364
365void
366TrMainWindow :: refreshStatusBar( )
367{
368    const Speed up( myModel.getUploadSpeed( ) );
369    const Speed down( myModel.getDownloadSpeed( ) );
370    ui.uploadTextLabel->setText( Utils :: speedToString( up ) );
371    ui.downloadTextLabel->setText( Utils :: speedToString( down ) );
372    const QString mode( myPrefs.getString( Prefs::STATUSBAR_STATS ) );
373    QString str;
374
375    if( mode == "session-ratio" )
376    {
377        str = tr( "Ratio: %1" ).arg( Utils :: ratioToString( mySession.getStats().ratio ) );
378    }
379    else if( mode == "session-transfer" )
380    {
381        const tr_session_stats& stats( mySession.getStats( ) );
382        str = tr( "Down: %1, Up: %2" ).arg( Utils :: sizeToString( stats.downloadedBytes ) )
383                                      .arg( Utils :: sizeToString( stats.uploadedBytes ) );
384    }
385    else if( mode == "total-transfer" )
386    {
387        const tr_session_stats& stats( mySession.getCumulativeStats( ) );
388        str = tr( "Down: %1, Up: %2" ).arg( Utils :: sizeToString( stats.downloadedBytes ) )
389                                      .arg( Utils :: sizeToString( stats.uploadedBytes ) );
390    }
391    else /* default is "total-ratio" */
392    {
393        str = tr( "Ratio: %1" ).arg( Utils :: ratioToString( mySession.getCumulativeStats().ratio ) );
394    }
395
396    ui.statusbarStatsLabel->setText( str );
397}
398
399void
400TrMainWindow :: refreshActionSensitivity( )
401{
402    int selected( 0 );
403    int paused( 0 );
404    int selectedAndPaused( 0 );
405    int canAnnounce( 0 );
406    const QAbstractItemModel * model( ui.listView->model( ) );
407    const QItemSelectionModel * selectionModel( ui.listView->selectionModel( ) );
408    const int rowCount( model->rowCount( ) );
409
410    /* count how many torrents are selected, paused, etc */
411    for( int row=0; row<rowCount; ++row ) {
412        const QModelIndex modelIndex( model->index( row, 0 ) );
413        assert( model == modelIndex.model( ) );
414        const Torrent * tor( model->data( modelIndex, TorrentModel::TorrentRole ).value<const Torrent*>( ) );
415        const bool isSelected( selectionModel->isSelected( modelIndex ) );
416        const bool isPaused( tor->isPaused( ) );
417        if( isSelected )
418            ++selected;
419        if( isPaused )
420            ++ paused;
421        if( isSelected && isPaused )
422            ++selectedAndPaused;
423        if( tor->canManualAnnounce( ) )
424            ++canAnnounce;
425    }
426
427    const bool haveSelection( selected > 0 );
428    ui.action_Verify->setEnabled( haveSelection );
429    ui.action_Remove->setEnabled( haveSelection );
430    ui.action_Delete->setEnabled( haveSelection );
431    ui.action_DeselectAll->setEnabled( haveSelection );
432
433    const bool oneSelection( selected == 1 );
434    ui.action_Properties->setEnabled( oneSelection );
435    ui.action_OpenFolder->setEnabled( oneSelection );
436
437    ui.action_SelectAll->setEnabled( selected < rowCount );
438    ui.action_StartAll->setEnabled( paused > 0 );
439    ui.action_PauseAll->setEnabled( paused < rowCount );
440    ui.action_Start->setEnabled( selectedAndPaused > 0 );
441    ui.action_Pause->setEnabled( selectedAndPaused < selected );
442    ui.action_Announce->setEnabled( selected > 0 && ( canAnnounce == selected ) );
443}
444
445/**
446***
447**/
448
449void
450TrMainWindow :: clearSelection( )
451{
452    ui.action_DeselectAll->trigger( );
453}
454
455QSet<int>
456TrMainWindow :: getSelectedTorrents( ) const
457{
458    QSet<int> ids;
459
460    foreach( QModelIndex index, ui.listView->selectionModel( )->selectedRows( ) )
461    {
462        const Torrent * tor( index.model()->data( index, TorrentModel::TorrentRole ).value<const Torrent*>( ) );
463        ids.insert( tor->id( ) );
464    }
465
466    return ids;
467}
468
469void
470TrMainWindow :: startSelected( )
471{
472    mySession.start( getSelectedTorrents( ) );
473}
474void
475TrMainWindow :: pauseSelected( )
476{
477    mySession.pause( getSelectedTorrents( ) );
478}
479void
480TrMainWindow :: startAll( )
481{
482    mySession.start( );
483}
484void
485TrMainWindow :: pauseAll( )
486{
487    mySession.pause( );
488}
489void
490TrMainWindow :: removeSelected( )
491{
492    mySession.removeTorrents( getSelectedTorrents( ), false );
493}
494void
495TrMainWindow :: deleteSelected( )
496{
497    mySession.removeTorrents( getSelectedTorrents( ), true );
498}
499void
500TrMainWindow :: verifySelected( )
501{
502    mySession.verifyTorrents( getSelectedTorrents( ) );
503}
504void
505TrMainWindow :: reannounceSelected( )
506{
507    mySession.reannounceTorrents( getSelectedTorrents( ) );
508}
509
510/**
511***
512**/
513
514void
515TrMainWindow :: setShowMode( TorrentFilter :: ShowMode mode )
516{
517    ui.filterAll->setChecked         ( mode == TorrentFilter :: SHOW_ALL );
518    ui.filterActive->setChecked      ( mode == TorrentFilter :: SHOW_ACTIVE );
519    ui.filterDownloading->setChecked ( mode == TorrentFilter :: SHOW_DOWNLOADING );
520    ui.filterSeeding->setChecked     ( mode == TorrentFilter :: SHOW_SEEDING );
521    ui.filterPaused->setChecked      ( mode == TorrentFilter :: SHOW_PAUSED );
522
523    myFilterModel.setShowMode( mode );
524}
525
526void TrMainWindow :: showAll         ( ) { setShowMode( TorrentFilter :: SHOW_ALL ); }
527void TrMainWindow :: showActive      ( ) { setShowMode( TorrentFilter :: SHOW_ACTIVE ); }
528void TrMainWindow :: showDownloading ( ) { setShowMode( TorrentFilter :: SHOW_DOWNLOADING ); }
529void TrMainWindow :: showSeeding     ( ) { setShowMode( TorrentFilter :: SHOW_SEEDING ); }
530void TrMainWindow :: showPaused      ( ) { setShowMode( TorrentFilter :: SHOW_PAUSED ); }
531
532void TrMainWindow :: filterByName    ( ) { myFilterModel.setTextMode( TorrentFilter :: FILTER_BY_NAME ); }
533void TrMainWindow :: filterByTracker ( ) { myFilterModel.setTextMode( TorrentFilter :: FILTER_BY_TRACKER ); }
534void TrMainWindow :: filterByFiles   ( ) { myFilterModel.setTextMode( TorrentFilter :: FILTER_BY_FILES ); }
535
536void
537TrMainWindow :: showTotalRatio( )
538{
539    myPrefs.set( Prefs::STATUSBAR_STATS, "total-ratio" );
540}
541void
542TrMainWindow :: showTotalTransfer( )
543{
544    myPrefs.set( Prefs::STATUSBAR_STATS, "total-transfer" );
545}
546void
547TrMainWindow :: showSessionRatio( )
548{
549    myPrefs.set( Prefs::STATUSBAR_STATS, "session-ratio" );
550}
551void
552TrMainWindow :: showSessionTransfer( )
553{
554    myPrefs.set( Prefs::STATUSBAR_STATS, "session-transfer" );
555}
556
557/**
558***
559**/
560
561void
562TrMainWindow :: setMinimalView( bool visible )
563{
564    myPrefs.set( Prefs :: MINIMAL_VIEW, visible );
565}
566void
567TrMainWindow :: setTrayIconVisible( bool visible )
568{
569    myPrefs.set( Prefs :: SHOW_TRAY_ICON, visible );
570}
571void
572TrMainWindow :: toggleSpeedMode( )
573{
574    myPrefs.toggleBool( Prefs :: ALT_SPEED_LIMIT_ENABLED );
575}
576void
577TrMainWindow :: setToolbarVisible( bool visible )
578{
579    myPrefs.set( Prefs::TOOLBAR, visible );
580}
581void
582TrMainWindow :: setFilterbarVisible( bool visible )
583{
584    myPrefs.set( Prefs::FILTERBAR, visible );
585}
586void
587TrMainWindow :: setStatusbarVisible( bool visible )
588{
589    myPrefs.set( Prefs::STATUSBAR, visible );
590}
591
592/**
593***
594**/
595
596void
597TrMainWindow :: toggleWindows( )
598{
599    setVisible( !isVisible( ) );
600}
601
602void
603TrMainWindow :: trayActivated( QSystemTrayIcon::ActivationReason reason )
604{
605    if( reason == QSystemTrayIcon::Trigger )
606        ui.action_ShowMainWindow->toggle( );
607}
608
609
610void
611TrMainWindow :: refreshPref( int key )
612{
613    bool b;
614    int i;
615    QString str;
616
617    switch( key )
618    {
619        case Prefs::STATUSBAR_STATS:
620            str = myPrefs.getString( key );
621            ui.action_TotalRatio->setChecked     ( str == "total-ratio" );
622            ui.action_TotalTransfer->setChecked  ( str == "total-transfer" );
623            ui.action_SessionRatio->setChecked   ( str == "session-ratio" );
624            ui.action_SessionTransfer->setChecked( str == "session-transfer" );
625            refreshStatusBar( );
626            break;
627
628        case Prefs::SORT_REVERSED:
629            ui.action_ReverseSortOrder->setChecked( myPrefs.getBool( key ) );
630            break;
631
632        case Prefs::SORT_MODE:
633            i = myFilterModel.getSortModeFromName( myPrefs.getString( key ) );
634            ui.action_SortByActivity->setChecked ( i == TorrentFilter::SORT_BY_ACTIVITY );
635            ui.action_SortByAge->setChecked      ( i == TorrentFilter::SORT_BY_AGE );
636            ui.action_SortByETA->setChecked      ( i == TorrentFilter::SORT_BY_ETA );
637            ui.action_SortByName->setChecked     ( i == TorrentFilter::SORT_BY_NAME );
638            ui.action_SortByProgress->setChecked ( i == TorrentFilter::SORT_BY_PROGRESS );
639            ui.action_SortByRatio->setChecked    ( i == TorrentFilter::SORT_BY_RATIO );
640            ui.action_SortBySize->setChecked     ( i == TorrentFilter::SORT_BY_SIZE );
641            ui.action_SortByState->setChecked    ( i == TorrentFilter::SORT_BY_STATE );
642            ui.action_SortByTracker->setChecked  ( i == TorrentFilter::SORT_BY_TRACKER );
643            break;
644
645        case Prefs::FILTER_MODE:
646            i = myFilterModel.getShowModeFromName( myPrefs.getString( key ) );
647            ui.filterAll->setChecked         ( i == TorrentFilter::SHOW_ALL );
648            ui.filterActive->setChecked      ( i == TorrentFilter::SHOW_ACTIVE );
649            ui.filterDownloading->setChecked ( i == TorrentFilter::SHOW_DOWNLOADING );
650            ui.filterSeeding->setChecked     ( i == TorrentFilter::SHOW_SEEDING );
651            ui.filterPaused->setChecked      ( i == TorrentFilter::SHOW_PAUSED );
652            break;
653
654
655        case Prefs::FILTERBAR:
656            b = myPrefs.getBool( key );
657            ui.filterbar->setVisible( b );
658            ui.action_Filterbar->setChecked( b );
659            break;
660
661        case Prefs::STATUSBAR:
662            b = myPrefs.getBool( key );
663            ui.statusbar->setVisible( b );
664            ui.action_Statusbar->setChecked( b );
665            break;
666
667        case Prefs::TOOLBAR:
668            b = myPrefs.getBool( key );
669            ui.toolBar->setVisible( b );
670            ui.action_Toolbar->setChecked( b );
671            break;
672
673        case Prefs::SHOW_TRAY_ICON:
674            b = myPrefs.getBool( key );
675            ui.action_TrayIcon->setChecked( b );
676            myTrayIcon.setVisible( b );
677            break;
678
679        case Prefs::MINIMAL_VIEW:
680            b = myPrefs.getBool( key );
681            ui.action_MinimalView->setChecked( b );
682            ui.listView->setItemDelegate( b ? myTorrentDelegateMin : myTorrentDelegate );
683            ui.listView->reset( ); // force the rows to resize
684            break;
685
686        case Prefs::MAIN_WINDOW_X:
687        case Prefs::MAIN_WINDOW_Y:
688        case Prefs::MAIN_WINDOW_WIDTH:
689        case Prefs::MAIN_WINDOW_HEIGHT:
690            setGeometry( myPrefs.getInt( Prefs::MAIN_WINDOW_X ),
691                         myPrefs.getInt( Prefs::MAIN_WINDOW_Y ),
692                         myPrefs.getInt( Prefs::MAIN_WINDOW_WIDTH ),
693                         myPrefs.getInt( Prefs::MAIN_WINDOW_HEIGHT ) );
694            break;
695
696        case Prefs :: ALT_SPEED_LIMIT_ENABLED:
697            b = myPrefs.getBool( key );
698            ui.speedLimitModeButton->setChecked( b );
699            ui.speedLimitModeButton->setIcon( b ? mySpeedModeOnIcon : mySpeedModeOffIcon );
700            ui.speedLimitModeButton->setToolTip( b ? tr( "Click to disable Speed Limit Mode" )
701                                                   : tr( "Click to enable Speed Limit Mode" ) );
702            break;
703
704        default:
705            break;
706    }
707}
708
709/***
710****
711***/
712
713void
714TrMainWindow :: newTorrent( )
715{
716    MakeDialog * d = new MakeDialog( mySession, this );
717    d->show( );
718}
719
720void
721TrMainWindow :: openTorrent( )
722{
723    if( myFileDialog == 0 )
724    {
725        myFileDialog = new QFileDialog( this,
726                                        tr( "Add Torrent" ),
727                                        myPrefs.getString( Prefs::OPEN_DIALOG_FOLDER ),
728                                        tr( "Torrent Files (*.torrent);;All Files (*.*)" ) );
729        myFileDialog->setFileMode( QFileDialog::ExistingFiles );
730
731
732        QCheckBox * button = new QCheckBox( tr( "Display &options dialog" ) );
733        button->setChecked( myPrefs.getBool( Prefs::OPTIONS_PROMPT ) );
734        QGridLayout * layout = dynamic_cast<QGridLayout*>(myFileDialog->layout());
735        layout->addWidget( button, layout->rowCount( ), 0, 1, -1, Qt::AlignLeft );
736        myFileDialogOptionsCheck = button;
737
738        connect( myFileDialog, SIGNAL(filesSelected(const QStringList&)), this, SLOT(addTorrents(const QStringList&)));
739    }
740
741    myFileDialog->show( );
742}
743
744void
745TrMainWindow :: addTorrents( const QStringList& filenames )
746{
747    foreach( const QString& filename, filenames )
748        addTorrent( filename );
749}
750
751void
752TrMainWindow :: addTorrent( const QString& filename )
753{
754    if( !myFileDialogOptionsCheck->isChecked( ) ) {
755        mySession.addTorrent( filename );
756        QApplication :: alert ( this );
757    } else {
758        Options * o = new Options( mySession, myPrefs, filename, this );
759        o->show( );
760        QApplication :: alert( o );
761    }
762}
763
764/***
765****
766***/
767
768void
769TrMainWindow :: updateNetworkIcon( )
770{
771    const time_t now = time( NULL );
772    const int period = 3;
773    const bool isSending = now - myLastSendTime <= period;
774    const bool isReading = now - myLastReadTime <= period;
775    const char * key;
776
777    if( isSending && isReading )
778        key = "network-transmit-receive";
779    else if( isSending )
780        key = "network-transmit";
781    else if( isReading )
782        key = "network-receive";
783    else
784        key = "network-idle";
785
786    QIcon icon = getStockIcon( key, QStyle::SP_DriveNetIcon );
787    QPixmap pixmap = icon.pixmap ( 16, 16 );
788    ui.networkLabel->setPixmap( pixmap );
789    ui.networkLabel->setToolTip( isSending || isReading
790        ? tr( "Transmission server is responding" )
791        : tr( "Last response from server was %1 ago" ).arg( Utils::timeToString( now-std::max(myLastReadTime,myLastSendTime))));
792}
793
794void
795TrMainWindow :: onNetworkTimer( )
796{
797    updateNetworkIcon( );
798}
799
800void
801TrMainWindow :: dataReadProgress( )
802{
803    myLastReadTime = time( NULL );
804    updateNetworkIcon( );
805}
806
807void
808TrMainWindow :: dataSendProgress( )
809{
810    myLastSendTime = time( NULL );
811    updateNetworkIcon( );
812}
Note: See TracBrowser for help on using the repository browser.