source: trunk/qt/prefs-dialog.cc @ 8751

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

(trunk gtk,qt) more o/c simplification of the prefs dialog

  • Property svn:keywords set to Date Rev Author Id
File size: 24.2 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: prefs-dialog.cc 8751 2009-06-27 05:23:13Z charles $
11 */
12
13#include <cassert>
14#include <iostream>
15
16#include <QCoreApplication>
17#include <QCheckBox>
18#include <QFileDialog>
19#include <QComboBox>
20#include <QDialogButtonBox>
21#include <QDoubleSpinBox>
22#include <QHBoxLayout>
23#include <QLabel>
24#include <QLineEdit>
25#include <QFileInfo>
26#include <QList>
27#include <QPushButton>
28#include <QIcon>
29#include <QSpinBox>
30#include <QStyle>
31#include <QTabWidget>
32#include <QTime>
33#include <QTimeEdit>
34#include <QTimer>
35#include <QVBoxLayout>
36#include <QHttp>
37#include <QMessageBox>
38
39#include "hig.h"
40#include "prefs.h"
41#include "prefs-dialog.h"
42#include "qticonloader.h"
43#include "session.h"
44
45/***
46****
47***/
48
49namespace
50{
51    const char * PREF_KEY( "pref-key" );
52};
53
54void
55PrefsDialog :: checkBoxToggled( bool checked )
56{
57    const int key( sender( )->property( PREF_KEY ).toInt( ) );
58    myPrefs.set( key, checked );
59}
60
61QCheckBox *
62PrefsDialog :: checkBoxNew( const QString& text, int key )
63{
64    QCheckBox * box = new QCheckBox( text );
65    box->setChecked( myPrefs.getBool( key ) );
66    box->setProperty( PREF_KEY, key );
67    connect( box, SIGNAL(toggled(bool)), this, SLOT(checkBoxToggled(bool)));
68    myWidgets.insert( key, box );
69    return box;
70}
71
72void
73PrefsDialog :: enableBuddyWhenChecked( QCheckBox * box, QWidget * buddy )
74{
75    connect( box, SIGNAL(toggled(bool)), buddy, SLOT(setEnabled(bool)) );
76    buddy->setEnabled( box->isChecked( ) );
77}
78
79void
80PrefsDialog :: spinBoxChangedIdle( )
81{
82    const QObject * spin( sender()->property( "SPIN" ).value<QObject*>( ) );
83    const int key( spin->property( PREF_KEY ).toInt( ) );
84
85    const QDoubleSpinBox * d = qobject_cast<const QDoubleSpinBox*>( spin );
86    if( d != 0 )
87        myPrefs.set( key, d->value( ) );
88    else
89        myPrefs.set( key, qobject_cast<const QSpinBox*>(spin)->value( ) );
90}
91
92void
93PrefsDialog :: spinBoxChanged( int value )
94{
95    Q_UNUSED( value );
96
97    static const QString timerName( "TIMER_CHILD" );
98    QObject * o( sender( ) );
99
100    // user may be spinning through many values, so let's hold off
101    // for a moment to kekep from flooding a bunch of prefs changes
102    QTimer * timer( o->findChild<QTimer*>( timerName ) );
103    if( timer == 0 )
104    {
105        timer = new QTimer( o );
106        timer->setObjectName( timerName );
107        timer->setSingleShot( true );
108        timer->setProperty( "SPIN", qVariantFromValue( o ) );
109        connect( timer, SIGNAL(timeout()), this, SLOT(spinBoxChangedIdle()));
110    }
111    timer->start( 200 );
112}
113
114QSpinBox *
115PrefsDialog :: spinBoxNew( int key, int low, int high, int step )
116{
117    QSpinBox * spin = new QSpinBox( );
118    spin->setRange( low, high );
119    spin->setSingleStep( step );
120    spin->setValue( myPrefs.getInt( key ) );
121    spin->setProperty( PREF_KEY, key );
122    connect( spin, SIGNAL(valueChanged(int)), this, SLOT(spinBoxChanged(int)));
123    myWidgets.insert( key, spin );
124    return spin;
125}
126
127void
128PrefsDialog :: doubleSpinBoxChanged( double value )
129{
130    Q_UNUSED( value );
131
132    spinBoxChanged( 0 );
133}
134
135QDoubleSpinBox *
136PrefsDialog :: doubleSpinBoxNew( int key, double low, double high, double step, int decimals )
137{
138    QDoubleSpinBox * spin = new QDoubleSpinBox( );
139    spin->setRange( low, high );
140    spin->setSingleStep( step );
141    spin->setDecimals( decimals );
142    spin->setValue( myPrefs.getDouble( key ) );
143    spin->setProperty( PREF_KEY, key );
144    connect( spin, SIGNAL(valueChanged(double)), this, SLOT(doubleSpinBoxChanged(double)));
145    myWidgets.insert( key, spin );
146    return spin;
147}
148
149void
150PrefsDialog :: timeChanged( const QTime& time )
151{
152    const int key( sender()->property( PREF_KEY ).toInt( ) );
153    const int seconds( QTime().secsTo( time ) );
154    myPrefs.set( key, seconds / 60 );
155}
156
157QTimeEdit*
158PrefsDialog :: timeEditNew( int key )
159{
160    const int minutes( myPrefs.getInt( key ) );
161    QTimeEdit * e = new QTimeEdit( );
162    e->setDisplayFormat( "hh:mm" );
163    e->setProperty( PREF_KEY, key );
164    e->setTime( QTime().addSecs( minutes * 60 ) );
165    myWidgets.insert( key, e );
166    connect( e, SIGNAL(timeChanged(const QTime&)), this, SLOT(timeChanged(const QTime&)) );
167    return e;
168}
169
170void
171PrefsDialog :: textChanged( const QString& text )
172{
173    const int key( sender()->property( PREF_KEY ).toInt( ) );
174    myPrefs.set( key, text );
175}
176
177QLineEdit*
178PrefsDialog :: lineEditNew( int key, int echoMode )
179{
180    QLineEdit * e = new QLineEdit( myPrefs.getString( key ) );
181    e->setProperty( PREF_KEY, key );
182    e->setEchoMode( QLineEdit::EchoMode( echoMode ) );
183    myWidgets.insert( key, e );
184    connect( e, SIGNAL(textChanged(const QString&)), this, SLOT(textChanged(const QString&)) );
185    return e;
186}
187
188/***
189****
190***/
191
192QWidget *
193PrefsDialog :: createTrackerTab( )
194{
195    QWidget *l, *r;
196    HIG * hig = new HIG( );
197    hig->addSectionTitle( tr( "Tracker Proxy" ) );
198    hig->addWideControl( l = checkBoxNew( tr( "Connect to tracker via a pro&xy" ), Prefs::PROXY_ENABLED ) );
199    myUnsupportedWhenRemote << l;
200    l = hig->addRow( tr( "Proxy &server:" ), r = lineEditNew( Prefs::PROXY ) );
201    myProxyWidgets << l << r;
202    l = hig->addRow( tr( "Proxy &port:" ), r = spinBoxNew( Prefs::PROXY_PORT, 1, 65535, 1 ) );
203    myProxyWidgets << l << r;
204    hig->addWideControl( l = checkBoxNew( tr( "Use &authentication" ), Prefs::PROXY_AUTH_ENABLED ) );
205    myProxyWidgets << l;
206    l = hig->addRow( tr( "&Username:" ), r = lineEditNew( Prefs::PROXY_USERNAME ) );
207    myProxyAuthWidgets << l << r;
208    l = hig->addRow( tr( "Pass&word:" ), r = lineEditNew( Prefs::PROXY_PASSWORD, QLineEdit::Password ) );
209    myProxyAuthWidgets << l << r;
210    myUnsupportedWhenRemote << myProxyAuthWidgets;
211    hig->finish( );
212    return hig;
213}
214
215/***
216****
217***/
218
219QWidget *
220PrefsDialog :: createWebTab( Session& session )
221{
222    HIG * hig = new HIG( this );
223    hig->addSectionTitle( tr( "Web Client" ) );
224    QWidget * w;
225    QHBoxLayout * h = new QHBoxLayout( );
226    QIcon i( style()->standardIcon( QStyle::StandardPixmap( QStyle::SP_DirOpenIcon ) ) );
227    QPushButton * b = new QPushButton( i, tr( "&Open web client" ) );
228    connect( b, SIGNAL(clicked()), &session, SLOT(launchWebInterface()) );
229    h->addWidget( b, 0, Qt::AlignRight );
230    QWidget * l = checkBoxNew( tr( "&Enable web client" ), Prefs::RPC_ENABLED );
231    myUnsupportedWhenRemote << l;
232    hig->addRow( l, h, 0 );
233    l = hig->addRow( tr( "Listening &port:" ), w = spinBoxNew( Prefs::RPC_PORT, 0, 65535, 1 ) );
234    myWebWidgets << l << w;
235    hig->addWideControl( w = checkBoxNew( tr( "Use &authentication" ), Prefs::RPC_AUTH_REQUIRED ) );
236    myWebWidgets << w;
237    l = hig->addRow( tr( "&Username:" ), w = lineEditNew( Prefs::RPC_USERNAME ) );
238    myWebAuthWidgets << l << w;
239    l = hig->addRow( tr( "Pass&word:" ), w = lineEditNew( Prefs::RPC_PASSWORD, QLineEdit::Password ) );
240    myWebAuthWidgets << l << w;
241    hig->addWideControl( w = checkBoxNew( tr( "Only allow these IP a&ddresses to connect:" ), Prefs::RPC_WHITELIST_ENABLED ) );
242    myWebWidgets << w;
243    l = hig->addRow( tr( "Addresses:" ), w = lineEditNew( Prefs::RPC_WHITELIST ) );
244    myWebWhitelistWidgets << l << w;
245    myUnsupportedWhenRemote << myWebWidgets << myWebAuthWidgets << myWebWhitelistWidgets;
246    hig->finish( );
247    return hig;
248}
249
250/***
251****
252***/
253
254void
255PrefsDialog :: altSpeedDaysEdited( int i )
256{
257    const int value = qobject_cast<QComboBox*>(sender())->itemData(i).toInt();
258    myPrefs.set( Prefs::ALT_SPEED_LIMIT_TIME_DAY, value );
259}
260
261
262QWidget *
263PrefsDialog :: createSpeedTab( )
264{
265    QWidget *l, *r;
266    HIG * hig = new HIG( this );
267    hig->addSectionTitle( tr( "Speed Limits" ) );
268
269        l = checkBoxNew( tr( "Limit &download speed (KB/s):" ), Prefs::DSPEED_ENABLED );
270        r = spinBoxNew( Prefs::DSPEED, 0, INT_MAX, 5 );
271        hig->addRow( l, r );
272        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), r );
273
274        l = checkBoxNew( tr( "Limit &upload speed (KB/s):" ), Prefs::USPEED_ENABLED );
275        r = spinBoxNew( Prefs::USPEED, 0, INT_MAX, 5 );
276        hig->addRow( l, r );
277        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), r );
278
279    hig->addSectionDivider( );
280    QHBoxLayout * h = new QHBoxLayout;
281    h->setSpacing( HIG :: PAD );
282    QLabel * label = new QLabel;
283    label->setPixmap( QPixmap( ":/icons/alt-limit-off.png" ) );
284    label->setAlignment( Qt::AlignLeft|Qt::AlignVCenter );
285    h->addWidget( label );
286    label = new QLabel( tr( "Temporary Speed Limits" ) );
287    label->setStyleSheet( "font: bold" );
288    label->setAlignment( Qt::AlignLeft|Qt::AlignVCenter );
289    h->addWidget( label );
290    hig->addSectionTitle( h );
291
292        QString s = tr( "<small>Override normal speed limits manually or at scheduled times</small>" );
293        hig->addWideControl( new QLabel( s ) );
294
295        s = tr( "Limit d&ownload speed (KB/s):" );
296        r = spinBoxNew( Prefs :: ALT_SPEED_LIMIT_DOWN, 0, INT_MAX, 5 );
297        hig->addRow( s, r );
298
299        s = tr( "Limit u&pload speed (KB/s):" );
300        r = spinBoxNew( Prefs :: ALT_SPEED_LIMIT_UP, 0, INT_MAX, 5 );
301        hig->addRow( s, r );
302
303        QCheckBox * c = checkBoxNew( tr( "&Scheduled times:" ), Prefs::ALT_SPEED_LIMIT_TIME_ENABLED );
304        h = new QHBoxLayout( );
305        h->setSpacing( HIG::PAD );
306        QWidget * w = timeEditNew( Prefs :: ALT_SPEED_LIMIT_TIME_BEGIN );
307        h->addWidget( w, 1 );
308        mySchedWidgets << w;
309        QLabel * nd = new QLabel( "&to" );
310        h->addWidget( nd );
311        mySchedWidgets << nd;
312        w = timeEditNew( Prefs :: ALT_SPEED_LIMIT_TIME_END );
313        nd->setBuddy( w );
314        h->addWidget( w, 1 );
315        mySchedWidgets << w;
316        hig->addRow( c, h, 0 );
317
318        s = tr( "&On days:" );
319        QComboBox * box = new QComboBox;
320        const QIcon noIcon;
321        box->addItem( noIcon, tr( "Every Day" ), QVariant( TR_SCHED_ALL ) );
322        box->addItem( noIcon, tr( "Weekdays" ),  QVariant( TR_SCHED_WEEKDAY ) );
323        box->addItem( noIcon, tr( "Weekends" ),  QVariant( TR_SCHED_WEEKEND ) );
324        box->addItem( noIcon, tr( "Sunday" ),    QVariant( TR_SCHED_SUN ) );
325        box->addItem( noIcon, tr( "Monday" ),    QVariant( TR_SCHED_MON ) );
326        box->addItem( noIcon, tr( "Tuesday" ),   QVariant( TR_SCHED_TUES ) );
327        box->addItem( noIcon, tr( "Wednesday" ), QVariant( TR_SCHED_WED ) );
328        box->addItem( noIcon, tr( "Thursday" ),  QVariant( TR_SCHED_THURS ) );
329        box->addItem( noIcon, tr( "Friday" ),    QVariant( TR_SCHED_FRI ) );
330        box->addItem( noIcon, tr( "Saturday" ),  QVariant( TR_SCHED_SAT ) );
331        box->setCurrentIndex( box->findData( myPrefs.getInt( Prefs :: ALT_SPEED_LIMIT_TIME_DAY ) ) );
332        connect( box, SIGNAL(activated(int)), this, SLOT(altSpeedDaysEdited(int)) );
333        w = hig->addRow( s, box );
334        mySchedWidgets << w << box;
335
336    hig->finish( );
337    return hig;
338}
339
340/***
341****
342***/
343
344void
345PrefsDialog :: onPortTested( bool isOpen )
346{
347    myPortButton->setEnabled( true );
348    myWidgets[Prefs::PEER_PORT]->setEnabled( true );
349    myPortLabel->setText( isOpen ? tr( "Port is <b>open</b>" )
350                                 : tr( "Port is <b>closed</b>" ) );
351}
352
353void
354PrefsDialog :: onPortTest( )
355{
356    myPortLabel->setText( tr( "Testing..." ) );
357    myPortButton->setEnabled( false );
358    myWidgets[Prefs::PEER_PORT]->setEnabled( false );
359    mySession.portTest( );
360}
361
362QWidget *
363PrefsDialog :: createPeersTab( )
364{
365    HIG * hig = new HIG( this );
366    hig->addSectionTitle( tr( "Incoming Peers" ) );
367
368    QSpinBox * s = spinBoxNew( Prefs::PEER_PORT, 1, 65535, 1 );
369    QHBoxLayout * h = new QHBoxLayout( );
370    QPushButton * b = myPortButton = new QPushButton( tr( "&Test Port" ) );
371    QLabel * l = myPortLabel = new QLabel( tr( "Status unknown" ) );
372    h->addWidget( l );
373    h->addSpacing( HIG :: PAD_BIG );
374    h->addWidget( b );
375    h->setStretchFactor( l, 1 );
376    connect( b, SIGNAL(clicked(bool)), this, SLOT(onPortTest()));
377    connect( &mySession, SIGNAL(portTested(bool)), this, SLOT(onPortTested(bool)));
378
379    hig->addRow( tr( "&Port for incoming connections:" ), s );
380    hig->addRow( "", h, 0 );
381    hig->addWideControl( checkBoxNew( tr( "Use UPnP or NAT-PMP port &forwarding from my router" ), Prefs::PORT_FORWARDING ) );
382    hig->addWideControl( checkBoxNew( tr( "Pick a &random port every time Transmission is started" ), Prefs :: PEER_PORT_RANDOM_ON_START ) );
383
384    hig->addSectionDivider( );
385    hig->addSectionTitle( tr( "Limits" ) );
386    hig->addRow( tr( "Maximum peers per &torrent:" ), spinBoxNew( Prefs::PEER_LIMIT_TORRENT, 1, 300, 5 ) );
387    hig->addRow( tr( "Maximum peers &overall:" ), spinBoxNew( Prefs::PEER_LIMIT_GLOBAL, 1, 3000, 5 ) );
388
389    hig->finish( );
390    return hig;
391}
392
393/***
394****
395***/
396
397void
398PrefsDialog :: onBlocklistDialogDestroyed( QObject * o )
399{
400    Q_UNUSED( o );
401
402    myBlocklistDialog = 0;
403}
404
405void
406PrefsDialog :: onUpdateBlocklistCancelled( )
407{
408    disconnect( &mySession, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int))) ;
409    myBlocklistDialog->deleteLater( );
410}
411
412void
413PrefsDialog :: onBlocklistUpdated( int n )
414{
415    myBlocklistDialog->setText( tr( "<b>Update succeeded!</b><p>Blocklist now has %Ln rules.", 0, n ) );
416    myBlocklistDialog->setTextFormat( Qt::RichText );
417}
418
419void
420PrefsDialog :: onUpdateBlocklistClicked( )
421{
422    myBlocklistDialog = new QMessageBox( QMessageBox::Information,
423                                         "",
424                                         tr( "<b>Update Blocklist</b><p>Getting new blocklist..." ),
425                                         QMessageBox::Close,
426                                         this );
427    QPixmap pixmap;
428    QIcon icon = QtIconLoader :: icon( "dialog-information" );
429    if( !icon.isNull( ) ) {
430        const int size = style()->pixelMetric( QStyle::PM_LargeIconSize );
431        myBlocklistDialog->setIconPixmap( icon.pixmap( size, size ) );
432    }
433    connect( myBlocklistDialog, SIGNAL(rejected()), this, SLOT(onUpdateBlocklistCancelled()) );
434    connect( &mySession, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int))) ;
435    myBlocklistDialog->show( );
436    mySession.updateBlocklist( );
437}
438   
439void
440PrefsDialog :: encryptionEdited( int i )
441{
442    const int value( qobject_cast<QComboBox*>(sender())->itemData(i).toInt( ) );
443    myPrefs.set( Prefs::ENCRYPTION, value );
444}
445
446QWidget *
447PrefsDialog :: createPrivacyTab( )
448{
449    HIG * hig = new HIG( this );
450    hig->addSectionTitle( tr( "Blocklist" ) );
451    QHBoxLayout * h = new QHBoxLayout( );
452    QIcon i( style()->standardIcon( QStyle::StandardPixmap( QStyle::SP_BrowserReload ) ) );
453    QPushButton * w = new QPushButton( i, tr( "&Update blocklist" ) );
454    connect( w, SIGNAL(clicked(bool)), this, SLOT(onUpdateBlocklistClicked()));
455    myBlockWidgets << w;
456    QWidget * l = checkBoxNew( "", Prefs::BLOCKLIST_ENABLED );
457    h->addWidget( l );
458    h->addStretch( 1 );
459    h->addWidget( w );
460    hig->addWideControl( h );
461    l = checkBoxNew( tr( "Enable &automatic updates" ), Prefs::BLOCKLIST_UPDATES_ENABLED );
462    myBlockWidgets << l;
463    hig->addWideControl( l );
464
465    QComboBox * box = new QComboBox( );
466    box->addItem( tr( "Plaintext preferred" ), 0 );
467    box->addItem( tr( "Encryption preferred" ), 1 );
468    box->addItem( tr( "Encryption required" ), 2 );
469    myWidgets.insert( Prefs :: ENCRYPTION, box );
470    connect( box, SIGNAL(activated(int)), this, SLOT(encryptionEdited(int)));
471
472    hig->addSectionDivider( );
473    hig->addSectionTitle( tr( "Privacy" ) );
474    hig->addRow( tr( "&Encryption mode:" ), box );
475    hig->addWideControl( checkBoxNew( tr( "Use PE&X to find more peers" ), Prefs::PEX_ENABLED ) );
476    hig->addWideControl( checkBoxNew( tr( "Use &DHT to find more peers" ), Prefs::DHT_ENABLED ) );
477
478    hig->finish( );
479    updateBlocklistCheckBox( );
480    return hig;
481}
482
483/***
484****
485***/
486
487void
488PrefsDialog :: onWatchClicked( void )
489{
490    QFileDialog * d = new QFileDialog( this,
491                                       tr( "Select Watch Directory" ),
492                                       myPrefs.getString( Prefs::DIR_WATCH ) );
493    d->setFileMode( QFileDialog::Directory );
494    connect( d, SIGNAL(filesSelected(const QStringList&)), this, SLOT(onWatchSelected(const QStringList&)) );
495    d->show( );
496}
497
498void
499PrefsDialog :: onWatchSelected( const QStringList& list )
500{
501    if( list.size() == 1 )
502        myPrefs.set( Prefs::DIR_WATCH, list.first( ) );
503}
504
505void
506PrefsDialog :: onDestinationClicked( void )
507{
508    QFileDialog * d = new QFileDialog( this,
509                                       tr( "Select Destination" ),
510                                       myPrefs.getString( Prefs::DOWNLOAD_DIR ) );
511    d->setFileMode( QFileDialog::Directory );
512    connect( d, SIGNAL(filesSelected(const QStringList&)), this, SLOT(onDestinationSelected(const QStringList&)) );
513    d->show( );
514}
515
516void
517PrefsDialog :: onDestinationSelected( const QStringList& list )
518{
519    if( list.size() == 1 )
520        myPrefs.set( Prefs::DOWNLOAD_DIR, list.first( ) );
521}
522
523QWidget *
524PrefsDialog :: createTorrentsTab( )
525{
526    const int iconSize( style( )->pixelMetric( QStyle :: PM_SmallIconSize ) );
527    const QIcon folderIcon = QtIconLoader :: icon( "folder", style()->standardIcon( QStyle::SP_DirIcon ) );
528    const QPixmap folderPixmap = folderIcon.pixmap( iconSize );
529
530    QWidget *l, *r;
531    HIG * hig = new HIG( this );
532    hig->addSectionTitle( tr( "Adding Torrents" ) );
533
534        l = checkBoxNew( tr( "Automatically &add torrents from:" ), Prefs::DIR_WATCH_ENABLED );
535        QPushButton * b = myWatchButton = new QPushButton;
536        b->setIcon( folderPixmap );
537        b->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
538        connect( b, SIGNAL(clicked(bool)), this, SLOT(onWatchClicked(void)) );
539        hig->addRow( l, b );
540        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), b );
541
542        hig->addWideControl( checkBoxNew( tr( "Display &options dialog" ), Prefs::OPTIONS_PROMPT ) );
543        hig->addWideControl( checkBoxNew( tr( "&Start when added" ), Prefs::START ) );
544        hig->addWideControl( checkBoxNew( tr( "&Delete source files" ), Prefs::TRASH_ORIGINAL ) );
545
546        b = myDestinationButton = new QPushButton;
547        b->setIcon( folderPixmap );
548        b->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
549        connect( b, SIGNAL(clicked(bool)), this, SLOT(onDestinationClicked(void)) );
550        hig->addRow( tr( "Save to &Location:" ), b );
551
552    hig->addSectionDivider( );
553    hig->addSectionTitle( tr( "Limits" ) );
554
555        l = checkBoxNew( tr( "&Seed torrent until its ratio reaches:" ), Prefs::RATIO_ENABLED );
556        r = doubleSpinBoxNew( Prefs::RATIO, 0, INT_MAX, 0.5, 2 );
557        hig->addRow( l, r );
558        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), r );
559
560    hig->finish( );
561    return hig;
562}
563
564/***
565****
566***/
567
568PrefsDialog :: PrefsDialog( Session& session, Prefs& prefs, QWidget * parent ):
569    QDialog( parent ),
570    myIsServer( session.isServer( ) ),
571    mySession( session ),
572    myPrefs( prefs ),
573    myLayout( new QVBoxLayout( this ) )
574{
575    setWindowTitle( tr( "Transmission Preferences" ) );
576
577    QTabWidget * t = new QTabWidget( this );
578    t->addTab( createTorrentsTab( ),     tr( "Torrents" ) );
579    t->addTab( createSpeedTab( ),        tr( "Speed" ) );
580    t->addTab( createPrivacyTab( ),      tr( "Privacy" ) );
581    t->addTab( createPeersTab( ),        tr( "Peers" ) );
582    t->addTab( createWebTab( session ),  tr( "Web" ) );
583    //t->addTab( createTrackerTab( ),    tr( "Trackers" ) );
584    myLayout->addWidget( t );
585
586    QDialogButtonBox * buttons = new QDialogButtonBox( QDialogButtonBox::Close, Qt::Horizontal, this );
587    connect( buttons, SIGNAL(rejected()), this, SLOT(hide()) ); // "close" triggers rejected
588    myLayout->addWidget( buttons );
589
590    connect( &myPrefs, SIGNAL(changed(int)), this, SLOT(updatePref(int)));
591    connect( &mySession, SIGNAL(sessionUpdated()), this, SLOT(sessionUpdated()));
592
593    QList<int> keys;
594    keys << Prefs :: RPC_ENABLED
595         << Prefs :: PROXY_ENABLED
596         << Prefs :: ALT_SPEED_LIMIT_ENABLED
597         << Prefs :: ALT_SPEED_LIMIT_TIME_ENABLED
598         << Prefs :: ENCRYPTION
599         << Prefs :: BLOCKLIST_ENABLED
600         << Prefs :: DIR_WATCH
601         << Prefs :: DOWNLOAD_DIR;
602    foreach( int key, keys )
603        updatePref( key );
604
605    // if it's a remote session, disable the preferences
606    // that don't work in remote sessions
607    if( !myIsServer )  {
608        foreach( QWidget * w, myUnsupportedWhenRemote ) {
609            w->setToolTip( tr( "Not supported by remote sessions" ) );
610            w->setEnabled( false );
611        }
612    }
613}
614
615PrefsDialog :: ~PrefsDialog( )
616{
617}
618
619/***
620****
621***/
622
623void
624PrefsDialog :: sessionUpdated( )
625{
626    updateBlocklistCheckBox( );
627}
628
629void
630PrefsDialog :: updateBlocklistCheckBox( )
631{
632    QCheckBox * box = qobject_cast<QCheckBox*>( myWidgets[Prefs::BLOCKLIST_ENABLED] );
633    const int n = mySession.blocklistSize( );
634    if( n < 0 ) // unknown
635        box->setText( tr( "Enable &blocklist" ) );
636    else
637        box->setText( tr( "Enable &blocklist (%Ln rules)", 0, n ) );
638}
639
640void
641PrefsDialog :: updatePref( int key )
642{
643    switch( key )
644    {
645        case Prefs :: RPC_ENABLED:
646        case Prefs :: RPC_WHITELIST_ENABLED:
647        case Prefs :: RPC_AUTH_REQUIRED: {
648            const bool enabled( myPrefs.getBool( Prefs::RPC_ENABLED ) );
649            const bool whitelist( myPrefs.getBool( Prefs::RPC_WHITELIST_ENABLED ) );
650            const bool auth( myPrefs.getBool( Prefs::RPC_AUTH_REQUIRED ) );
651            foreach( QWidget * w, myWebWhitelistWidgets ) w->setEnabled( enabled && whitelist ); 
652            foreach( QWidget * w, myWebAuthWidgets ) w->setEnabled( enabled && auth ); 
653            foreach( QWidget * w, myWebWidgets ) w->setEnabled( enabled );
654            break;
655        }
656
657        case Prefs :: PROXY_ENABLED:
658        case Prefs :: PROXY_AUTH_ENABLED: {
659            const bool enabled( myPrefs.getBool( Prefs::PROXY_ENABLED ) );
660            const bool auth( myPrefs.getBool( Prefs::PROXY_AUTH_ENABLED ) );
661            foreach( QWidget * w, myProxyAuthWidgets ) w->setEnabled( enabled && auth ); 
662            foreach( QWidget * w, myProxyWidgets ) w->setEnabled( enabled );
663            break;
664        }
665
666        case Prefs :: ALT_SPEED_LIMIT_TIME_ENABLED: {
667            const bool enabled = myPrefs.getBool( key );
668            foreach( QWidget * w, mySchedWidgets ) w->setEnabled( enabled );
669            break;
670        }
671
672        case Prefs :: BLOCKLIST_ENABLED: {
673            const bool enabled = myPrefs.getBool( key );
674            foreach( QWidget * w, myBlockWidgets ) w->setEnabled( enabled );
675            break;
676        }
677
678        case Prefs :: DIR_WATCH:
679            myWatchButton->setText( QFileInfo(myPrefs.getString(Prefs::DIR_WATCH)).fileName() );
680            break;
681
682        case Prefs :: PEER_PORT:
683            myPortLabel->setText( tr( "Status unknown" ) );
684            myPortButton->setEnabled( true );
685            break;
686
687        case Prefs :: DOWNLOAD_DIR: {
688            QString path( myPrefs.getString( Prefs :: DOWNLOAD_DIR ) );
689            myDestinationButton->setText( QFileInfo(path).fileName() );
690            break;
691        }
692
693        default:
694            break;
695    }
696
697    key2widget_t::iterator it( myWidgets.find( key ) );
698    if( it != myWidgets.end( ) )
699    {
700        QWidget * w( it.value( ) );
701        QCheckBox * checkBox;
702        QSpinBox * spin;
703        QDoubleSpinBox * doubleSpin;
704        QTimeEdit * timeEdit;
705        QLineEdit * lineEdit;
706
707        if(( checkBox = qobject_cast<QCheckBox*>(w)))
708        {
709            checkBox->setChecked( myPrefs.getBool( key ) );
710        }
711        else if(( spin = qobject_cast<QSpinBox*>(w)))
712        {
713            spin->setValue( myPrefs.getInt( key ) );
714        }
715        else if(( doubleSpin = qobject_cast<QDoubleSpinBox*>(w)))
716        {
717            doubleSpin->setValue( myPrefs.getDouble( key ) );
718        }
719        else if(( timeEdit = qobject_cast<QTimeEdit*>(w)))
720        {
721            const int minutes( myPrefs.getInt( key ) );
722            timeEdit->setTime( QTime().addSecs( minutes * 60 ) );
723        }
724        else if(( lineEdit = qobject_cast<QLineEdit*>(w)))
725        {
726            lineEdit->setText( myPrefs.getString( key ) );
727        }
728        else if( key == Prefs::ENCRYPTION )
729        {
730            QComboBox * comboBox( qobject_cast<QComboBox*>( w ) );
731            const int index = comboBox->findData( myPrefs.getInt( key ) );
732            comboBox->setCurrentIndex( index );
733        }
734    }
735}
736
737bool
738PrefsDialog :: isAllowed( int key ) const
739{
740    Q_UNUSED( key );
741
742    return true;
743}
Note: See TracBrowser for help on using the repository browser.