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

Last change on this file since 14150 was 14150, checked in by jordan, 9 years ago

support qt5 in transmission-qt

  • Property svn:keywords set to Date Rev Author Id
File size: 27.6 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9 *
10 * $Id: prefs-dialog.cc 14150 2013-07-27 21:58:14Z jordan $
11 */
12
13#include <cassert>
14#include <iostream>
15
16#include <QCheckBox>
17#include <QComboBox>
18#include <QCoreApplication>
19#include <QDialogButtonBox>
20#include <QDoubleSpinBox>
21#include <QFileIconProvider>
22#include <QFileInfo>
23#include <QHBoxLayout>
24#include <QIcon>
25#include <QLabel>
26#include <QLineEdit>
27#include <QList>
28#include <QMessageBox>
29#include <QPushButton>
30#include <QSpinBox>
31#include <QStyle>
32#include <QTabWidget>
33#include <QTime>
34#include <QTimeEdit>
35#include <QTimer>
36#include <QVBoxLayout>
37
38#include "freespace-label.h"
39#include "formatter.h"
40#include "hig.h"
41#include "prefs.h"
42#include "prefs-dialog.h"
43#include "session.h"
44#include "utils.h"
45
46/***
47****
48***/
49
50namespace
51{
52    const char * PREF_KEY( "pref-key" );
53};
54
55void
56PrefsDialog :: checkBoxToggled( bool checked )
57{
58    const int key( sender( )->property( PREF_KEY ).toInt( ) );
59    setPref( key, checked );
60}
61
62QCheckBox *
63PrefsDialog :: checkBoxNew( const QString& text, int key )
64{
65    QCheckBox * box = new QCheckBox( text );
66    box->setChecked( myPrefs.getBool( key ) );
67    box->setProperty( PREF_KEY, key );
68    connect( box, SIGNAL(toggled(bool)), this, SLOT(checkBoxToggled(bool)));
69    myWidgets.insert( key, box );
70    return box;
71}
72
73void
74PrefsDialog :: enableBuddyWhenChecked( QCheckBox * box, QWidget * buddy )
75{
76    connect( box, SIGNAL(toggled(bool)), buddy, SLOT(setEnabled(bool)) );
77    buddy->setEnabled( box->isChecked( ) );
78}
79
80void
81PrefsDialog :: spinBoxEditingFinished()
82{
83    const QObject * spin = sender();
84    const int key = spin->property( PREF_KEY ).toInt( );
85    const QDoubleSpinBox * d = qobject_cast<const QDoubleSpinBox*>( spin );
86    if( d )
87        setPref( key, d->value( ) );
88    else
89        setPref( key, qobject_cast<const QSpinBox*>(spin)->value( ) );
90}
91
92QSpinBox *
93PrefsDialog :: spinBoxNew( int key, int low, int high, int step )
94{
95    QSpinBox * spin = new QSpinBox( );
96    spin->setRange( low, high );
97    spin->setSingleStep( step );
98    spin->setValue( myPrefs.getInt( key ) );
99    spin->setProperty( PREF_KEY, key );
100    connect( spin, SIGNAL(editingFinished()), this, SLOT(spinBoxEditingFinished()));
101    myWidgets.insert( key, spin );
102    return spin;
103}
104
105QDoubleSpinBox *
106PrefsDialog :: doubleSpinBoxNew( int key, double low, double high, double step, int decimals )
107{
108    QDoubleSpinBox * spin = new QDoubleSpinBox( );
109    spin->setRange( low, high );
110    spin->setSingleStep( step );
111    spin->setDecimals( decimals );
112    spin->setValue( myPrefs.getDouble( key ) );
113    spin->setProperty( PREF_KEY, key );
114    connect( spin, SIGNAL(editingFinished()), this, SLOT(spinBoxEditingFinished()));
115    myWidgets.insert( key, spin );
116    return spin;
117}
118
119void
120PrefsDialog :: timeEditingFinished( )
121{
122    QTimeEdit * e = qobject_cast<QTimeEdit*>(sender());
123    if( e )
124    {
125        const int key( e->property( PREF_KEY ).toInt( ) );
126        const QTime time( e->time( ) );
127        const int seconds( QTime().secsTo( time ) );
128std::cerr << "setPref to " << (seconds/60) << " minutes" << std::endl;
129        setPref( key, seconds / 60 );
130    }
131}
132QTimeEdit*
133PrefsDialog :: timeEditNew( int key )
134{
135    const int minutes( myPrefs.getInt( key ) );
136    QTimeEdit * e = new QTimeEdit( );
137    e->setDisplayFormat( QString::fromUtf8( "hh:mm" ) );
138    e->setProperty( PREF_KEY, key );
139    e->setTime( QTime().addSecs( minutes * 60 ) );
140    myWidgets.insert( key, e );
141    connect( e, SIGNAL(editingFinished()), this, SLOT(timeEditingFinished()) );
142    return e;
143}
144
145void
146PrefsDialog :: lineEditingFinished( )
147{
148    QLineEdit * e = qobject_cast<QLineEdit*>(sender());
149    if( e && e->isModified( ) )
150    {
151        const int key( e->property( PREF_KEY ).toInt( ) );
152        const QString text( e->text() );
153        setPref( key, text );
154    }
155}
156QLineEdit*
157PrefsDialog :: lineEditNew( int key, int echoMode )
158{
159    QLineEdit * e = new QLineEdit( myPrefs.getString( key ) );
160    e->setProperty( PREF_KEY, key );
161    e->setEchoMode( QLineEdit::EchoMode( echoMode ) );
162    myWidgets.insert( key, e );
163    connect( e, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished()) );
164    return e;
165}
166
167/***
168****
169***/
170
171QWidget *
172PrefsDialog :: createRemoteTab( Session& session )
173{
174    HIG * hig = new HIG( this );
175    hig->addSectionTitle( tr( "Remote Control" ) );
176    QWidget * w;
177    QHBoxLayout * h = new QHBoxLayout( );
178    QPushButton * b = new QPushButton( tr( "&Open web client" ) );
179    connect( b, SIGNAL(clicked()), &session, SLOT(launchWebInterface()) );
180    h->addWidget( b, 0, Qt::AlignRight );
181    QWidget * l = checkBoxNew( tr( "Allow &remote access" ), Prefs::RPC_ENABLED );
182    myUnsupportedWhenRemote << l;
183    hig->addRow( l, h, 0 );
184    l = hig->addRow( tr( "HTTP &port:" ), w = spinBoxNew( Prefs::RPC_PORT, 0, 65535, 1 ) );
185    myWebWidgets << l << w;
186    hig->addWideControl( w = checkBoxNew( tr( "Use &authentication" ), Prefs::RPC_AUTH_REQUIRED ) );
187    myWebWidgets << w;
188    l = hig->addRow( tr( "&Username:" ), w = lineEditNew( Prefs::RPC_USERNAME ) );
189    myWebAuthWidgets << l << w;
190    l = hig->addRow( tr( "Pass&word:" ), w = lineEditNew( Prefs::RPC_PASSWORD, QLineEdit::Password ) );
191    myWebAuthWidgets << l << w;
192    hig->addWideControl( w = checkBoxNew( tr( "Only allow these IP a&ddresses:" ), Prefs::RPC_WHITELIST_ENABLED ) );
193    myWebWidgets << w;
194    l = hig->addRow( tr( "Addresses:" ), w = lineEditNew( Prefs::RPC_WHITELIST ) );
195    myWebWhitelistWidgets << l << w;
196    myUnsupportedWhenRemote << myWebWidgets << myWebAuthWidgets << myWebWhitelistWidgets;
197    hig->finish( );
198    return hig;
199}
200
201/***
202****
203***/
204
205void
206PrefsDialog :: altSpeedDaysEdited( int i )
207{
208    const int value = qobject_cast<QComboBox*>(sender())->itemData(i).toInt();
209    setPref( Prefs::ALT_SPEED_LIMIT_TIME_DAY, value );
210}
211
212
213QWidget *
214PrefsDialog :: createSpeedTab( )
215{
216    QWidget *l, *r;
217    HIG * hig = new HIG( this );
218    hig->addSectionTitle( tr( "Speed Limits" ) );
219    const QString speed_K_str = Formatter::unitStr( Formatter::SPEED, Formatter::KB );
220
221        l = checkBoxNew( tr( "&Upload (%1):" ).arg( speed_K_str ), Prefs::USPEED_ENABLED );
222        r = spinBoxNew( Prefs::USPEED, 0, INT_MAX, 5 );
223        hig->addRow( l, r );
224        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), r );
225
226        l = checkBoxNew( tr( "&Download (%1):" ).arg( speed_K_str ), Prefs::DSPEED_ENABLED );
227        r = spinBoxNew( Prefs::DSPEED, 0, INT_MAX, 5 );
228        hig->addRow( l, r );
229        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), r );
230
231    hig->addSectionDivider( );
232    QHBoxLayout * h = new QHBoxLayout;
233    h->setSpacing( HIG :: PAD );
234    QLabel * label = new QLabel;
235    label->setPixmap( QPixmap( QString::fromUtf8( ":/icons/alt-limit-off.png" ) ) );
236    label->setAlignment( Qt::AlignLeft|Qt::AlignVCenter );
237    h->addWidget( label );
238    label = new QLabel( tr( "Alternative Speed Limits" ) );
239    label->setStyleSheet( QString::fromUtf8( "font: bold" ) );
240    label->setAlignment( Qt::AlignLeft|Qt::AlignVCenter );
241    h->addWidget( label );
242    hig->addSectionTitle( h );
243
244        QString s = tr( "<small>Override normal speed limits manually or at scheduled times</small>" );
245        hig->addWideControl( new QLabel( s ) );
246
247        s = tr( "U&pload (%1):" ).arg( speed_K_str );
248        r = spinBoxNew( Prefs :: ALT_SPEED_LIMIT_UP, 0, INT_MAX, 5 );
249        hig->addRow( s, r );
250
251        s = tr( "Do&wnload (%1):" ).arg( speed_K_str );
252        r = spinBoxNew( Prefs :: ALT_SPEED_LIMIT_DOWN, 0, INT_MAX, 5 );
253        hig->addRow( s, r );
254
255        QCheckBox * c = checkBoxNew( tr( "&Scheduled times:" ), Prefs::ALT_SPEED_LIMIT_TIME_ENABLED );
256        h = new QHBoxLayout( );
257        h->setSpacing( HIG::PAD );
258        QWidget * w = timeEditNew( Prefs :: ALT_SPEED_LIMIT_TIME_BEGIN );
259        h->addWidget( w, 1 );
260        mySchedWidgets << w;
261        QLabel * nd = new QLabel( tr("&to") );
262        h->addWidget( nd );
263        mySchedWidgets << nd;
264        w = timeEditNew( Prefs :: ALT_SPEED_LIMIT_TIME_END );
265        nd->setBuddy( w );
266        h->addWidget( w, 1 );
267        mySchedWidgets << w;
268        hig->addRow( c, h, 0 );
269
270        s = tr( "&On days:" );
271        QComboBox * box = new QComboBox;
272        const QIcon noIcon;
273        box->addItem( noIcon, tr( "Every Day" ), QVariant( TR_SCHED_ALL ) );
274        box->addItem( noIcon, tr( "Weekdays" ),  QVariant( TR_SCHED_WEEKDAY ) );
275        box->addItem( noIcon, tr( "Weekends" ),  QVariant( TR_SCHED_WEEKEND ) );
276        box->addItem( noIcon, tr( "Sunday" ),    QVariant( TR_SCHED_SUN ) );
277        box->addItem( noIcon, tr( "Monday" ),    QVariant( TR_SCHED_MON ) );
278        box->addItem( noIcon, tr( "Tuesday" ),   QVariant( TR_SCHED_TUES ) );
279        box->addItem( noIcon, tr( "Wednesday" ), QVariant( TR_SCHED_WED ) );
280        box->addItem( noIcon, tr( "Thursday" ),  QVariant( TR_SCHED_THURS ) );
281        box->addItem( noIcon, tr( "Friday" ),    QVariant( TR_SCHED_FRI ) );
282        box->addItem( noIcon, tr( "Saturday" ),  QVariant( TR_SCHED_SAT ) );
283        box->setCurrentIndex( box->findData( myPrefs.getInt( Prefs :: ALT_SPEED_LIMIT_TIME_DAY ) ) );
284        connect( box, SIGNAL(activated(int)), this, SLOT(altSpeedDaysEdited(int)) );
285        w = hig->addRow( s, box );
286        mySchedWidgets << w << box;
287
288    hig->finish( );
289    return hig;
290}
291
292/***
293****
294***/
295
296QWidget *
297PrefsDialog :: createDesktopTab( )
298{
299    HIG * hig = new HIG( this );
300    hig->addSectionTitle( tr( "Desktop" ) );
301
302      hig->addWideControl( checkBoxNew( tr( "Show Transmission icon in the &notification area" ), Prefs::SHOW_TRAY_ICON ) );
303      hig->addWideControl( checkBoxNew( tr( "Start &minimized in notification area" ), Prefs::START_MINIMIZED ) );
304
305    hig->addSectionDivider( );
306    hig->addSectionTitle( tr ("Notification") );
307
308      hig->addWideControl( checkBoxNew( tr( "Show a notification when torrents are a&dded" ), Prefs::SHOW_NOTIFICATION_ON_ADD ) );
309      hig->addWideControl( checkBoxNew( tr( "Show a notification when torrents &finish" ), Prefs::SHOW_NOTIFICATION_ON_COMPLETE ) );
310      hig->addWideControl( checkBoxNew( tr( "Play a &sound when torrents finish" ), Prefs::COMPLETE_SOUND_ENABLED ) );
311
312    hig->finish( );
313    return hig;
314}
315
316/***
317****
318***/
319
320void
321PrefsDialog :: onPortTested( bool isOpen )
322{
323    myPortButton->setEnabled( true );
324    myWidgets[Prefs::PEER_PORT]->setEnabled( true );
325    myPortLabel->setText( isOpen ? tr( "Port is <b>open</b>" )
326                                 : tr( "Port is <b>closed</b>" ) );
327}
328
329void
330PrefsDialog :: onPortTest( )
331{
332    myPortLabel->setText( tr( "Testing TCP Port..." ) );
333    myPortButton->setEnabled( false );
334    myWidgets[Prefs::PEER_PORT]->setEnabled( false );
335    mySession.portTest( );
336}
337
338QWidget *
339PrefsDialog :: createNetworkTab( )
340{
341    HIG * hig = new HIG( this );
342    hig->addSectionTitle( tr( "Incoming Peers" ) );
343
344    QSpinBox * s = spinBoxNew( Prefs::PEER_PORT, 1, 65535, 1 );
345    QHBoxLayout * h = new QHBoxLayout( );
346    QPushButton * b = myPortButton = new QPushButton( tr( "Te&st Port" ) );
347    QLabel * l = myPortLabel = new QLabel( tr( "Status unknown" ) );
348    h->addWidget( l );
349    h->addSpacing( HIG :: PAD_BIG );
350    h->addWidget( b );
351    h->setStretchFactor( l, 1 );
352    connect( b, SIGNAL(clicked(bool)), this, SLOT(onPortTest()));
353    connect( &mySession, SIGNAL(portTested(bool)), this, SLOT(onPortTested(bool)));
354
355    hig->addRow( tr( "&Port for incoming connections:" ), s );
356    hig->addRow( QString(), h, 0 );
357    hig->addWideControl( checkBoxNew( tr( "Pick a &random port every time Transmission is started" ), Prefs :: PEER_PORT_RANDOM_ON_START ) );
358    hig->addWideControl( checkBoxNew( tr( "Use UPnP or NAT-PMP port &forwarding from my router" ), Prefs::PORT_FORWARDING ) );
359
360    hig->addSectionDivider( );
361    hig->addSectionTitle( tr( "Peer Limits" ) );
362    hig->addRow( tr( "Maximum peers per &torrent:" ), spinBoxNew( Prefs::PEER_LIMIT_TORRENT, 1, FD_SETSIZE, 5 ) );
363    hig->addRow( tr( "Maximum peers &overall:" ), spinBoxNew( Prefs::PEER_LIMIT_GLOBAL, 1, FD_SETSIZE, 5 ) );
364
365    hig->addSectionDivider( );
366    hig->addSectionTitle( tr( "Options" ) );
367
368    QWidget * w;
369    hig->addWideControl( w = checkBoxNew( tr( "Enable &uTP for peer connections" ), Prefs::UTP_ENABLED ) );
370    w->setToolTip( tr( "uTP is a tool for reducing network congestion." ) );
371    hig->addWideControl( w = checkBoxNew( tr( "Use PE&X to find more peers" ), Prefs::PEX_ENABLED ) );
372    w->setToolTip( tr( "PEX is a tool for exchanging peer lists with the peers you're connected to." ) );
373    hig->addWideControl( w = checkBoxNew( tr( "Use &DHT to find more peers" ), Prefs::DHT_ENABLED ) );
374    w->setToolTip( tr( "DHT is a tool for finding peers without a tracker." ) );
375    hig->addWideControl( w = checkBoxNew( tr( "Use &Local Peer Discovery to find more peers" ), Prefs::LPD_ENABLED ) );
376    w->setToolTip( tr( "LPD is a tool for finding peers on your local network." ) );
377
378    hig->finish( );
379    return hig;
380}
381
382/***
383****
384***/
385
386void
387PrefsDialog :: onBlocklistDialogDestroyed( QObject * o )
388{
389    Q_UNUSED( o );
390
391    myBlocklistDialog = 0;
392}
393
394void
395PrefsDialog :: onUpdateBlocklistCancelled( )
396{
397    disconnect( &mySession, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int))) ;
398    myBlocklistDialog->deleteLater( );
399}
400
401void
402PrefsDialog :: onBlocklistUpdated( int n )
403{
404    myBlocklistDialog->setText( tr( "<b>Update succeeded!</b><p>Blocklist now has %Ln rules.", 0, n ) );
405    myBlocklistDialog->setTextFormat( Qt::RichText );
406}
407
408void
409PrefsDialog :: onUpdateBlocklistClicked( )
410{
411    myBlocklistDialog = new QMessageBox( QMessageBox::Information,
412                                         QString(),
413                                         tr( "<b>Update Blocklist</b><p>Getting new blocklist..." ),
414                                         QMessageBox::Close,
415                                         this );
416    connect( myBlocklistDialog, SIGNAL(rejected()), this, SLOT(onUpdateBlocklistCancelled()) );
417    connect( &mySession, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int))) ;
418    myBlocklistDialog->show( );
419    mySession.updateBlocklist( );
420}
421
422void
423PrefsDialog :: encryptionEdited( int i )
424{
425    const int value( qobject_cast<QComboBox*>(sender())->itemData(i).toInt( ) );
426    setPref( Prefs::ENCRYPTION, value );
427}
428
429QWidget *
430PrefsDialog :: createPrivacyTab( )
431{
432    QWidget * w;
433    HIG * hig = new HIG( this );
434
435    hig->addSectionTitle( tr( "Encryption" ) );
436
437    QComboBox * box = new QComboBox( );
438    box->addItem( tr( "Allow encryption" ), 0 );
439    box->addItem( tr( "Prefer encryption" ), 1 );
440    box->addItem( tr( "Require encryption" ), 2 );
441    myWidgets.insert( Prefs :: ENCRYPTION, box );
442    connect( box, SIGNAL(activated(int)), this, SLOT(encryptionEdited(int)));
443
444    hig->addRow( tr( "&Encryption mode:" ), box );
445
446    hig->addSectionDivider( );
447    hig->addSectionTitle( tr( "Blocklist" ) );
448
449    QWidget * l = checkBoxNew( tr("Enable &blocklist:"), Prefs::BLOCKLIST_ENABLED );
450    QWidget * e = lineEditNew( Prefs::BLOCKLIST_URL );
451    myBlockWidgets << e;
452    hig->addRow( l, e );
453
454    l = myBlocklistLabel = new QLabel( );
455    myBlockWidgets << l;
456    w = new QPushButton( tr( "&Update" ) );
457    connect( w, SIGNAL(clicked(bool)), this, SLOT(onUpdateBlocklistClicked()));
458    myBlockWidgets << w;
459    QHBoxLayout * h = new QHBoxLayout( );
460    h->addWidget( l );
461    h->addStretch( 1 );
462    h->addWidget( w );
463    hig->addWideControl( h );
464
465    l = checkBoxNew( tr( "Enable &automatic updates" ), Prefs::BLOCKLIST_UPDATES_ENABLED );
466    myBlockWidgets << l;
467    hig->addWideControl( l );
468
469    hig->finish( );
470    updateBlocklistLabel( );
471    return hig;
472}
473
474/***
475****
476***/
477
478void
479PrefsDialog :: onScriptClicked( void )
480{
481    const QString title = tr( "Select \"Torrent Done\" Script" );
482    const QString myPath = myPrefs.getString( Prefs::SCRIPT_TORRENT_DONE_FILENAME );
483    const QString path = Utils::remoteFileChooser( this, title, myPath, false, mySession.isServer() );
484
485    if( !path.isEmpty() )
486        onLocationSelected( path, Prefs::SCRIPT_TORRENT_DONE_FILENAME );
487}
488
489void
490PrefsDialog :: onIncompleteClicked( void )
491{
492    const QString title = tr( "Select Incomplete Directory" );
493    const QString myPath = myPrefs.getString( Prefs::INCOMPLETE_DIR );
494    const QString path = Utils::remoteFileChooser( this, title, myPath, true, mySession.isServer() );
495
496    if( !path.isEmpty() )
497        onLocationSelected( path, Prefs::INCOMPLETE_DIR );
498}
499
500void
501PrefsDialog :: onWatchClicked( void )
502{
503    const QString title = tr( "Select Watch Directory" );
504    const QString myPath = myPrefs.getString( Prefs::DIR_WATCH );
505    const QString path = Utils::remoteFileChooser( this, title, myPath, true, true );
506
507    if( !path.isEmpty() )
508        onLocationSelected( path, Prefs::DIR_WATCH );
509}
510
511void
512PrefsDialog :: onDestinationClicked( void )
513{
514    const QString title = tr( "Select Destination" );
515    const QString myPath = myPrefs.getString( Prefs::DOWNLOAD_DIR );
516    const QString path = Utils::remoteFileChooser( this, title, myPath, true, mySession.isServer() );
517
518    if( !path.isEmpty() )
519        onLocationSelected( path, Prefs::DOWNLOAD_DIR );
520}
521
522void
523PrefsDialog :: onLocationSelected( const QString& path, int key )
524{
525    setPref( key, path );
526}
527
528QWidget *
529PrefsDialog :: createSeedingTab( )
530{
531    const int iconSize( style( )->pixelMetric( QStyle :: PM_SmallIconSize ) );
532    const QFileIconProvider iconProvider;
533    const QIcon folderIcon = iconProvider.icon( QFileIconProvider::Folder );
534    const QPixmap folderPixmap = folderIcon.pixmap( iconSize );
535    const QIcon fileIcon = iconProvider.icon( QFileIconProvider::File );
536    const QPixmap filePixmap = fileIcon.pixmap( iconSize );
537
538    QWidget *l, *r;
539    HIG * hig = new HIG( this );
540    hig->addSectionTitle( tr( "Limits" ) );
541
542        l = checkBoxNew( tr( "Stop seeding at &ratio:" ), Prefs::RATIO_ENABLED );
543        r = doubleSpinBoxNew( Prefs::RATIO, 0, INT_MAX, 0.5, 2 );
544        hig->addRow( l, r );
545        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), r );
546
547        l = checkBoxNew( tr( "Stop seeding if idle for &N minutes:" ), Prefs::IDLE_LIMIT_ENABLED );
548        r = spinBoxNew( Prefs::IDLE_LIMIT, 1, INT_MAX, 5 );
549        hig->addRow( l, r );
550        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), r );
551
552    hig->finish( );
553    return hig;
554}
555
556QWidget *
557PrefsDialog :: createDownloadingTab( )
558{
559    const int iconSize( style( )->pixelMetric( QStyle :: PM_SmallIconSize ) );
560    const QFileIconProvider iconProvider;
561    const QIcon folderIcon = iconProvider.icon( QFileIconProvider::Folder );
562    const QPixmap folderPixmap = folderIcon.pixmap( iconSize );
563    const QIcon fileIcon = iconProvider.icon( QFileIconProvider::File );
564    const QPixmap filePixmap = fileIcon.pixmap( iconSize );
565
566    QWidget * l;
567    QPushButton * b;
568    HIG * hig = new HIG( this );
569    hig->addSectionTitle( tr( "Adding" ) );
570
571        l = checkBoxNew( tr( "Automatically add .torrent files &from:" ), Prefs::DIR_WATCH_ENABLED );
572        b = myWatchButton = new QPushButton;
573        b->setIcon( folderPixmap );
574        b->setStyleSheet( QString::fromUtf8( "text-align: left; padding-left: 5; padding-right: 5" ) );
575        connect( b, SIGNAL(clicked(bool)), this, SLOT(onWatchClicked(void)) );
576        hig->addRow( l, b );
577        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), b );
578
579        hig->addWideControl( checkBoxNew( tr( "Show the Torrent Options &dialog" ), Prefs::OPTIONS_PROMPT ) );
580
581        hig->addWideControl( checkBoxNew( tr( "&Start added torrents" ), Prefs::START ) );
582
583        hig->addWideControl( checkBoxNew( tr( "Mo&ve the .torrent file to the trash" ), Prefs::TRASH_ORIGINAL ) );
584
585        b = myDestinationButton = new QPushButton;
586        b->setIcon( folderPixmap );
587        b->setStyleSheet( QString::fromUtf8( "text-align: left; padding-left: 5; padding-right: 5" ) );
588        connect( b, SIGNAL(clicked(bool)), this, SLOT(onDestinationClicked(void)) );
589        hig->addRow( tr( "Save to &Location:" ), b );
590
591        const QString downloadDir (myPrefs.getString(Prefs::DOWNLOAD_DIR));
592        l = myFreespaceLabel = new FreespaceLabel (mySession, downloadDir, this);
593        QHBoxLayout * h = new QHBoxLayout ();
594        h->addStretch (1);
595        h->addWidget (l);
596        hig->addWideControl (h);
597
598    hig->addSectionDivider( );
599    hig->addSectionTitle( tr( "Download Queue" ) );
600   
601        hig->addRow( tr( "Ma&ximum active downloads:" ), spinBoxNew( Prefs::DOWNLOAD_QUEUE_SIZE, 1, INT_MAX, 1 ) );
602        hig->addRow( tr( "Downloads sharing data in the last &N minutes are active:" ), spinBoxNew( Prefs::QUEUE_STALLED_MINUTES, 1, INT_MAX, 10 ) );
603
604    hig->addSectionDivider( );
605    hig->addSectionTitle( tr( "Incomplete" ) );
606
607        hig->addWideControl( checkBoxNew( tr( "Append \".&part\" to incomplete files' names" ), Prefs::RENAME_PARTIAL_FILES ) );
608
609        l = myIncompleteCheckbox = checkBoxNew( tr( "Keep &incomplete files in:" ), Prefs::INCOMPLETE_DIR_ENABLED );
610        b = myIncompleteButton = new QPushButton;
611        b->setIcon( folderPixmap );
612        b->setStyleSheet( QString::fromUtf8( "text-align: left; padding-left: 5; padding-right: 5" ) );
613        connect( b, SIGNAL(clicked(bool)), this, SLOT(onIncompleteClicked(void)) );
614        hig->addRow( myIncompleteCheckbox, b );
615        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), b );
616
617        l = myTorrentDoneScriptCheckbox = checkBoxNew( tr( "Call scrip&t when torrent is completed:" ), Prefs::SCRIPT_TORRENT_DONE_ENABLED );
618        b = myTorrentDoneScriptButton = new QPushButton;
619        b->setIcon( filePixmap );
620        b->setStyleSheet( QString::fromUtf8( "text-align: left; padding-left: 5; padding-right: 5" ) );
621        connect( b, SIGNAL(clicked(bool)), this, SLOT(onScriptClicked(void)) );
622        hig->addRow( myTorrentDoneScriptCheckbox, b );
623        enableBuddyWhenChecked( qobject_cast<QCheckBox*>(l), b );
624
625    hig->finish( );
626    return hig;
627}
628
629/***
630****
631***/
632
633PrefsDialog :: PrefsDialog( Session& session, Prefs& prefs, QWidget * parent ):
634    QDialog( parent ),
635    myIsServer( session.isServer( ) ),
636    mySession( session ),
637    myPrefs( prefs ),
638    myLayout( new QVBoxLayout( this ) )
639{
640    setWindowTitle( tr( "Transmission Preferences" ) );
641
642    QTabWidget * t = new QTabWidget( this );
643    t->addTab( createSpeedTab( ),        tr( "Speed" ) );
644    t->addTab( createDownloadingTab( ),  tr( "Downloading" ) );
645    t->addTab( createSeedingTab( ),      tr( "Seeding" ) );
646    t->addTab( createPrivacyTab( ),      tr( "Privacy" ) );
647    t->addTab( createNetworkTab( ),      tr( "Network" ) );
648    t->addTab( createDesktopTab( ),      tr( "Desktop" ) );
649    t->addTab( createRemoteTab(session), tr( "Remote" ) );
650    myLayout->addWidget( t );
651
652    QDialogButtonBox * buttons = new QDialogButtonBox( QDialogButtonBox::Close, Qt::Horizontal, this );
653    connect( buttons, SIGNAL(rejected()), this, SLOT(close()) ); // "close" triggers rejected
654    myLayout->addWidget( buttons );
655    QWidget::setAttribute( Qt::WA_DeleteOnClose, true );
656
657    connect( &mySession, SIGNAL(sessionUpdated()), this, SLOT(sessionUpdated()));
658
659    QList<int> keys;
660    keys << Prefs :: RPC_ENABLED
661         << Prefs :: ALT_SPEED_LIMIT_ENABLED
662         << Prefs :: ALT_SPEED_LIMIT_TIME_ENABLED
663         << Prefs :: ENCRYPTION
664         << Prefs :: BLOCKLIST_ENABLED
665         << Prefs :: DIR_WATCH
666         << Prefs :: DOWNLOAD_DIR
667         << Prefs :: INCOMPLETE_DIR
668         << Prefs :: INCOMPLETE_DIR_ENABLED
669         << Prefs :: SCRIPT_TORRENT_DONE_FILENAME;
670    foreach( int key, keys )
671        refreshPref( key );
672
673    // if it's a remote session, disable the preferences
674    // that don't work in remote sessions
675    if( !myIsServer )  {
676        foreach( QWidget * w, myUnsupportedWhenRemote ) {
677            w->setToolTip( tr( "Not supported by remote sessions" ) );
678            w->setEnabled( false );
679        }
680    }
681}
682
683PrefsDialog :: ~PrefsDialog( )
684{
685}
686
687void
688PrefsDialog :: setPref( int key, const QVariant& v )
689{
690    myPrefs.set( key, v );
691    refreshPref( key );
692}
693
694/***
695****
696***/
697
698void
699PrefsDialog :: sessionUpdated( )
700{
701    updateBlocklistLabel( );
702}
703
704void
705PrefsDialog :: updateBlocklistLabel( )
706{
707    const int n = mySession.blocklistSize( );
708    myBlocklistLabel->setText( tr( "<i>Blocklist contains %Ln rules</i>", 0, n ) );
709}
710
711void
712PrefsDialog :: refreshPref( int key )
713{
714    switch( key )
715    {
716        case Prefs :: RPC_ENABLED:
717        case Prefs :: RPC_WHITELIST_ENABLED:
718        case Prefs :: RPC_AUTH_REQUIRED: {
719            const bool enabled( myPrefs.getBool( Prefs::RPC_ENABLED ) );
720            const bool whitelist( myPrefs.getBool( Prefs::RPC_WHITELIST_ENABLED ) );
721            const bool auth( myPrefs.getBool( Prefs::RPC_AUTH_REQUIRED ) );
722            foreach( QWidget * w, myWebWhitelistWidgets ) w->setEnabled( enabled && whitelist );
723            foreach( QWidget * w, myWebAuthWidgets ) w->setEnabled( enabled && auth );
724            foreach( QWidget * w, myWebWidgets ) w->setEnabled( enabled );
725            break;
726        }
727
728        case Prefs :: ALT_SPEED_LIMIT_TIME_ENABLED: {
729            const bool enabled = myPrefs.getBool( key );
730            foreach( QWidget * w, mySchedWidgets ) w->setEnabled( enabled );
731            break;
732        }
733
734        case Prefs :: BLOCKLIST_ENABLED: {
735            const bool enabled = myPrefs.getBool( key );
736            foreach( QWidget * w, myBlockWidgets ) w->setEnabled( enabled );
737            break;
738        }
739
740        case Prefs :: DIR_WATCH:
741            myWatchButton->setText( QFileInfo(myPrefs.getString(Prefs::DIR_WATCH)).fileName() );
742            break;
743
744        case Prefs :: SCRIPT_TORRENT_DONE_FILENAME: {
745            const QString path( myPrefs.getString( key ) );
746            myTorrentDoneScriptButton->setText( QFileInfo(path).fileName() );
747            break;
748        }
749
750        case Prefs :: PEER_PORT:
751            myPortLabel->setText( tr( "Status unknown" ) );
752            myPortButton->setEnabled( true );
753            break;
754
755        case Prefs :: DOWNLOAD_DIR: {
756            const QString path( myPrefs.getString( key ) );
757            myDestinationButton->setText( QFileInfo(path).fileName() );
758            myFreespaceLabel->setPath (path);
759            break;
760        }
761
762        case Prefs :: INCOMPLETE_DIR: {
763            QString path( myPrefs.getString( key ) );
764            myIncompleteButton->setText( QFileInfo(path).fileName() );
765            break;
766        }
767
768        case Prefs :: INCOMPLETE_DIR_ENABLED: {
769            const bool enabled = myPrefs.getBool( key );
770            myIncompleteButton->setEnabled( enabled );
771            break;
772        }
773
774        default:
775            break;
776    }
777
778    key2widget_t::iterator it( myWidgets.find( key ) );
779    if( it != myWidgets.end( ) )
780    {
781        QWidget * w( it.value( ) );
782        QCheckBox * checkBox;
783        QSpinBox * spin;
784        QDoubleSpinBox * doubleSpin;
785        QTimeEdit * timeEdit;
786        QLineEdit * lineEdit;
787
788        if(( checkBox = qobject_cast<QCheckBox*>(w)))
789        {
790            checkBox->setChecked( myPrefs.getBool( key ) );
791        }
792        else if(( spin = qobject_cast<QSpinBox*>(w)))
793        {
794            spin->setValue( myPrefs.getInt( key ) );
795        }
796        else if(( doubleSpin = qobject_cast<QDoubleSpinBox*>(w)))
797        {
798            doubleSpin->setValue( myPrefs.getDouble( key ) );
799        }
800        else if(( timeEdit = qobject_cast<QTimeEdit*>(w)))
801        {
802            const int minutes( myPrefs.getInt( key ) );
803            timeEdit->setTime( QTime().addSecs( minutes * 60 ) );
804        }
805        else if(( lineEdit = qobject_cast<QLineEdit*>(w)))
806        {
807            lineEdit->setText( myPrefs.getString( key ) );
808        }
809        else if( key == Prefs::ENCRYPTION )
810        {
811            QComboBox * comboBox( qobject_cast<QComboBox*>( w ) );
812            const int index = comboBox->findData( myPrefs.getInt( key ) );
813            comboBox->setCurrentIndex( index );
814        }
815    }
816}
817
818bool
819PrefsDialog :: isAllowed( int key ) const
820{
821    Q_UNUSED( key );
822
823    return true;
824}
Note: See TracBrowser for help on using the repository browser.