~ubuntu-branches/ubuntu/karmic/transmission/karmic-proposed

« back to all changes in this revision

Viewing changes to qt/.svn/text-base/prefs-dialog.cc.svn-base

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Klimonda
  • Date: 2009-12-06 19:11:34 UTC
  • mfrom: (2.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20091206191134-t0ayk0mv6xuoyt0t
Tags: 1.75-0ubuntu2.1
* debian/patches/25_new_inhibition_api.diff:
  - Port Transmission to the new gnome-session inhibit API in order
    to make suspend/hibernate inhibiting work again on Karmic (LP: #457123)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <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
 
 
49
namespace
 
50
{
 
51
    const char * PREF_KEY( "pref-key" );
 
52
};
 
53
 
 
54
void
 
55
PrefsDialog :: checkBoxToggled( bool checked )
 
56
{
 
57
    const int key( sender( )->property( PREF_KEY ).toInt( ) );
 
58
    myPrefs.set( key, checked );
 
59
}
 
60
 
 
61
QCheckBox *
 
62
PrefsDialog :: 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
 
 
72
void
 
73
PrefsDialog :: enableBuddyWhenChecked( QCheckBox * box, QWidget * buddy )
 
74
{
 
75
    connect( box, SIGNAL(toggled(bool)), buddy, SLOT(setEnabled(bool)) );
 
76
    buddy->setEnabled( box->isChecked( ) );
 
77
}
 
78
 
 
79
void
 
80
PrefsDialog :: 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
 
 
92
void
 
93
PrefsDialog :: 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
 
 
114
QSpinBox *
 
115
PrefsDialog :: 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
 
 
127
void
 
128
PrefsDialog :: doubleSpinBoxChanged( double value )
 
129
{
 
130
    Q_UNUSED( value );
 
131
 
 
132
    spinBoxChanged( 0 );
 
133
}
 
134
 
 
135
QDoubleSpinBox *
 
136
PrefsDialog :: 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
 
 
149
void
 
150
PrefsDialog :: 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
 
 
157
QTimeEdit*
 
158
PrefsDialog :: 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
 
 
170
void
 
171
PrefsDialog :: textChanged( const QString& text )
 
172
{
 
173
    const int key( sender()->property( PREF_KEY ).toInt( ) );
 
174
    myPrefs.set( key, text );
 
175
}
 
176
 
 
177
QLineEdit*
 
178
PrefsDialog :: 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
 
 
192
QWidget *
 
193
PrefsDialog :: 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
 
 
219
QWidget *
 
220
PrefsDialog :: 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
 
 
254
void
 
255
PrefsDialog :: 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
 
 
262
QWidget *
 
263
PrefsDialog :: 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
 
 
344
void
 
345
PrefsDialog :: 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
 
 
353
void
 
354
PrefsDialog :: onPortTest( )
 
355
{
 
356
    myPortLabel->setText( tr( "Testing..." ) );
 
357
    myPortButton->setEnabled( false );
 
358
    myWidgets[Prefs::PEER_PORT]->setEnabled( false );
 
359
    mySession.portTest( );
 
360
}
 
361
 
 
362
QWidget *
 
363
PrefsDialog :: createNetworkTab( )
 
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
 
 
397
void
 
398
PrefsDialog :: onBlocklistDialogDestroyed( QObject * o )
 
399
{
 
400
    Q_UNUSED( o );
 
401
 
 
402
    myBlocklistDialog = 0;
 
403
}
 
404
 
 
405
void
 
406
PrefsDialog :: onUpdateBlocklistCancelled( )
 
407
{
 
408
    disconnect( &mySession, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int))) ;
 
409
    myBlocklistDialog->deleteLater( );
 
410
}
 
411
 
 
412
void
 
413
PrefsDialog :: 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
 
 
419
void
 
420
PrefsDialog :: 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
    
 
439
void
 
440
PrefsDialog :: encryptionEdited( int i )
 
441
{
 
442
    const int value( qobject_cast<QComboBox*>(sender())->itemData(i).toInt( ) );
 
443
    myPrefs.set( Prefs::ENCRYPTION, value );
 
444
}
 
445
 
 
446
QWidget *
 
447
PrefsDialog :: 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( "Allow encryption" ), 0 );
 
467
    box->addItem( tr( "Prefer encryption" ), 1 );
 
468
    box->addItem( tr( "Require encryption" ), 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
 
 
487
void
 
488
PrefsDialog :: 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
 
 
498
void
 
499
PrefsDialog :: onWatchSelected( const QStringList& list )
 
500
{
 
501
    if( list.size() == 1 )
 
502
        myPrefs.set( Prefs::DIR_WATCH, list.first( ) );
 
503
}
 
504
 
 
505
void
 
506
PrefsDialog :: 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
 
 
516
void
 
517
PrefsDialog :: onDestinationSelected( const QStringList& list )
 
518
{
 
519
    if( list.size() == 1 )
 
520
        myPrefs.set( Prefs::DOWNLOAD_DIR, list.first( ) );
 
521
}
 
522
 
 
523
QWidget *
 
524
PrefsDialog :: 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
 
 
568
PrefsDialog :: 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( createNetworkTab( ),      tr( "Network" ) );
 
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
 
 
615
PrefsDialog :: ~PrefsDialog( )
 
616
{
 
617
}
 
618
 
 
619
/***
 
620
****
 
621
***/
 
622
 
 
623
void
 
624
PrefsDialog :: sessionUpdated( )
 
625
{
 
626
    updateBlocklistCheckBox( );
 
627
}
 
628
 
 
629
void
 
630
PrefsDialog :: 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
 
 
640
void
 
641
PrefsDialog :: 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
 
 
737
bool
 
738
PrefsDialog :: isAllowed( int key ) const
 
739
{
 
740
    Q_UNUSED( key );
 
741
 
 
742
    return true;
 
743
}