2 * This file Copyright (C) Mnemosyne LLC
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.
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10 * $Id: prefs-dialog.cc 12550 2011-07-17 14:12:00Z jordan $
18 #include <QCoreApplication>
19 #include <QDialogButtonBox>
20 #include <QDoubleSpinBox>
21 #include <QFileIconProvider>
23 #include <QHBoxLayout>
29 #include <QMessageBox>
30 #include <QPushButton>
37 #include <QVBoxLayout>
39 #include "formatter.h"
42 #include "prefs-dialog.h"
52 const char * PREF_KEY( "pref-key" );
56 PrefsDialog :: checkBoxToggled( bool checked
)
58 const int key( sender( )->property( PREF_KEY
).toInt( ) );
59 setPref( key
, checked
);
63 PrefsDialog :: checkBoxNew( const QString
& text
, int key
)
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
);
74 PrefsDialog :: enableBuddyWhenChecked( QCheckBox
* box
, QWidget
* buddy
)
76 connect( box
, SIGNAL(toggled(bool)), buddy
, SLOT(setEnabled(bool)) );
77 buddy
->setEnabled( box
->isChecked( ) );
81 PrefsDialog :: spinBoxEditingFinished()
83 const QObject
* spin
= sender();
84 const int key
= spin
->property( PREF_KEY
).toInt( );
85 const QDoubleSpinBox
* d
= qobject_cast
<const QDoubleSpinBox
*>( spin
);
87 setPref( key
, d
->value( ) );
89 setPref( key
, qobject_cast
<const QSpinBox
*>(spin
)->value( ) );
93 PrefsDialog :: spinBoxNew( int key
, int low
, int high
, int step
)
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
);
106 PrefsDialog :: doubleSpinBoxNew( int key
, double low
, double high
, double step
, int decimals
)
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
);
120 PrefsDialog :: timeEditingFinished( )
122 QTimeEdit
* e
= qobject_cast
<QTimeEdit
*>(sender());
125 const int key( e
->property( PREF_KEY
).toInt( ) );
126 const QTime
time( e
->time( ) );
127 const int seconds( QTime().secsTo( time
) );
128 std::cerr
<< "setPref to " << (seconds
/60) << " minutes" << std::endl
;
129 setPref( key
, seconds
/ 60 );
133 PrefsDialog :: timeEditNew( int key
)
135 const int minutes( myPrefs
.getInt( key
) );
136 QTimeEdit
* e
= new QTimeEdit( );
137 e
->setDisplayFormat( "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()) );
146 PrefsDialog :: lineEditingFinished( )
148 QLineEdit
* e
= qobject_cast
<QLineEdit
*>(sender());
149 if( e
&& e
->isModified( ) )
151 const int key( e
->property( PREF_KEY
).toInt( ) );
152 const QString
text( e
->text() );
153 setPref( key
, text
);
157 PrefsDialog :: lineEditNew( int key
, int echoMode
)
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()) );
172 PrefsDialog :: createWebTab( Session
& session
)
174 HIG
* hig
= new HIG( this );
175 hig
->addSectionTitle( tr( "Web Client" ) );
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( "&Enable web client" ), Prefs::RPC_ENABLED
);
182 myUnsupportedWhenRemote
<< l
;
183 hig
->addRow( l
, h
, 0 );
184 l
= hig
->addRow( tr( "Listening &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
) );
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 to connect:" ), Prefs::RPC_WHITELIST_ENABLED
) );
194 l
= hig
->addRow( tr( "Addresses:" ), w
= lineEditNew( Prefs::RPC_WHITELIST
) );
195 myWebWhitelistWidgets
<< l
<< w
;
196 myUnsupportedWhenRemote
<< myWebWidgets
<< myWebAuthWidgets
<< myWebWhitelistWidgets
;
206 PrefsDialog :: altSpeedDaysEdited( int i
)
208 const int value
= qobject_cast
<QComboBox
*>(sender())->itemData(i
).toInt();
209 setPref( Prefs::ALT_SPEED_LIMIT_TIME_DAY
, value
);
214 PrefsDialog :: createSpeedTab( )
217 HIG
* hig
= new HIG( this );
218 hig
->addSectionTitle( tr( "Speed Limits" ) );
219 const QString speed_K_str
= Formatter::unitStr( Formatter::SPEED
, Formatter::KB
);
221 l
= checkBoxNew( tr( "Limit &download speed (%1):" ).arg( speed_K_str
), Prefs::DSPEED_ENABLED
);
222 r
= spinBoxNew( Prefs::DSPEED
, 0, INT_MAX
, 5 );
224 enableBuddyWhenChecked( qobject_cast
<QCheckBox
*>(l
), r
);
226 l
= checkBoxNew( tr( "Limit &upload speed (%1):" ).arg( speed_K_str
), Prefs::USPEED_ENABLED
);
227 r
= spinBoxNew( Prefs::USPEED
, 0, INT_MAX
, 5 );
229 enableBuddyWhenChecked( qobject_cast
<QCheckBox
*>(l
), r
);
231 hig
->addSectionDivider( );
232 QHBoxLayout
* h
= new QHBoxLayout
;
233 h
->setSpacing( HIG :: PAD
);
234 QLabel
* label
= new QLabel
;
235 label
->setPixmap( QPixmap( ":/icons/alt-limit-off.png" ) );
236 label
->setAlignment( Qt::AlignLeft
|Qt::AlignVCenter
);
237 h
->addWidget( label
);
238 label
= new QLabel( tr( "Temporary Speed Limits" ) );
239 label
->setStyleSheet( "font: bold" );
240 label
->setAlignment( Qt::AlignLeft
|Qt::AlignVCenter
);
241 h
->addWidget( label
);
242 hig
->addSectionTitle( h
);
244 QString s
= tr( "<small>Override normal speed limits manually or at scheduled times</small>" );
245 hig
->addWideControl( new QLabel( s
) );
247 s
= tr( "Limit do&wnload speed (%1):" ).arg( speed_K_str
);
248 r
= spinBoxNew( Prefs :: ALT_SPEED_LIMIT_DOWN
, 0, INT_MAX
, 5 );
251 s
= tr( "Limit u&pload speed (%1):" ).arg( speed_K_str
);
252 r
= spinBoxNew( Prefs :: ALT_SPEED_LIMIT_UP
, 0, INT_MAX
, 5 );
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 );
261 QLabel
* nd
= new QLabel( tr("&to") );
263 mySchedWidgets
<< nd
;
264 w
= timeEditNew( Prefs :: ALT_SPEED_LIMIT_TIME_END
);
266 h
->addWidget( w
, 1 );
268 hig
->addRow( c
, h
, 0 );
270 s
= tr( "&On days:" );
271 QComboBox
* box
= new QComboBox
;
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
;
297 PrefsDialog :: createDesktopTab( )
299 HIG
* hig
= new HIG( this );
300 hig
->addSectionTitle( tr( "Desktop" ) );
302 hig
->addWideControl( checkBoxNew( tr( "Show Transmission icon in the ¬ification area" ), Prefs::SHOW_TRAY_ICON
) );
303 hig
->addWideControl( checkBoxNew( tr( "Show &popup notifications" ), Prefs::SHOW_DESKTOP_NOTIFICATION
) );
314 PrefsDialog :: onPortTested( bool isOpen
)
316 myPortButton
->setEnabled( true );
317 myWidgets
[Prefs::PEER_PORT
]->setEnabled( true );
318 myPortLabel
->setText( isOpen
? tr( "Port is <b>open</b>" )
319 : tr( "Port is <b>closed</b>" ) );
323 PrefsDialog :: onPortTest( )
325 myPortLabel
->setText( tr( "Testing TCP Port..." ) );
326 myPortButton
->setEnabled( false );
327 myWidgets
[Prefs::PEER_PORT
]->setEnabled( false );
328 mySession
.portTest( );
332 PrefsDialog :: createNetworkTab( )
334 HIG
* hig
= new HIG( this );
335 hig
->addSectionTitle( tr( "Incoming Peers" ) );
337 QSpinBox
* s
= spinBoxNew( Prefs::PEER_PORT
, 1, 65535, 1 );
338 QHBoxLayout
* h
= new QHBoxLayout( );
339 QPushButton
* b
= myPortButton
= new QPushButton( tr( "Te&st Port" ) );
340 QLabel
* l
= myPortLabel
= new QLabel( tr( "Status unknown" ) );
342 h
->addSpacing( HIG :: PAD_BIG
);
344 h
->setStretchFactor( l
, 1 );
345 connect( b
, SIGNAL(clicked(bool)), this, SLOT(onPortTest()));
346 connect( &mySession
, SIGNAL(portTested(bool)), this, SLOT(onPortTested(bool)));
348 hig
->addRow( tr( "&Port for incoming connections:" ), s
);
349 hig
->addRow( "", h
, 0 );
350 hig
->addWideControl( checkBoxNew( tr( "Pick a &random port every time Transmission is started" ), Prefs :: PEER_PORT_RANDOM_ON_START
) );
351 hig
->addWideControl( checkBoxNew( tr( "Use UPnP or NAT-PMP port &forwarding from my router" ), Prefs::PORT_FORWARDING
) );
353 hig
->addSectionDivider( );
354 hig
->addSectionTitle( tr( "Limits" ) );
355 hig
->addRow( tr( "Maximum peers per &torrent:" ), spinBoxNew( Prefs::PEER_LIMIT_TORRENT
, 1, FD_SETSIZE
, 5 ) );
356 hig
->addRow( tr( "Maximum peers &overall:" ), spinBoxNew( Prefs::PEER_LIMIT_GLOBAL
, 1, FD_SETSIZE
, 5 ) );
358 hig
->addSectionDivider( );
359 hig
->addSectionTitle( tr( "Options" ) );
362 hig
->addWideControl( w
= checkBoxNew( tr( "Enable &uTP for peer connections" ), Prefs::UTP_ENABLED
) );
363 w
->setToolTip( tr( "uTP is a tool for reducing network congestion." ) );
374 PrefsDialog :: onBlocklistDialogDestroyed( QObject
* o
)
378 myBlocklistDialog
= 0;
382 PrefsDialog :: onUpdateBlocklistCancelled( )
384 disconnect( &mySession
, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int))) ;
385 myBlocklistDialog
->deleteLater( );
389 PrefsDialog :: onBlocklistUpdated( int n
)
391 myBlocklistDialog
->setText( tr( "<b>Update succeeded!</b><p>Blocklist now has %Ln rules.", 0, n
) );
392 myBlocklistDialog
->setTextFormat( Qt::RichText
);
396 PrefsDialog :: onUpdateBlocklistClicked( )
398 myBlocklistDialog
= new QMessageBox( QMessageBox::Information
,
400 tr( "<b>Update Blocklist</b><p>Getting new blocklist..." ),
403 connect( myBlocklistDialog
, SIGNAL(rejected()), this, SLOT(onUpdateBlocklistCancelled()) );
404 connect( &mySession
, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int))) ;
405 myBlocklistDialog
->show( );
406 mySession
.updateBlocklist( );
410 PrefsDialog :: encryptionEdited( int i
)
412 const int value( qobject_cast
<QComboBox
*>(sender())->itemData(i
).toInt( ) );
413 setPref( Prefs::ENCRYPTION
, value
);
417 PrefsDialog :: createPrivacyTab( )
420 HIG
* hig
= new HIG( this );
422 hig
->addSectionTitle( tr( "Blocklist" ) );
424 QWidget
* l
= checkBoxNew( tr("Enable &blocklist:"), Prefs::BLOCKLIST_ENABLED
);
425 QWidget
* e
= lineEditNew( Prefs::BLOCKLIST_URL
);
429 l
= myBlocklistLabel
= new QLabel( "" );
431 w
= new QPushButton( tr( "&Update" ) );
432 connect( w
, SIGNAL(clicked(bool)), this, SLOT(onUpdateBlocklistClicked()));
434 QHBoxLayout
* h
= new QHBoxLayout( );
438 hig
->addWideControl( h
);
440 l
= checkBoxNew( tr( "Enable &automatic updates" ), Prefs::BLOCKLIST_UPDATES_ENABLED
);
442 hig
->addWideControl( l
);
444 hig
->addSectionDivider( );
445 hig
->addSectionTitle( tr( "Privacy" ) );
447 QComboBox
* box
= new QComboBox( );
448 box
->addItem( tr( "Allow encryption" ), 0 );
449 box
->addItem( tr( "Prefer encryption" ), 1 );
450 box
->addItem( tr( "Require encryption" ), 2 );
451 myWidgets
.insert( Prefs :: ENCRYPTION
, box
);
452 connect( box
, SIGNAL(activated(int)), this, SLOT(encryptionEdited(int)));
454 hig
->addRow( tr( "&Encryption mode:" ), box
);
455 hig
->addWideControl( w
= checkBoxNew( tr( "Use PE&X to find more peers" ), Prefs::PEX_ENABLED
) );
456 w
->setToolTip( tr( "PEX is a tool for exchanging peer lists with the peers you're connected to." ) );
457 hig
->addWideControl( w
= checkBoxNew( tr( "Use &DHT to find more peers" ), Prefs::DHT_ENABLED
) );
458 w
->setToolTip( tr( "DHT is a tool for finding peers without a tracker." ) );
459 hig
->addWideControl( w
= checkBoxNew( tr( "Use &Local Peer Discovery to find more peers" ), Prefs::LPD_ENABLED
) );
460 w
->setToolTip( tr( "LPD is a tool for finding peers on your local network." ) );
463 updateBlocklistLabel( );
472 PrefsDialog :: onScriptClicked( void )
474 const QString title
= tr( "Select \"Torrent Done\" Script" );
475 const QString myPath
= myPrefs
.getString( Prefs::SCRIPT_TORRENT_DONE_FILENAME
);
476 const QString path
= Utils::remoteFileChooser( this, title
, myPath
, false, mySession
.isServer() );
478 if( !path
.isEmpty() )
479 onLocationSelected( path
, Prefs::SCRIPT_TORRENT_DONE_FILENAME
);
483 PrefsDialog :: onIncompleteClicked( void )
485 const QString title
= tr( "Select Incomplete Directory" );
486 const QString myPath
= myPrefs
.getString( Prefs::INCOMPLETE_DIR
);
487 const QString path
= Utils::remoteFileChooser( this, title
, myPath
, true, mySession
.isServer() );
489 if( !path
.isEmpty() )
490 onLocationSelected( path
, Prefs::INCOMPLETE_DIR
);
494 PrefsDialog :: onWatchClicked( void )
496 const QString title
= tr( "Select Watch Directory" );
497 const QString myPath
= myPrefs
.getString( Prefs::DIR_WATCH
);
498 const QString path
= Utils::remoteFileChooser( this, title
, myPath
, true, true );
500 if( !path
.isEmpty() )
501 onLocationSelected( path
, Prefs::DIR_WATCH
);
505 PrefsDialog :: onDestinationClicked( void )
507 const QString title
= tr( "Select Destination" );
508 const QString myPath
= myPrefs
.getString( Prefs::DOWNLOAD_DIR
);
509 const QString path
= Utils::remoteFileChooser( this, title
, myPath
, true, mySession
.isServer() );
511 if( !path
.isEmpty() )
512 onLocationSelected( path
, Prefs::DOWNLOAD_DIR
);
516 PrefsDialog :: onLocationSelected( const QString
& path
, int key
)
518 setPref( key
, path
);
522 PrefsDialog :: createTorrentsTab( )
524 const int iconSize( style( )->pixelMetric( QStyle :: PM_SmallIconSize
) );
525 const QFileIconProvider iconProvider
;
526 const QIcon folderIcon
= iconProvider
.icon( QFileIconProvider::Folder
);
527 const QPixmap folderPixmap
= folderIcon
.pixmap( iconSize
);
528 const QIcon fileIcon
= iconProvider
.icon( QFileIconProvider::File
);
529 const QPixmap filePixmap
= fileIcon
.pixmap( iconSize
);
532 HIG
* hig
= new HIG( this );
533 hig
->addSectionTitle( tr( "Adding" ) );
535 l
= checkBoxNew( tr( "Automatically &add torrents from:" ), Prefs::DIR_WATCH_ENABLED
);
536 QPushButton
* b
= myWatchButton
= new QPushButton
;
537 b
->setIcon( folderPixmap
);
538 b
->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
539 connect( b
, SIGNAL(clicked(bool)), this, SLOT(onWatchClicked(void)) );
541 enableBuddyWhenChecked( qobject_cast
<QCheckBox
*>(l
), b
);
543 hig
->addWideControl( checkBoxNew( tr( "Show &options dialog" ), Prefs::OPTIONS_PROMPT
) );
544 hig
->addWideControl( checkBoxNew( tr( "&Start when added" ), Prefs::START
) );
545 hig
->addWideControl( checkBoxNew( tr( "Mo&ve .torrent file to the trash" ), Prefs::TRASH_ORIGINAL
) );
547 hig
->addSectionDivider( );
548 hig
->addSectionTitle( tr( "Downloading" ) );
550 hig
->addWideControl( checkBoxNew( tr( "Append \".&part\" to incomplete files' names" ), Prefs::RENAME_PARTIAL_FILES
) );
552 b
= myDestinationButton
= new QPushButton
;
553 b
->setIcon( folderPixmap
);
554 b
->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
555 connect( b
, SIGNAL(clicked(bool)), this, SLOT(onDestinationClicked(void)) );
556 hig
->addRow( tr( "Save to &Location:" ), b
);
558 l
= myIncompleteCheckbox
= checkBoxNew( tr( "Keep &incomplete files in:" ), Prefs::INCOMPLETE_DIR_ENABLED
);
559 b
= myIncompleteButton
= new QPushButton
;
560 b
->setIcon( folderPixmap
);
561 b
->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
562 connect( b
, SIGNAL(clicked(bool)), this, SLOT(onIncompleteClicked(void)) );
563 hig
->addRow( myIncompleteCheckbox
, b
);
564 enableBuddyWhenChecked( qobject_cast
<QCheckBox
*>(l
), b
);
566 l
= myTorrentDoneScriptCheckbox
= checkBoxNew( tr( "Call scrip&t when torrent is completed:" ), Prefs::SCRIPT_TORRENT_DONE_ENABLED
);
567 b
= myTorrentDoneScriptButton
= new QPushButton
;
568 b
->setIcon( filePixmap
);
569 b
->setStyleSheet( "text-align: left; padding-left: 5; padding-right: 5" );
570 connect( b
, SIGNAL(clicked(bool)), this, SLOT(onScriptClicked(void)) );
571 hig
->addRow( myTorrentDoneScriptCheckbox
, b
);
572 enableBuddyWhenChecked( qobject_cast
<QCheckBox
*>(l
), b
);
574 hig
->addSectionDivider( );
575 hig
->addSectionTitle( tr( "Seeding Limits" ) );
577 l
= checkBoxNew( tr( "Stop seeding at &ratio:" ), Prefs::RATIO_ENABLED
);
578 r
= doubleSpinBoxNew( Prefs::RATIO
, 0, INT_MAX
, 0.5, 2 );
580 enableBuddyWhenChecked( qobject_cast
<QCheckBox
*>(l
), r
);
582 l
= checkBoxNew( tr( "Stop seeding if idle for &N minutes:" ), Prefs::IDLE_LIMIT_ENABLED
);
583 r
= spinBoxNew( Prefs::IDLE_LIMIT
, 1, INT_MAX
, 5 );
585 enableBuddyWhenChecked( qobject_cast
<QCheckBox
*>(l
), r
);
595 PrefsDialog :: PrefsDialog( Session
& session
, Prefs
& prefs
, QWidget
* parent
):
597 myIsServer( session
.isServer( ) ),
598 mySession( session
),
600 myLayout( new QVBoxLayout( this ) )
602 setWindowTitle( tr( "Transmission Preferences" ) );
604 QTabWidget
* t
= new QTabWidget( this );
605 t
->addTab( createTorrentsTab( ), tr( "Torrents" ) );
606 t
->addTab( createSpeedTab( ), tr( "Speed" ) );
607 t
->addTab( createPrivacyTab( ), tr( "Privacy" ) );
608 t
->addTab( createNetworkTab( ), tr( "Network" ) );
609 t
->addTab( createDesktopTab( ), tr( "Desktop" ) );
610 t
->addTab( createWebTab( session
), tr( "Web" ) );
611 myLayout
->addWidget( t
);
613 QDialogButtonBox
* buttons
= new QDialogButtonBox( QDialogButtonBox::Close
, Qt::Horizontal
, this );
614 connect( buttons
, SIGNAL(rejected()), this, SLOT(close()) ); // "close" triggers rejected
615 myLayout
->addWidget( buttons
);
616 QWidget::setAttribute( Qt::WA_DeleteOnClose
, true );
618 connect( &mySession
, SIGNAL(sessionUpdated()), this, SLOT(sessionUpdated()));
621 keys
<< Prefs :: RPC_ENABLED
622 << Prefs :: ALT_SPEED_LIMIT_ENABLED
623 << Prefs :: ALT_SPEED_LIMIT_TIME_ENABLED
624 << Prefs :: ENCRYPTION
625 << Prefs :: BLOCKLIST_ENABLED
626 << Prefs :: DIR_WATCH
627 << Prefs :: DOWNLOAD_DIR
628 << Prefs :: INCOMPLETE_DIR
629 << Prefs :: INCOMPLETE_DIR_ENABLED
630 << Prefs :: SCRIPT_TORRENT_DONE_FILENAME
;
631 foreach( int key
, keys
)
634 // if it's a remote session, disable the preferences
635 // that don't work in remote sessions
637 foreach( QWidget
* w
, myUnsupportedWhenRemote
) {
638 w
->setToolTip( tr( "Not supported by remote sessions" ) );
639 w
->setEnabled( false );
644 PrefsDialog :: ~PrefsDialog( )
649 PrefsDialog :: setPref( int key
, const QVariant
& v
)
651 myPrefs
.set( key
, v
);
660 PrefsDialog :: sessionUpdated( )
662 updateBlocklistLabel( );
666 PrefsDialog :: updateBlocklistLabel( )
668 const int n
= mySession
.blocklistSize( );
669 myBlocklistLabel
->setText( tr( "<i>Blocklist contains %Ln rules</i>", 0, n
) );
673 PrefsDialog :: refreshPref( int key
)
677 case Prefs :: RPC_ENABLED
:
678 case Prefs :: RPC_WHITELIST_ENABLED
:
679 case Prefs :: RPC_AUTH_REQUIRED
: {
680 const bool enabled( myPrefs
.getBool( Prefs::RPC_ENABLED
) );
681 const bool whitelist( myPrefs
.getBool( Prefs::RPC_WHITELIST_ENABLED
) );
682 const bool auth( myPrefs
.getBool( Prefs::RPC_AUTH_REQUIRED
) );
683 foreach( QWidget
* w
, myWebWhitelistWidgets
) w
->setEnabled( enabled
&& whitelist
);
684 foreach( QWidget
* w
, myWebAuthWidgets
) w
->setEnabled( enabled
&& auth
);
685 foreach( QWidget
* w
, myWebWidgets
) w
->setEnabled( enabled
);
689 case Prefs :: ALT_SPEED_LIMIT_TIME_ENABLED
: {
690 const bool enabled
= myPrefs
.getBool( key
);
691 foreach( QWidget
* w
, mySchedWidgets
) w
->setEnabled( enabled
);
695 case Prefs :: BLOCKLIST_ENABLED
: {
696 const bool enabled
= myPrefs
.getBool( key
);
697 foreach( QWidget
* w
, myBlockWidgets
) w
->setEnabled( enabled
);
701 case Prefs :: DIR_WATCH
:
702 myWatchButton
->setText( QFileInfo(myPrefs
.getString(Prefs::DIR_WATCH
)).fileName() );
705 case Prefs :: SCRIPT_TORRENT_DONE_FILENAME
: {
706 const QString
path( myPrefs
.getString( key
) );
707 myTorrentDoneScriptButton
->setText( QFileInfo(path
).fileName() );
711 case Prefs :: PEER_PORT
:
712 myPortLabel
->setText( tr( "Status unknown" ) );
713 myPortButton
->setEnabled( true );
716 case Prefs :: DOWNLOAD_DIR
: {
717 QString
path( myPrefs
.getString( key
) );
718 myDestinationButton
->setText( QFileInfo(path
).fileName() );
722 case Prefs :: INCOMPLETE_DIR
: {
723 QString
path( myPrefs
.getString( key
) );
724 myIncompleteButton
->setText( QFileInfo(path
).fileName() );
728 case Prefs :: INCOMPLETE_DIR_ENABLED
: {
729 const bool enabled
= myPrefs
.getBool( key
);
730 myIncompleteButton
->setEnabled( enabled
);
738 key2widget_t::iterator
it( myWidgets
.find( key
) );
739 if( it
!= myWidgets
.end( ) )
741 QWidget
* w( it
.value( ) );
742 QCheckBox
* checkBox
;
744 QDoubleSpinBox
* doubleSpin
;
745 QTimeEdit
* timeEdit
;
746 QLineEdit
* lineEdit
;
748 if(( checkBox
= qobject_cast
<QCheckBox
*>(w
)))
750 checkBox
->setChecked( myPrefs
.getBool( key
) );
752 else if(( spin
= qobject_cast
<QSpinBox
*>(w
)))
754 spin
->setValue( myPrefs
.getInt( key
) );
756 else if(( doubleSpin
= qobject_cast
<QDoubleSpinBox
*>(w
)))
758 doubleSpin
->setValue( myPrefs
.getDouble( key
) );
760 else if(( timeEdit
= qobject_cast
<QTimeEdit
*>(w
)))
762 const int minutes( myPrefs
.getInt( key
) );
763 timeEdit
->setTime( QTime().addSecs( minutes
* 60 ) );
765 else if(( lineEdit
= qobject_cast
<QLineEdit
*>(w
)))
767 lineEdit
->setText( myPrefs
.getString( key
) );
769 else if( key
== Prefs::ENCRYPTION
)
771 QComboBox
* comboBox( qobject_cast
<QComboBox
*>( w
) );
772 const int index
= comboBox
->findData( myPrefs
.getInt( key
) );
773 comboBox
->setCurrentIndex( index
);
779 PrefsDialog :: isAllowed( int key
) const